V2Ray 实现透明网关 配合树莓派搭建无墙热点 - kernel panic

V2Ray 实现透明网关 配合树莓派搭建无墙热点

使用V2的任意门结合iptables做流量转发

V2Ray 一直来是一个强大的代理程序,很多机场都在用它。但本文不讨论扶墙那套,仅仅是学习它的代理功能和记录常用的配置,这次介绍很多软路由上的 透明网关 的实现。

就我个人而言,并不喜欢各种一键脚本,且曾经深受其害,主要是别人写好的脚本并非适合每个环境,而且有的脚本有挖矿或者上传数据的嫌疑,即使开源也总不可能源码都一行行认真看吧。比起一键脚本我更喜欢看manual一步步操作"特立独行"。

我曾经在介绍,把OpenVPN的数据依靠CDN进行转发的文章中提到我不喜欢软代理,而喜欢虚拟网卡这种对上层透明的代理,而阅读V2ray的Reference manual了解到从某个版本开始V2已经可以接收来自系统的流量了,故本文介绍如何将流量从内核引导到V2。

注:环境在树莓派3B+上,系统为Centos 7,不使用自带的Firewalld,使用能实现相同功能的iptables。

本文分为两个部分,首先从数据包在内核的流转开始
防火墙是工作在内核中的,即防火墙应该是内核中所实现的功能,而iptables只是一个软件,它间接操作下层的netfilter完成对数据的匹配工作。
流转

如图所示,数据包在流入网卡后首先经过PREROUTING进行处理,很多网站后端会用到的DNAT功能,也就是把公网地址在经过iptables策略后改为内网地址就在这里运行。以前我在校园网外访问教务网,它提示我IP是172开头的内网IP,那个时候我还很疑惑,不过在了解了DNAT后就不觉得奇怪了,在DNAT下拿到真实IP地址又是另外一件事了,如果有机会我还想写一下。然后判断是否目的地为本机,不是本机就转到Forward链继续执行。最后由POSTROUTING转发出去,POSTROUTING就是人们常说的NAT功能的实现方式之一,也就是很多个内网地址共享一个公网地址,另外 很羡慕隔壁电科大等高校,DHCP直接分配教育网公网IPv4的。至于目的地为本机的就不介绍了。

使能内核的转发功能

可能是处于安全考虑,Linux默认未允许转发目的地不是本机的数据包,需要在/etc/sysctl.conf中写入net.ipv4.ip_forward = 1以开启转发,完成后需要执行sysctl -p刷新。

在iptables上的操作以及说明

由前面简单介绍的iptables流程可知,要在 PREROUTING环节把数据交给V2ray,我们可以直接写规则 -A PREROUTING -s 192.168.2.0/24 -p tcp -j REDIRECT --to-ports v2ray监听的端口,但是这有个缺点是连接到本机的数据也会被发给v2,这样连接就中断了
较为稳妥的方式是在POSTROUTING后面插入一条自定义链:
iptables -A PREROUTING -p tcp -j V2RAY

分流策略如下:

  1. 所有流量进来后,进入V2ray这条自定义链等候处理.
  2. 来自客户端网段的数据,不做处理,Return回内核原来的主线。
    iptables -A V2RAY -d 192.168.0.0/16 -j RETURN
  3. 对于其它流量,转发到V2Ray的任意门进行处理。
    iptables -A V2RAY -s 192.168.2.0/24 -p tcp -j REDIRECT --to-ports 8081

这样就实现了客户端到网关和网关到落地服务器之间的流量分离。
iptables

v2ray部分

Dokodemo-door (任意门)是一个入站数据协议,它可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果。

由于你懂的原因,我不展开讨论出站协议。

入站:

{
        "protocol": "dokodemo-door",
        "port": 8081,
        "settings": {
                "network": "tcp,udp",
                "followRedirect": true,
                "userLevel": 0
        }

    }

Dokodemo-door 的协议很清晰,没有什么好讲的,如果不清楚建议看官方文档,要注意是必须打开followRedirect

followRedirect当值为true时,dokodemo-door 会识别出由 iptables 转发而来的数据,并转发到相应的目标地址。

此时启动v2,将你的客户端设备网关设置为v2设备,进行TCP ping操作已经能ping通IP地址了,然而还是打不开任何谷歌,这是DNS问题,大家肯定会想到DNS污染,等等,太快了还没到这一步。

这是因为UDP流量没法通过iptables的REDIRECT转发(实测会找不到目的IP)。解决方法有两种,一种是用iptables提供的TPROXY,这也是我以后要研究的。还有一种是再开一个任意门,把我们的DNS请求转发到落地服务器来解析:

{
            "tag": "dns-in",
            "port": 53,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "1.1.1.1",
                "port": 53, //UDP端口53号是DNS的
                "network": "tcp,udp" //不要TCP也行
            }
        }

路由设置: 说实话,v2的路由功能是很强大的,去广告,地域分流都能用

"routing": {
        "rules": [
            {
                "type": "field",
                "inboundTag": [
                    "dns-in"
                ],
                "outboundTag": "proxy"
            }
        ]
    }

此时,客户端设备网关设置为树莓派IP,DNS也设置为树莓派IP,即可在客户端设备上无需做任何操作也不用开任何软件科学上网。
服务

开热点!

这是附加内容,因为树莓派本身有一个很弱的网卡,就拿来开热点了,无缝科学上网。 具体不展开说,贴一下dhcpd和hostapd配置,关键的都加了注释,有兴趣的可以搜索linux怎么开热点 DHCP。

[root@localhost ~]# cat /etc/dhcp/dhcpd.conf
#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp*/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#
ddns-update-style interim;

#监听 192.168.2.0 这个子网
subnet 192.168.2.0 netmask 255.255.255.0 {

        #设置自动派 IP 的范围
        range 192.168.2.10 192.168.2.250;

        #默认的 DNS 服务器
        option domain-name-servers 192.168.2.1;
        #告诉客户端路由器地址
        option routers 192.168.2.1;
        #告诉客户端子网掩码
        option subnet-mask 255.255.255.0;
        #告诉客户端广播地址
        option broadcast-address 192.168.2.255;

        #IP 默认租期和最大租期
        default-lease-time 86400;
        max-lease-time 172800;

}

HostAP:

interface=wlan0
driver=nl80211
ssid=*****_
hw_mode=g
channel=9
auth_algs=1
ignore_broadcast_ssid=0                 # 是否广播,0 广播
#wpa=2
#wpa_passphrase=11111111
#wpa_pairwise=TKIP CCMP
ieee80211n=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

添加新评论

电子邮件地址不会被公开,评论内容可能需要管理员审核后显示。