“工匠精神” 精心打造一个代理服务器 前言 代理入口 Shadowsocks 配置 Shadowsocks Shadowsocks 优化 Shadowsocks 配置文件 兼容 WEB SNIPROXY 中转服务器 V2ray IP 分流 iptables ipset UDP 测试 UDP IPv6 支持 去广告 & 境外受限 dnsmasq 配置 大功告成~!
前言 首先,本文会涉及众多代理软件的名字,但因为本人是在国外,用代理软件是回国的,是一名爱国青年。所以请大家不要把代理的方向反转来用。
在国外很多时候打开国内的网站非常缓慢,而且时不时有境外 IP 受限的问题。而代理软件的 obfs 或者 Websocks 能让我冒认成其他软件的服务器干些嘿嘿嘿的事情之外,还能帮助我突破一些的网络限制,比如我们学校的 Wi-Fi ,除了 443 和 80 端口,其他端口很多都是不通的。经过代理后就不会有域名和端口被限制的问题,还能保障安全,随便连各种 Wi-Fi 。
从而有了这篇文章,整个代理实现了:obfs + 服务器 IP 分流 + UDP 转发 + 去广告 + IPv6 支持 。
代理入口 Shadowsocks 之所以选择 Shadowsocks 作为代理入口是因为 Shadowsocks 都发展有一段时间了,各平台的客户端也比较完善,用起来比较顺手。而目前 V2ray 的手机客户端目前还不稳定,如果直接用 V2ray 作为入口的话,就可以直接在 V2ray 实现 UDP 转发和 IP 分流,也能用 Caddy 和 Nginx 直接代理它的 Websocks 不需要再套 SNIPROXY,整个过程更加简洁。但截止目前 2017-11-15 ,IOS 端的 ShadowRay 还是很不稳定,丢失 VPN 图标经常发生,而且 IPv6 支持并不完美(不支持直接打开 IPv6 地址),也不支持 UDP 转发。综合以上的考虑,决定使用 Shadowsocks 作为代理的入口。
配置 Shadowsocks 相信大家对于这个已经不陌生了,我也不过多介绍。
推荐使用 秋水逸冰 的一键安装脚本,Shadowsocks-libev 版 https://teddysun.com/
Shadowsocks 优化 除了基本的安装,当然还要有一些其他的优化,比如打开 BBR 和 TCP Fast Open ,还有一些 sysctl 的优化,我直接放上来。
原本我是参考小数派里面一篇很好的文章的,里面有详细写到每一项的作用,但 “不知道为什么” ,这文章后来被删除了。
所以如果大家要了解以下 sysctl 设置的作用的话,可以 Google 一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 net.ipv6 .conf .all .accept_ra = 2 net.ipv4 .tcp_fastopen = 3 net.ipv4 .tcp_congestion_control = bbr net.core .default_qdisc = fq fs.file-max = 1024000 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.core .rmem_max = 12582912 net.core .wmem_max = 12582912 net.ipv4 .tcp_rmem = 10240 87380 12582912 net.ipv4 .tcp_wmem = 10240 87380 12582912 net.ipv4 .ip_forward = 1 net.ipv4 .tcp_syncookies = 1 net.ipv4 .tcp_tw_reuse = 1 net.ipv4 .tcp_fin_timeout = 30 net.ipv4 .tcp_keepalive_time = 1200 net.ipv4 .tcp_mtu_probing = 1 net.ipv4 .conf .all .accept_source_route = 1 n et.ipv4 .conf .default .accept_source_route = 1 net.ipv4 .conf .all .accept_redirects = 0 net.ipv4 .conf .default .accept_redirects = 0 net.ipv4 .conf .all .send_redirects = 0 net.ipv4 .conf .default .send_redirects = 0 net.ipv4 .conf .lo .send_redirects = 0 net.ipv4 .conf .all .rp_filter = 0 net.ipv4 .conf .default .rp_filter = 0 net.ipv4 .conf .lo .rp_filter = 0 net.ipv4 .icmp_echo_ignore_broadcasts = 1 net.ipv4 .icmp_ignore_bogus_error_responses = 1 net.ipv6 .conf .all .accept_source_route = 1 net.ipv6 .conf .default .accept_source_route = 1 net.ipv6 .conf .all .accept_redirects = 0 net.ipv6 .conf .default .accept_redirects = 0 net.ipv6 .conf .all .autoconf = 1 net.ipv6 .conf .all .forwarding = 1
Shadowsocks 配置文件 因为我们需要兼容到 WEB 服务器的运行,然后用 443 端口来做代理 TCP 和 UDP 的 Shadowsocks 流量。我们要分别跑两个 Shadowsocks 服务,一个是 TCP + obfs server 的,另一个是 UDP Only 的,因为 SNIPROXY 不代理 UDP 流量。
TCP SERVER:
1 2 3 4 5 6 7 8 9 { "server" : [ "[::1]" , "127.0.0.1" ] , "server_port" : 8988 , "local_address" : "127.0.0.1" , "local_port" : 1080 , "password" : "stevenkwan.me" , "timeout" : 600 , "method" : "chacha20-ietf-poly1305" }
因为服务还需要经过 SNIPROXY 代理,所以监听 IPv4 的 127.0.0.1
即可,顺带提一下 IPv6 里是 [::1]
。
在运行的时候,还需要加上以下的参数:
1 -6 -c /xxxxxx/ss-tls.conf -d 127.0.0.1:53 --plugin obfs-server --plugin-opts "obfs=tls;fast-open"
-6
优先使用 IPv6 地址。
-d
指定 DNS 服务器,这里指定为本机的 dnsmasq 服务器,下面去广告会用到。
UDP Only SERVER:
1 2 3 4 5 6 7 8 9 { "server" : [ "[::0]" , "0.0.0.0" ] , "server_port" : 443 , "local_address" : "127.0.0.1" , "local_port" : 443 , "password" : "stevenkwan.me" , "timeout" : 600 , "method" : "chacha20-ietf-poly1305" }
这里的 UDP 是需要直接暴露在公网的 443 端口。
在运行的时候,还需要加上以下的参数:
1 -6 -U -c /xxxx/udp-443.conf -d 127.0.0.1:53
-U
大写的 U 代表只开启 UDP 转发不开启 TCP 转发,如果写成小写的话,是两个同时开始。有 WEB Server 的话就会提示端口已经被占用。
兼容 WEB SNIPROXY SNIPROXY 的设置非常简单,直接上配置文件。
需要注意的是,启用前,要先将 WEB Server 改成非 443 端口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 user daemon pidfile /tmp/sniproxy.pid error_log { syslog daemon priority notice } listen 443 { protocol tls reuseport no table https fallback [::1] :445 } table https { www.google .com [::1] :8988 }
fallback
指向你的 WEB Server 端口即可。
table https
里面写你 Shadowsoks 里使用的 obfs 域名。
中转服务器 V2ray 除了我上面说的 V2ray 客户端不足,V2ray 还是有很多优势的,适合用来 “长距离” “翻山越岭” 。它支持 mkcp 和 mux 。
我曾经用过 Shadowsocks 作为中转服务器,那速度真的太慢了。
这里我用到了 mkcp 和 动态端口。
国内服务器配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 { "inbound" : { "port" : 8888 , "protocol" : "vmess" , "streamSettings" : { "network" : "kcp" } , "settings" : { "clients" : [ { "id" : "xxxxxxxxxx" , "level" : 1 , "alterId" : 32 } ] , "detour" : { "to" : "detour-kcp" } } } , "inboundDetour" : [ { "protocol" : "vmess" , "port" : "8889-9999" , "tag" : "detour-kcp" , "settings" : { } , "allocate" : { "strategy" : "random" , "concurrency" : 2 , "refresh" : 5 } , "streamSettings" : { "network" : "kcp" } } ] , "outbound" : { "protocol" : "freedom" , "settings" : { } } , "outboundDetour" : [ { "protocol" : "blackhole" , "settings" : { } , "tag" : "blocked" } ] , "routing" : { "strategy" : "rules" , "settings" : { "rules" : [ { "type" : "field" , "ip" : [ "0.0.0.0/8" , "10.0.0.0/8" , "100.64.0.0/10" , "127.0.0.0/8" , "169.254.0.0/16" , "172.16.0.0/12" , "192.0.0.0/24" , "192.0.2.0/24" , "192.168.0.0/16" , "198.18.0.0/15" , "198.51.100.0/24" , "203.0.113.0/24" , "::1/128" , "fc00::/7" , "fe80::/10" ] , "outboundTag" : "blocked" } ] } } , "transport" : { "kcpSettings" : { "mtu" : 1400 , "tti" : 20 , "uplinkCapacity" : 10 , "downlinkCapacity" : 10 , "congestion" : false , "readBufferSize" : 2 , "writeBufferSize" : 2 , "header" : { "type" : "none" } } } }
请自行修改配置文件的端口、动态端口范围、客户 ID 。
国外服务器配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 { "inbound" : { "protocol" : "dokodemo-door" , "port" : 1080 , "settings" : { "network" : "tcp,udp" , "timeout" : 30 , "followRedirect" : true } } , "outbound" : { "protocol" : "vmess" , "streamSettings" : { "network" : "kcp" } , "mux" : { "enabled" : true , "concurrency" : 8 } , "settings" : { "vnext" : [ { "address" : "8.8.8.8" , "port" : 8888 , "users" : [ { "id" : "xxxxxxxxxx" , "alterId" : 32 , "security" : "aes-128-gcm" } ] } ] } } , "transport" : { "kcpSettings" : { "mtu" : 1400 , "tti" : 20 , "uplinkCapacity" : 100 , "downlinkCapacity" : 100 , "congestion" : false , "readBufferSize" : 2 , "writeBufferSize" : 2 , "header" : { "type" : "none" } } } }
这里我们将 V2ray 的 inbound 设置为透明代理,这样 iptables 就能把国内流量转发到 V2ray 上。
更详细的设置 V2ray 设置可以参考他们家的官网 https://www.v2ray.com
IP 分流 iptables 要根据 IP 来分流,除了 iptables 之外,也没其他什么软件能做到了。但是单纯靠 iptables 来分流的话,会造成性能低下,这时候我们需要 ipset 。
下面这篇文章测试了在使用 ipset 和不使用 ipset 时 iptables 的性能。
http://blog.csdn.net/dog250/article/details/41171643
ipset 在这里推荐大家用这个项目来获取中国的 IP 地址,每月更新的。
https://github.com/17mon/china_ip_list
这里我只转发了 TCP 流量:
1 2 3 4 5 ipset -N chnroute hash:net maxelem 65536 ipset add chnroute $IP iptables -t nat -N V2RAY iptables -t nat -A V2RAY -p tcp -m set --match-set chnroute dst -j REDIRECT --to-port 1080 iptables -t nat -A OUTPUT -p tcp -j V2RAY
将上面的 $IP
换成你需要添加的 IP 地址,推荐大家用脚本来添加,这样可以设置成每月任务,自动更新。
更新前,通常需要先移除旧规则:
1 2 3 4 iptables -t nat -D OUTPUT -p tcp -j V2RAY iptables -t nat -F V2RAY iptables -t nat -X V2RAY ipset destroy chnroute
UDP 在上面配置 Shadowsocks 服务端的时候,我们已经做好了完整的 UDP 转发支持。但客户端支不支持,却又是另一回事,我们可以通过以下方法来测试。
测试 UDP 我们在服务器上打开一个 screen 运行 nc -lu 20000
来监听 20000 端口的 UDP 。
然后在需要测试的设备上,发一个 UDP 包到你的服务器上。
如果服务器能收到这个 UDP 包,那么就可以再新开一个 screen 运行 netstat -nu | grep 20000
来查看来源 IP ,通过来源 IP 来判断是否走了代理。
截止 2017-11-15 ,IOS 客户端就只有 Shadowrocket 支持 UDP 转发,Surge 和 ShadowRay 均为直连。
IPv6 支持 在上面配置 Shadowsocks 服务端的时候,已经做好了完整的 IPv6 支持,大家可以打开一下网站里面的 “技术信息” 来测试 IPv6 。
http://test-ipv6.com
截止 2017-11-15 ,IOS 客户端就只有 Surge 支持直接打开 IPv6 地址,Shadowrocket 和 ShadowRay 均失败。
去广告 & 境外受限 自建 DNS 服务器除了能达到去广告的目的外,还能解决部分国内服务商将域名在国外解析成 127.0.0.1
的问题(如网易云音乐)。
关于如何更好的解除境外受限,大家可以参考一下以下项目。
https://github.com/uku/Unblock-Youku
DNS 去广告的效果也是非常好的,因为是从根源上返回一个 fake IP ,无论是 HTTP 和 HTTPS 都支持。
但域名列表是需要经常更新的,大家可以写个脚本来定期更新。
这里推荐一下这个更新广告域名的项目:
https://github.com/StevenBlack/hosts
还有个小问题是,大多数的去广告 hosts 文件都是把 IP 指向了 127.0.0.1
或者 0.0.0.0
,但我服务器上是有 WEB Server 的,这会造成浏览器在尝试连接时,会等待结果而不是立即断开连接。我也试过把 IP 地址改成美国国防部的保留 IP 地址,然后通过 iptables 把所有出去的包 drop 了,效果也是不理想。推荐大家把 IP 指向 224.0.0.0
等特殊 IP 地址,实测不会拖慢网页加载速度。(以上结论暂时还没有进行过详细的测试,仅凭实测,如有错误,欢迎指出)
dnsmasq 配置 1 2 3 4 5 6 7 8 9 port=53 no-resolv server=2001 :4860 :4860 ::8888 server=8.8 .8.8 server=2620 :0 :ccc::2 server=208.67 .222.222 all -serverslisten-address=127.0 .0.1 ,::1 addn-hosts=/etc/dnsmasq_host/hosts
这里我设置了 4 个 DNS 上有地址,是 Google Public DNS 和 OpenDNS 的 IPv4 和 IPv6 地址,用了 all-servers
选项去并发查询这 4 个服务器,取最先返回结果的。
如果 Shadowsocks 开启了 IPv6 优先的话,hosts 文件也要加入 IPv6 的地址,推荐使用 'FF00::' 。
因为 DNS 服务器只是给本机使用的,安全起见可以只监听 127.0.0.1
。
addn-hosts
则为去广告所用的 hosts 文件。
大功告成~! 至此为此,安全性和各种功能都有了,可以无拘无束的安心上网了。
原文链接:https://stevenkwan.me/post/perfect-proxy-server.html
-- EOF --