HTTPプロキシのある環境でShadowsocks透過プロキシを構築する

HTTPプロキシのある環境でShadowsocks透過プロキシを構築する

はじめに#

プロキシを通さないと外に出れない環境でShadowsocks(以下SS)透過プロキシを動かして自由になってみます。

インターネット検閲では先輩である中華兄貴たちの情報を繋ぎ合わせてやってみました。

今回の環境はこんな感じ

  • 192.168.254.254:8080にプロキシサーバー、認証が必要
  • Shadowsocksサーバはss.example.com:443に設置
  • WIFI中継機として動作する
  • LAN側のブリッジは192.168.33.1/24

サーバーとしてArchLinuxARMをインストールしたQuaStationを使います。しかし使用しているソフトウェアはOpenWRTでも揃っているため同じ感じに構築できると思います。

*今回のポイントはSSサーバーが443で動いていることです。大抵のProxyでは443以外でソケット通信できないと思います。

*動けばいいやのかなりのお手軽セットアップなので終了処理などきちんとしていないところがあります。

Step1:Proxy超え#

ss-local、ss-redirなどは標準ではプロキシサーバー経由での接続をサポートしていないようです。

今回はGostを使って中継することにしました。armやamd64はもちろん、mipsまでサポートしています。しかしWZR-HP-G300Nで動かしたところ性能不足で不安定でした。

実はこれ自身でSSクライアントとして動作し、socks5プロキシになることができますが今回は使いません。

1
gost -L=tcp://127.0.0.1:8888/ss.example.com:443 -F http://%PROXY_USER%:%PROXY_PASS%@192.168.254.254:8080

これをsystemdデーモンとして登録します。

/etc/systemd/system/ss-gost.service

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
After=network.target

[Service]
User=root
Restart=always
TimeoutStartSec=90
ExecStartPre=
ExecStart=/usr/local/bin/gost -L=tcp://127.0.0.1:8888/ss.example.com:443 -F http://%PROXY_USER%:%PROXY_PASS%@192.168.254.254:8080
ExecStopPost=

[Install]
1
2
systemctl enable gost-ss
systemctl start gost-ss

Step2: ss-redir設定#

ArchLinuxではshadowsocks-libevパッケージでインストールできます。

1
pacman -S shadowsocks-libev

ss-redirの設定ですが、接続先がgostなので注意してください

/etc/shadowsocks-libev/config.json

1
2
3
4
5
6
7
8
9
10
{
"server": "127.0.0.1",
"server_port": 8888,
"password": "%SS_PASSWORD%",
"method": "chacha20-ietf-poly1305",
"local_address": "192.168.33.1",
"local_port": 54763,
"timeout": 300,
"reuse_port": true
}

local_addressを0.0.0.0にするとどのアドレスからも繋がるようになりますが、ファイアウォールしっかりしないとWAN側からも繋がってしまうので注意

Step3: ネットワーク設定#

今回のネットワーク構成はこんな感じです

  • 192.168.33.1/24のブリッジbr0を作成し、これをhostapdで使用
  • NetworkManagerを用いてwlp0s0でWi-Fi接続
  • WAN側のIPは192.168.1.0/23(多分あんまり関係ない)

ブリッジの作成方法は色々ありますが、Wi-Fi同様にNetworkManagerでサクッと作ってしまいました。

で、192.168.33.0/24からのパケットをマスカレードしたりss-redirの動いている54763へ転送したりします。

/etc/shadowsocks-libev/ss_up.sh

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
#!/bin/bash

# 環境に合わせてください
iptables -t nat -A POSTROUTING -s 192.168.33.0/24 -o wlp0s0 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i br0 -o wlp0s0 -j ACCEPT
sysctl -w net.ipv4.ip_forward=1


# Setup iptables
iptables -t nat -N SHADOWSOCKS

# Allow connection to reserved networks
iptables -t nat -A SHADOWSOCKS -d 100.100.2.0/24 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

# Redirect to Shadowsocks
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 54763

