
ドメイン名を使用してブラウザのルーティングパケットを制御し、特殊ドメイン名内のトラフィックパケットがVPNを通過し、特殊ドメイン名を持たない他のトラフィックパケットが通常のルーティングを通過するようにしたいと思います。私はdnsmasqとiptablesを使ってこれを達成しました。
しかし、私はdnsmasqとwireguardを含むラップトップ(deepinLinux 4.15.0-29deepin-generic)を使用しています。私のラップトップはVPNクライアントでもDNSサーバーでもあります。
次のように進んでください。
1DNSmasqの構成
構成ファイル:
root@notebook-PC:~# cat /etc/dnsmasq.conf
# auto-generated config file from /etc/config/dhcp
conf-file=/etc/dnsmasq.conf
domain-needed
log-queries
log-facility=/var/log/dnsmasq.log
no-resolv
localise-queries
read-ethers
bogus-priv
expand-hosts
local-service
cache-size=150
domain=lan
server=/lan/
server=223.6.6.6
# dhcp-leasefile=/tmp/dhcp.leases
# addn-hosts=/tmp/hosts
conf-dir=/etc/dnsmasq.d
stop-dns-rebind
rebind-localhost-ok
dhcp-broadcast=tag:needs-broadcast
dhcp-range=lan,192.168.10.100,192.168.10.249,255.255.255.0,12h
# no-dhcp-interface=eth0.2
そして/etc/dnsmasq.dにはファイルが1つしかありません。
root@notebook-PC:~# cd /etc/dnsmasq.d/
root@notebook-PC:/etc/dnsmasq.d# more newgfw.conf
# dnsmasq rules generated by ss_spec_dst_fw
# Last Updated on 2019-04-29 13:36:58
#
server=/030buy.com/8.8.8.8#53
ipset=/030buy.com/ss_spec_dst_fw
server=/0rz.tw/8.8.8.8#53
ipset=/0rz.tw/ss_spec_dst_fw
server=/1000giri.net/8.8.8.8#53
ipset=/1000giri.net/ss_spec_dst_fw
...........
「server」および「ipset」オプションは、これらのdnsに8.8.8.8を照会させ、応答ホストIPをipset ss_spec_dst_fwに追加します。
もちろん、dnsmasqをDNSサーバーとして追加することを忘れませんでした。
root@notebook-PC:~# nslookup
> google.com
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: google.com
Address: 172.217.24.206
Name: google.com
Address: 2404:6800:4005:806::200e
>
2wg-quickを修正してwireguardを起動する
すべてのトラフィックがVPNインターフェイスを通過するようにするwg-quick.shを見つけて、ルールを直接追加したい3行のコードをコメントアウトしました。
vi /usr/bin/wg-quick
................
add_default() {
local table proto key value
if ! get_fwmark table; then
table=51820
while [[ -n $(ip -4 route show table $table) || -n $(ip -6 route show table $table) ]]; do
((table++))
done
cmd wg set "$INTERFACE" fwmark $table
fi
proto=-4
[[ $1 == *:* ]] && proto=-6
# cmd ip $proto route add "$1" dev "$INTERFACE" table $table
# cmd ip $proto rule add not fwmark $table table $table
# cmd ip $proto rule add table main suppress_prefixlength 0
while read -r key _ value; do
[[ $value -eq 1 ]] && sysctl -q "$key=2"
done < <(sysctl -a -r '^net\.ipv4.conf\.[^ .=]+\.rp_filter$')
return 0
}
................
その後、ワイヤガードが始まると
wg-quick up wgnet0
wgnet0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420
inet 192.168.32.2 netmask 255.255.255.0 destination 192.168.32.2
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
RX packets 15 bytes 1380 (1.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 615 bytes 21652 (21.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.3 netmask 255.255.255.0 broadcast 192.168.1.255
wgnet0 は特別なドメイン名トラフィックを介して使用される VPN インターフェイスであり、wlp5s0 は通常のトラフィックで使用されるパブリックインターフェイスです。
ip rule show follow
root@notebook-PC:~# ip rule
0: from all lookup local
220: from all lookup 220
32766: from all lookup main
32767: from all lookup default
[3]ルールとルーティング構成
/etc/iproute2/rt_tables ファイルに wg テーブルを追加します。
root@notebook-PC:~# cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
201 wg
0 unspec
#
# local
#
#1 inr.ruhep
次に、次のようにルールを追加します。
ip -4 route add table wg default via 192.168.32.1 dev wgnet0 metric 100
ip rule add prio 100 from all fwmark 51820 lookup wg
root@notebook-PC:~# ip rule show all
0: from all lookup local
100: from all fwmark 0xca6c lookup wg
220: from all lookup 220
32766: from all lookup main
32767: from all lookup default
root@notebook-PC:~# ip route show table wg
default via 192.168.32.1 dev wgnet0 metric 100
[4]タグを有効にする
root@notebook-PC:~# cat /proc/sys/net/ipv4/tcp_fwmark_accept
0
root@notebook-PC:~# sysctl -w net.ipv4.tcp_fwmark_accept=1
net.ipv4.tcp_fwmark_accept = 1
root@notebook-PC:~# cat /proc/sys/net/ipv4/tcp_fwmark_accept
1
[5]チェーンとルールを追加するためのiptablesの設定
前の手順の結果として、VPNインターフェイスにルーティングする必要があるipset ss_spec_dst_fwにIPを追加してから、これらのパケットを表示する必要があります。
これで記事(http://www.faqs.org/docs/iptables/traversingoftables.html)、iptablesは2つのステップにルーティング決定をします。ローカルプロセス(この場合、私のラップトップのブラウザプロセス)は、OUTPUTプロセスに入る前にルーティングを決定し、再ルーティングするにはローカルプロセスが必要です。
だから私が行った方法に従ってOUTPUT_directチェーンにルールを追加し、ipset ss_spec_dst_fwと一致するすべてのパケットをPREROUTING_directチェーンにジャンプし、PREROUTING_directチェーンにルールを追加し、ipset ss_spec_dst_fwと一致するすべてのパケットを下の図に示すようにマークしました。示す:
PREROUTING_direct chain() が ACCEPT パケットとして使用されると、次のようにルーティング決定が再開されます。
root@notebook-PC:~# iptables -t mangle -A OUTPUT_direct -m set --match-set ss_spec_dst_fw dsts -j PREROUTING_direct
root@notebook-PC:~# iptables -t mangle -A PREROUTING_direct -j CONNMARK --restore-mark
root@notebook-PC:~# iptables -t mangle -A PREROUTING_direct -m set --match-set ss_spec_dst_fw dsts -j MARK --set-mark 51820
root@notebook-PC:~# iptables -t mangle -A PREROUTING_direct -j CONNMARK --save-mark
root@notebook-PC:~# iptables -t mangle -A PREROUTING_direct -j ACCEPT
root@notebook-PC:~#
root@notebook-PC:~# iptables -L -t mangle
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
PREROUTING_direct all -- anywhere anywhere
PREROUTING_ZONES_SOURCE all -- anywhere anywhere
PREROUTING_ZONES all -- anywhere anywhere
Chain INPUT (policy ACCEPT)
target prot opt source destination
INPUT_direct all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
FORWARD_direct all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
OUTPUT_direct all -- anywhere anywhere
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
POSTROUTING_direct all -- anywhere anywhere
Chain FORWARD_direct (1 references)
target prot opt source destination
Chain INPUT_direct (1 references)
target prot opt source destination
Chain OUTPUT_direct (1 references)
target prot opt source destination
PREROUTING_direct all -- anywhere anywhere match-set ss_spec_dst_fw dst
Chain POSTROUTING_direct (1 references)
target prot opt source destination
Chain PREROUTING_ZONES (1 references)
target prot opt source destination
PRE_public all -- anywhere anywhere [goto]
PRE_public all -- anywhere anywhere [goto]
Chain PREROUTING_ZONES_SOURCE (1 references)
target prot opt source destination
Chain PREROUTING_direct (2 references)
target prot opt source destination
CONNMARK all -- anywhere anywhere CONNMARK restore
MARK all -- anywhere anywhere match-set ss_spec_dst_fw dst MARK set 0xca6c
CONNMARK all -- anywhere anywhere CONNMARK save
ACCEPT all -- anywhere anywhere
Chain PRE_public (2 references)
target prot opt source destination
PRE_public_log all -- anywhere anywhere
PRE_public_deny all -- anywhere anywhere
PRE_public_allow all -- anywhere anywhere
Chain PRE_public_allow (1 references)
target prot opt source destination
Chain PRE_public_deny (1 references)
target prot opt source destination
Chain PRE_public_log (1 references)
target prot opt source destination
root@notebook-PC:~#
これですべての作業が完了しましたが、結果は私のものではありません。ただし、動作しません!
ipset ss_spec_dst_fw は DNS クエリの IP 応答を追加しました。
root@notebook-PC:~# ipset list ss_spec_dst_fw
Name: ss_spec_dst_fw
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 5368
References: 2
Number of entries: 113
Members:
216.58.221.229
172.217.161.170
172.217.161.173
203.208.43.95
216.58.199.5
216.58.221.234
216.58.199.110
172.217.161.141
172.217.161.133
216.58.200.74
172.217.161.138
203.208.39.215
...........
dnsmasq が正常に動作したら、次の IP パスをテストします。
root@notebook-PC:~# ip route get 216.58.221.229
216.58.221.229 via 192.168.1.1 dev wlp5s0 src 192.168.1.3 uid 0
cache
この結果は私が予想したものとは異なります。 192.168.1.1 は VPN ゲートウェイではなく、一般的なゲートウェイです。次に、タグ51820(上記のコードのタグ値)を追加してテストします。
root@notebook-PC:~# ip route flush cache
root@notebook-PC:~# ip route get 216.58.221.229 mark 51820
216.58.221.229 via 192.168.32.1 dev wgnet0 table wg src 192.168.32.2 mark 0xca6c uid 0
cache
root@notebook-PC:~# ip route flush cache
root@notebook-PC:~# ip route get 216.58.221.229
216.58.221.229 via 192.168.1.1 dev wlp5s0 src 192.168.1.3 uid 0
cache
この結果は、IP ルールとルートが正常であることを確認しますが、そうでない場合は、iptables がこれらのパケットを表示することを確認し、ルート 216.58.221.229 を追跡し、ログを記録します。
root@notebook-PC:~# traceroute 216.58.221.229
traceroute to 216.58.221.229 (216.58.221.229), 30 hops max, 60 byte packets
1 * * *
2 * * *
3 * * *
4 * * *
5 * * *
6 *
トレースログをリンクします。
root@notebook-PC:~# conntrack -E -d 216.58.221.229
[NEW] udp 17 30 src=192.168.1.3 dst=216.58.221.229 sport=44951 dport=33434 [UNREPLIED] src=216.58.221.229 dst=192.168.1.3 sport=33434 dport=44951 mark=51820
[NEW] udp 17 30 src=192.168.1.3 dst=216.58.221.229 sport=34181 dport=33435 [UNREPLIED] src=216.58.221.229 dst=192.168.1.3 sport=33435 dport=34181 mark=51820
[NEW] udp 17 30 src=192.168.1.3 dst=216.58.221.229 sport=58059 dport=33436 [UNREPLIED] src=216.58.221.229 dst=192.168.1.3 sport=33436 dport=58059 mark=51820
[NEW] udp 17 30 src=192.168.1.3 dst=216.58.221.229 sport=40739 dport=33437 [UNREPLIED] src=216.58.221.229 dst=192.168.1.3 sport=33437 dport=40739 mark=51820
........................
マーク51820完了!
今混乱しています。私は何を逃しましたか?
答え1
mangle/PREROUTING
ローカルで開始されたパケットはチェーンを介して転送されません。タグ付けルールをmangle/OUTPUT
チェーンに移動する必要があります。 「iptables-save -c
」またはiptables -L -n -v
「あなたの場合、カウンターはゼロになる可能性があります。