web-dev-qa-db-ja.com

ルートテーブルのトラフィックをマークするIPTableマングルルール

Ubuntu Server 16.04を使用してVPNルーターをセットアップしようとしています。

トラフィックが漏洩しないように、またはVPNに障害が発生した場合にルーターが閉じられないように、ルーターをセキュリティで保護するように構成しています。

ルーターには、インターネット接続のためにワイヤレスネットワークに接続するワイヤレスインターフェイス(wlp2s0)と、ラップトップを接続するイーサネットインターフェイス(enp1s0)があります。

理想的には、openvpnは起動時に実行され、wlp2s0を使用してtun0インターフェイスを作成します。次に、いくつかのiptableルールがenp1s0トラフィックをtun0に転送します。

トラフィックリークを防止するという私の目標を達成するために、すべてのルートをフラッシュしてからwlp2s0のローカルサブネットルートをMAINテーブルに追加する起動スクリプトを作成しました。また、テーブル100のデフォルトルートwlp2s0を追加します。

Openvpnトラフィックをマークするiptables mangleルールを追加し、マークされたトラフィックがテーブル100を使用するfwルールを追加しました。

したがって、基本的には、openvpnトラフィックのみがワイヤレスのデフォルトルート(テーブル100)を使用できるようにして、トンネルを作成できるようにします。他のすべてのトラフィックはローカルまたはトンネルを通過します。

私の起動スクリプトは正常に動作し、起動時に適切なルートを作成します。私のiptableルールとfwルールも正しいようです。

問題は、openvpnトラフィックがiptablesマングルルールに該当しないように見えることです。

openvpnトラフィックをマークするiptableルール。

iptables -t mangle -A OUTPUT -p tcp --dport 501 -j MARK --set-mark 2

起動スクリプト

ip route add table 100 default via 192.168.0.1 dev wlp2s0
ip rule add fwmark 0x2 table 100
ip route flush table main
ip route add 192.168.0.0/24 dev wlp2s0

ほとんどの人が要求するさまざまなコマンドの出力

administrator@ubuntu-svr:~$ Sudo iptables -t mangle -L -v
Chain PREROUTING (policy ACCEPT 6153 packets, 1859K bytes)
 pkts bytes target     prot opt in     out     source               destination                  

Chain INPUT (policy ACCEPT 1961 packets, 297K bytes)
 pkts bytes target     prot opt in     out     source               destination       

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        

Chain OUTPUT (policy ACCEPT 1348 packets, 128K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:501 MARK set 0x2                  

Chain POSTROUTING (policy ACCEPT 1348 packets, 128K bytes)
 pkts bytes target     prot opt in     out     source               destination         

administrator@ubuntu-svr:~$ ip rule
0:  from all lookup local 
32765:  from all fwmark 0x2 lookup 100 
32766:  from all lookup main 
32767:  from all lookup default 

administrator@ubuntu-svr:~$ ip route show table main
192.168.0.0/24 dev wlp2s0  scope link 

administrator@ubuntu-svr:~$ ip route show table 100
default via 192.168.0.1 dev wlp2s0 

administrator@ubuntu-svr:~$ ip route get 8.8.8.8 mark 0x2
8.8.8.8 via 192.168.0.1 dev wlp2s0  src 192.168.0.209  mark 2

上記の出力から、適切なルート、iptable mangleルール、fwルールがすべて適切に配置されていることがわかります。

「ip route get」getコマンドを発行すると、マークされたトラフィックに対して適切なルートが選択されていることがわかります。

ただし、iptablesマングルルールはヒットしていません。 「telnet 8.8.8.8 501」を発行しましたが、まだルールに違反しています。トラフィックはローカルで生成され、tcp 501にヒットしますが、これはルールに一致するはずです。

Openvpnトラフィックは、ルーター自体から生成されます。マングルのOUTPUTチェーンであるiptablesのmanページは、ローカルで生成されたトラフィックのPREROUTE決定を変更するためのものです。

私はここで完全に途方に暮れています。私は同様の問題を抱えている人々の他の投稿を読みましたが、解決策を見つけることができないようです。

2
Matt M

問題は、テーブルmainにデフォルトルートがないことです。これは、ip route get ... mark ...で確認する場合は検出できません。パス全体が直接渡された「ソリューション」で短絡されているためです。

デフォルトルートがないため、パケットがマングルのOUTPUTチェーンに到達する前に、8.8.8.8へのルートルックアップは「ネットワークに到達できません」で失敗します。

テーブルmainanyデフォルトルートを追加すると(有効な構文である限り、存在しないルーターを使用しても)、意図したフロー:

  • パケットが生成され、
  • ルートはip ruleテーブルで初めて確認され、存在すると見なされます。
  • マングルのOUTPUTチェーンを横断し、マークを継承し、
  • 再ルーティングされ(reroute check in Netfilter and General Networkingのパケットフロー )、2回目にip ruleテーブルのルックアップがトリガーされます。
  • テーブル100の初期ルックアップを取得し、その最終ルート「via 192.168.0.1 dev wlp2s0」を取得します。

したがって、LANでどのホストにも属していないIPを選択すると、たとえば、192.168.0.250をスクリプトに追加すると、次のようになります。

ip route add table 100 default via 192.168.0.1 dev wlp2s0
ip rule add fwmark 0x2 table 100
ip route flush table main
ip route add 192.168.0.0/24 dev wlp2s0
ip route add default via 192.168.0.250 dev wlp2s0

質問で行われたテストを解決します:

  • 宛先tcpポート501で作成されていない接続は、192.168.0.250へのARP要求をトリガーします。これは、「ネットワークに到達できません」ではなく、「ホストへのルートがありません」というメッセージで3秒後にタイムアウトするはずです。
  • 宛先tcpポート501で行われたすべての接続は(ARP要求を解決して)192.168.0.1を経由します
1
A.B