# Redirect to SHADOWSOCKS
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

############### set dns ################
echo 'nameserver 127.0.0.1' | tee /etc/resolv.conf

# thanks to https://github.com/jm33-m0/w411brk

これをss-redirのサービス開始時に実行されるようにします。

もっぱらルーターとして使うつもりで停止時のことは考えられてないので注意

/etc/systemd/system/ss-redir@.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Shadowsocks-Libev Custom Client Service Redir Mode for %I
Documentation=man:ss-redir(1)
After=network.target

[Service]
User=root
Restart=always
TimeoutStartSec=90
ExecStartPre=/etc/shadowsocks-libev/ss_up.sh
ExecStart=/usr/bin/ss-redir -u -c /etc/shadowsocks-libev/%i.json

[Install]
WantedBy=multi-user.target
1
2
3
systemctl daemon-reload
systemctl enable ss-redir@config
systemctl start ss-redir@config

Step4: DNS/DHCP#

dnsmasqを使用します。
また、DNS over HTTPSクライアントとしてdns-over-httpsを使用します。

1
pacman -S dnsmasq dns-over-https

DNS over HTTPS#

doh-client設定#

/etc/dns-over-https/doh-client.conf

先頭あたり、dnsmasqと競合するので53をコメントアウト

1
2
3
4
5
6
# DNS listen port
listen = [
#"127.0.0.1:53", #コメントアウト
"127.0.0.1:5380",
#"[::1]:53", #コメントアウト
"[::1]:5380",

65行ぐらい

ローカルDNSがあるならここに書きます

1
2
3
4
bootstrap = [
# Google's resolver, bad ECS, good DNSSEC
#"8.8.8.8:53",
#"8.8.4.4:53",

81行ぐらいのpassthroughtを全部コメントアウト(*ローカルDNSがある場合不要)

デフォルトではcloudflare-dns.comが使用されるようになっているのでそのつもりで行きます。

ss-tunnelでDoHサーバーを転送#

redirがbindしているのは192.168.33.1なので127.0.0.1からでは恩恵を受けれません。そこでcloudflare-dns.comだけss-tunnelを使って転送します。(DNATで回避する方法もあるらしいですが、横着なので頭わるわるな方法で行きます)

/etc/shadowsocks-libev/config-dns.json

1
2
3
4
5
6
7
8
9
10
11
    "server":"127.0.0.1",
"server_port":8888,
"password":"%SS_PASSWORD%",
"method":"chacha20-ietf-poly1305",
"local_address": "127.0.0.1",
"local_port": "443",
"tunnel_address": "cloudflare-dns.com:443",
"no_delay": true,
"reuse_port": true,
"mode": "tcp"
}

/etc/systemd/system/ss-tunnel-dns.service

1
2
3
4
5
6
7
8
9
10
11
[Unit]
After=network.target

[Service]
Type=simple
Restart=always
User=root
ExecStart=/usr/bin/ss-tunnel -c /etc/shadowsocks-libev/config-dns.json

[Install]
WantedBy=multi-user.target

/etc/hosts

1
127.0.0.1       cloudflare-dns.com

これでcloudflare-dns.comを使えるようになりました。

各サービスを動かしてテストします。

1
2
3
4
5
systemctl daemon-reload
systemctl start ss-tunnel-dns
systemctl enable ss-tunnel-dns
systemctl start doh-client
systemctl enable doh-client

レスポンス

1
dig @127.0.0.1 -p 5380 google.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; <<>> DiG 9.16.4 <<>> @127.0.0.1 -p 5380 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59033
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;google.com. IN A

;; ANSWER SECTION:
google.com. 260 IN A 172.217.161.78

;; Query time: 740 msec
;; SERVER: 127.0.0.1#5380(127.0.0.1)
;; WHEN: Sat Jul 04 20:28:12 JST 2020
;; MSG SIZE rcvd: 65

大丈夫みたいです。

DNS/DHCP#

一番下に追記

/etc/dnsmasq.conf

1
2
3
4
5
6
7
8
9
10
11
12
domain-needed
bogus-priv
local = /local/
domain = local
expand-hosts

server=127.0.0.1#5380

dhcp-range = 192.168.33.100, 192.168.33.200, 12h

dhcp-option = option:router, 192.168.33.1
dhcp-option = option:dns-server, 192.168.33.1

Step5: Hostapd#

どうもデバイスやらドライバやらの相性がかなりシビアみたいです。なんであまり参考にならないかも。

1
pacman -S hostapd

まず、いちいち変わられては困るのでインターフェイスの名前を固定します。

通常(?)だとmacで固定するみたいですが、僕の使ったカードは再起動するたびにmacが変わる子みたいなのでドライバで固定することにしました。

1
udevadm test /sys/class/net/wlanX

の出力で得られるパラメータを使って識別することができます。

/etc/udev/rules.d/99-uharu.rules

1
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="rtl8812au", NAME="wlan99"

次、hostapdがwlan99とbr0をを待ってから起動するようにします。

/etc/systemd/system/hostapd_mod.service

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
After=network.target sys-devices-virtual-net-br0.device sys-devices-virtual-net-wlan99.device
Wants=sys-devices-virtual-net-br0.device sys-devices-virtual-net-wlan99.device

[Service]
Restart=always
ExecStart=/usr/bin/hostapd /etc/hostapd/hostapd.conf
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

hostapdの設定ファイルはこんな感じです

/etc/hostapd/hostapd.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface=wlan99
driver=nl80211
bridge=br0
ssid=QuaStation
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase=hogehuga
rsn_pairwise=CCMP

起動してみます

1
2
systemctl start hostapd_mod
systemctl enable hostapd_mod

PCやスマホからAPが見え、接続できたら成功です。ついでにちゃんと外のIPになってるか確認します。

無事に外に出ることができました。

大量にソケットを貼れるからか体感OpenVPNより高速です。

測ってみたらほぼ回線速度が出ました。安定感は元の回線が不安定なのでなんとも言えないですが良さそうです。

終わりに#

メッチャ長い感じになってしまいましたが、設定は環境によって変わるのであくまで参考って感じですね。

僕もネットから拾った設定がそのままじゃ使えなくてこうやって書いてるわけですし…

完成したQuaRouterくんです。まあ元々ネットに繋いで使う物なので原点回帰的な…?

んで、QuaStationについてなんですが、旧ブログにある内容は完全にoutdatedになっております。

まとめるのも面倒でが乗らないんでてんぷ君のまとめたpastebinでも見てくだしあ…

https://pastebin.com/pm9sf4PT

ちなみに、なんでQuaStationに8821AE載ってるのにそれでhostapdやらないのかというと、どうもRF周りが特殊みたい(?)でアンテナが繋がってないような動作をするからです。

ドライバを読み解けば解決するのかもしれませんがお手軽セットアップなのでuharu君からパクってきました…(横着)

しかしQuaStationくん、BPIのカーネルが使えるようになったので大変便利です。

あと、Twitterにしか書いてないんですけどwvdialを使ってLTEモデムを動作させることができました。

Rakuten MNOを普通に使えているのでSIM Freeみたいです。これは思わぬ収穫…(KDDIバンドなのでバッチリ使える)

どうでもいいんですが、頻繁にネットワークを変えたりインターネットに繋がっていないネットワークを使ったりしてる上でWindows 10に対する恨みが増加の一途をたどっています。

まじでネットに繋がらないからって何度も再認証したり他のAPに繋いだりするなんて行儀悪すぎませんか…

M$社員はmac使ってWindows作ってるのか?って気持ちです。品質も保てないならローリングリリースなんてやめてください…

商用OSのくせに不具合多すぎです。

参考URL#

しかし透過プロキシのことを透明代理って書くの面白いですね…意味をたどればそのままなんですが

コメント

名前を入れてください
本文を入れてください

コメント読み込み中...

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×