我正在尝试使用VpnService for
BS项目为Android实现一个简单的防火墙。我选择VpnService,因为它将在非root用户的设备上运行。它将记录连接并让您过滤连接。(基于IP)
有一个应用程序可以这样做。
GooglePlay应用商店
我进行了一些研究,发现VpnService创建了Tun接口。而已。(没有VPN实现只是一个隧道)它使您可以对此接口进行地址分配并添加路由。它返回一个文件描述符。您可以读取传出的程序包并编写传入的程序包。
我创建了一个VpnService派生类并开始服务。我可以tun0
使用VpnService.Builder类进行配置。当我查看mobiwol's
与adb shell netcfg
它的连接时,会创建一个tun0
具有10.2.3.4/32地址的接口。它将所有程序包路由到该专用网络并发送到Internet。我正在尝试相同。创建一个具有10.0.0.2/32地址的接口。使用addRoute函数添加了一条路由。0.0.0.0/0,据我了解,我可以从所有网络捕获所有软件包。(我对这门学科还很陌生,现在还在学习。我在网上找到了一些作品,所以我不确定。如果我错了,请纠正我。)
我在服务中创建了2个线程。一个从文件描述符读取并使用受保护的套接字将其写入127.0.0.1。(我不太确定我是否应该读/写127.0.0.1。也许这是问题所在。)
我分析了从文件描述符读取的数据包。例如:
01000101 byte:69 //ipv4 20byte header
00000000 byte:0 //TOS
00000000 byte:0 //Total Length
00111100 byte:60 //Total Length
11111100 byte:-4 //ID
11011011 byte:-37 //ID
01000000 byte:64 //fragment
00000000 byte:0 //"
01000000 byte:64 //TTL
00000110 byte:6 //Protocol 6 -> TCP
01011110 byte:94 //Header checksum
11001111 byte:-49 //Header checksum
00001010 byte:10 //10.0.0.2
00000000 byte:0
00000000 byte:0
00000010 byte:2
10101101 byte:-83 //173.194.39.78 //google
00111110 byte:-62
00100111 byte:39
******** byte:78
10110100 byte:-76 // IP option
01100101 byte:101
00000001 byte:1
10111011 byte:-69
//20byte IP haeder
01101101 byte:109
. . //40byte data (i couldnt parse TCP header,
I think its not needed when I route this in IP layer)
. .
. .
00000110 byte:6
我没有在其余数据中找到任何其他IP标头。我认为应该在10.0.0.2网络到本地网络(192.168.2.1)和Internet之间进行封装。我不确定。
我真正的问题是我停留在传入的包线程上。我什么也看不懂。没有反应。如您在屏幕快照中看到的,没有传入数据:
屏幕截图
我正在尝试从与用于使用受保护套接字写入127.0.0.1的同一连接读取数据。
Android <-> Tun接口(tun0)<-> Internet连接
所有软件包<-> 10.0.0.2 <-> 127.0.0.1?<-> 192.168.2.1 <-> Internet?
我找不到有关VpnService的任何帮助。(ToyVPN示例只是无用的)我阅读了有关Linux Tun /
Tap的文档,但有关主机和远程之间的隧道传输的文档。我希望主机和远程设备位于同一设备上。不喜欢隧道。
我怎样才能做到这一点?
编辑:要求的代码。还处于初期。如前所述,它是VpnService派生的类。在服务线程中创建了2个线程(读和写)。
package com.git.firewall;
public class GITVpnService extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "GITVpnService";
private String mServerAddress = "127.0.0.1";
private int mServerPort = 55555;
private PendingIntent mConfigureIntent;
private Handler mHandler;
private Thread mThread;
private ParcelFileDescriptor mInterface;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The handler is only used to show messages.
if (mHandler == null) {
mHandler = new Handler(this);
}
// Stop the previous session by interrupting the thread.
if (mThread != null) {
mThread.interrupt();
}
// Start a new session by creating a new thread.
mThread = new Thread(this, "VpnThread");
mThread.start();
return START_STICKY;
}
@Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
}
@Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, (String)message.obj, Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public synchronized void run() {
try {
Log.i(TAG, "Starting");
InetSocketAddress server = new InetSocketAddress(
mServerAddress, mServerPort);
run(server);
} catch (Exception e) {
Log.e(TAG, "Got " + e.toString());
try {
mInterface.close();
} catch (Exception e2) {
// ignore
}
Message msgObj = mHandler.obtainMessage();
msgObj.obj = "Disconnected";
mHandler.sendMessage(msgObj);
} finally {
}
}
DatagramChannel mTunnel = null;
private boolean run(InetSocketAddress server) throws Exception {
boolean connected = false;
android.os.Debug.waitForDebugger();
// Create a DatagramChannel as the VPN tunnel.
mTunnel = DatagramChannel.open();
// Protect the tunnel before connecting to avoid loopback.
if (!protect(mTunnel.socket())) {
throw new IllegalStateException("Cannot protect the tunnel");
}
// Connect to the server.
mTunnel.connect(server);
// For simplicity, we use the same thread for both reading and
// writing. Here we put the tunnel into non-blocking mode.
mTunnel.configureBlocking(false);
// Authenticate and configure the virtual network interface.
handshake();
// Now we are connected. Set the flag and show the message.
connected = true;
Message msgObj = mHandler.obtainMessage();
msgObj.obj = "Connected";
mHandler.sendMessage(msgObj);
new Thread ()
{
public void run ()
{
// Packets to be sent are queued in this input stream.
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
int length;
try
{
while (true)
{
while ((length = in.read(packet.array())) > 0) {
// Write the outgoing packet to the tunnel.
packet.limit(length);
debugPacket(packet); // Packet size, Protocol, source, destination
mTunnel.write(packet);
packet.clear();
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}.start();
new Thread ()
{
public void run ()
{
DatagramChannel tunnel = mTunnel;
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(8096);
// Packets received need to be written to this output stream.
FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor());
while (true)
{
try
{
// Read the incoming packet from the tunnel.
int length;
while ((length = tunnel.read(packet)) > 0)
{
// Write the incoming packet to the output stream.
out.write(packet.array(), 0, length);
packet.clear();
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
}.start();
return connected;
}
private void handshake() throws Exception {
if (mInterface == null)
{
Builder builder = new Builder();
builder.setMtu(1500);
builder.addAddress("10.0.0.2",32);
builder.addRoute("0.0.0.0", 0);
//builder.addRoute("192.168.2.0",24);
//builder.addDnsServer("8.8.8.8");
// Close the old interface since the parameters have been changed.
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
// Create a new interface using the builder and save the parameters.
mInterface = builder.setSession("GIT VPN")
.setConfigureIntent(mConfigureIntent)
.establish();
}
}
private void debugPacket(ByteBuffer packet)
{
/*
for(int i = 0; i < length; ++i)
{
byte buffer = packet.get();
Log.d(TAG, "byte:"+buffer);
}*/
int buffer = packet.get();
int version;
int headerlength;
version = buffer >> 4;
headerlength = buffer & 0x0F;
headerlength *= 4;
Log.d(TAG, "IP Version:"+version);
Log.d(TAG, "Header Length:"+headerlength);
String status = "";
status += "Header Length:"+headerlength;
buffer = packet.get(); //DSCP + EN
buffer = packet.getChar(); //Total Length
Log.d(TAG, "Total Length:"+buffer);
buffer = packet.getChar(); //Identification
buffer = packet.getChar(); //Flags + Fragment Offset
buffer = packet.get(); //Time to Live
buffer = packet.get(); //Protocol
Log.d(TAG, "Protocol:"+buffer);
status += " Protocol:"+buffer;
buffer = packet.getChar(); //Header checksum
String sourceIP = "";
buffer = packet.get(); //Source IP 1st Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 2nd Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 3rd Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 4th Octet
sourceIP += buffer;
Log.d(TAG, "Source IP:"+sourceIP);
status += " Source IP:"+sourceIP;
String destIP = "";
buffer = packet.get(); //Destination IP 1st Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 2nd Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 3rd Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 4th Octet
destIP += buffer;
Log.d(TAG, "Destination IP:"+destIP);
status += " Destination IP:"+destIP;
/*
msgObj = mHandler.obtainMessage();
msgObj.obj = status;
mHandler.sendMessage(msgObj);
*/
//Log.d(TAG, "version:"+packet.getInt());
//Log.d(TAG, "version:"+packet.getInt());
//Log.d(TAG, "version:"+packet.getInt());
}
}
几个月前,有人提出了类似的问题,虽然答案并不十分有见地,但接受的答案中的评论使您可以洞悉可能出了什么问题。
您应该牢记逻辑驻留在OSI模型的哪一层:
在示例字节流中,您可以看到传入的字节流是IPv4数据报,因为前四个位是0100
(4)。有关IPv4的详细信息,请查阅此数据包结构规范。
请记住,这会跳过传输层,因为那些实现会负责构造UDP标头(对于DatagramSocket)和TCP标头和选项(对于Socket)。
您的应用程序本质上将需要能够解释和构造IPv4和IPv6标头和选项,以及作为IP有效负载的UDP标头和TCP标头和选项。
我正在尝试用vpnserviceforbs项目为android实现一个简单的防火墙。我选择VPN服务是因为它将在非根设备上工作。它将记录连接并允许您过滤连接。(基于IP) 有一个应用程序可以这样做。 谷歌play应用商店 我做了一些研究,发现VPN服务创建了一个Tun接口。没别的了。(没有VPN实现,只是一个隧道)它允许您向该接口提供地址并添加路由。它返回一个文件描述符。您可以读取传出包和写入传入
可以使用高级安全 Windows 防火墙帮助您保护网络上的计算机。高级安全 Windows 防火墙包括有状态的防火墙,通过该防火墙您可以确定允许在计算机和网络之间传输的网络流量。
我想创建应用程序,它重新路由数据包。我使用vpnservice(因为不需要根电话),使用toyVpn和这个代码http://www.theGeekstuff.com/2014/06/android-vpn-service/但是问题是在这行DatagramChannel tunnel=DatagramChannel.open();此行抛出异常。这是我的密码 这是日志: null null 我还有一个
基本概念 netfilter Linux 内核包含一个强大的网络过滤子系统 netfilter。netfilter 子系统允许内核模块对遍历系统的每个网络数据包进行检查。这表示在任何传入、传出或转发的网络数据包到达用户空间中的组件之前,都可以通过编程方式检查、修改、丢弃或拒绝。netfilter 是 RHEL 7 计算机上构建防火墙的主要构建块。 尽管系统管理员理论上可以编写自己的内核模块以与 n
我有一个服务器写在JavaServerSocket。 我有一个客户端,它位于一个公司防火墙之上,除了公共端口之外,它阻止了所有东西。 我已在SMTP端口(#25)上启动服务器。 有防火墙的用户连接到它,到目前为止一切正常。 然后服务器处理ServerSocket.accept()。据我所知,它在一个随机端口上创建一个套接字(每次端口号都不同)。因为防火墙而失败。 我的问题是-如何制作ServerS
iptables 命令 防火墙分为硬件防火墙和软件防火墙 防火墙策略一般分为两种:开放和屏蔽 iptables 是 Linux 上常用的防火墙软件 iptables 一共有四张表和五条链 iptables (选项)[表名] (选项)[链名规则] (选项)[动作] 表: Raw 负责连接跟踪 Mangle 负责包处理 Nat 负责地址转换 Filter 负责包过滤 链名规则: PREROUTING