iptablesにフラグが付けられているが例外にルーティングされないのはなぜですか?

iptablesにフラグが付けられているが例外にルーティングされないのはなぜですか?

ドメイン名を使用してブラウザのルーティングパケットを制御し、特殊ドメイン名内のトラフィックパケットが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「あなたの場合、カウンターはゼロになる可能性があります。

おすすめ記事