组织结构是生产力。诚然。。。

“工匠精神” 精心打造一个代理服务器


  1. 前言
  2. 代理入口
    1. Shadowsocks
      1. 配置 Shadowsocks
      2. Shadowsocks 优化
      3. Shadowsocks 配置文件
  3. 兼容 WEB
    1. SNIPROXY
  4. 中转服务器
    1. V2ray
  5. IP 分流
    1. iptables
      1. ipset
  6. UDP
    1. 测试 UDP
  7. IPv6 支持
  8. 去广告 & 境外受限
    1. dnsmasq 配置
  9. 大功告成~!

前言

首先,本文会涉及众多代理软件的名字,但因为本人是在国外,用代理软件是回国的,是一名爱国青年。所以请大家不要把代理的方向反转来用。

在国外很多时候打开国内的网站非常缓慢,而且时不时有境外 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 = 1n
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-servers
listen-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 --

页阅读量:  ・  站访问量:  ・  站访客数: