iptables --set-mark-異なるインターフェースを介して異なるポートをルーティングする


13

短編、
3つのインターフェイス、eth0(LAN)、eth1(ADSL)、eth2(4G)。
eth0-> eth1:動作
(ポート80、443、4070)eth0-> eth2:発生しません


これは、アイデアのグラフィカルな表現です。

eth2経由のポート80および443、および
eth1経由の残りのポート
ここに画像の説明を入力してください

Netscheme:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






この新しいスクリプトは、22と4070を適切なテーブルに転送します。
ただし、そのテーブルに到達した後、eth2に再ルーティングされません。




このスクリプトは、22と4070を除いて機能します!

(ポート80はコメント化されておらず動作しますが、間違っているeth1を介して動作します。)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









古いスクリプト:


  Ignore everything below unless you're interested in retracing my steps!!




私が何か悪いことをした場合に備えて、環境をセットアップするためにrouter.shスクリプトを作成しました。4G接続に送信したい3つのポートと、固定電話ADSL接続経由で送信したいポートがあります。これを行うために、デフォルトのルートでパッケージをマングルし、--dport == 443 | 80 | 4070

ただし、これは機能しません。それでも、固定電話を経由してルーティングされています。

これは私のスクリプトのようです:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

また、これらの3つをスクリプトのbottomgに追加しようとしました。

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

また、成功せずに試しました:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

最後に、試してみました:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

ルーティングは機能します。Webをブラウズしたり、音楽などを聴いたりできますが、間違ったインターフェイスを使用してそれを行っています。私は長い間グーグルで検索してきましたが、自分が何をしているのか、なぜそれをしているのかを理解するための断片を見つけました。tcでトラフィックシェーピングを行うこともできますが、iptablesでパッケージをマークすることで可能であれば、長い道のりを助けてくれるでしょう。

私の推測では、異なるルール、主にマスケレード部分で順序を間違えているのでしょうか?それともそこにあるべきか?

誰かがDNATポートに、外部インターフェイス(1つまたは両方のプロトコル)から内部10.0.0.0アドレス空間へのtcp:80の方法を説明できますか?



出力:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

これらの指示に従ってください:他のいくつかの関連するスレッドの中で、
異なるインターフェイス上の出力トラフィック、宛先上の
ポートに 基づくiptables-forward-specific-port-to-specific-nic


申し訳ありませんが、Apache localhosteth2インターフェイスのアドレスにのみバインドしない理由はありますか?
ヤンマレク

@JanMarek:ここではApacheについて言及していません。また、情報のために、ソケットをethXIPアドレスにバインドすると、ethXLAN 上のホストがIPアドレスを使用してローカルサーバーにアクセスできethYなくなり、ホストがIPアドレスethYを使用してサーバーにアクセスできなくなりますethX。Linuxは弱いホストモデルを使用することに注意してください。
BatchyX

OK、Apacheサーバーだけでなく、もっと多くのWebサーバーがあります...しかし、インターフェースeth2でWebサーバーをバインドすることは簡単な解決策です。しかし、私は間違っている可能性があります。
ヤンマレク

回答:


4

BatchyXはすでにiptablesとルーティングに関する非常に良い説明をしているので、怠を行使してスクリプトに直接行きます。

192.168.0.91を介してポート80,443,22,4070へのすべてのトラフィックをNATする必要があります。残りはすべて192.168.1.254を介してNATします。

私はテストをやり直し、このガイドに従っています。このガイドに欠けているのは、スクリプトの最後の3行です。私は別のポートからそれを見つけましたが、そのリンクを追跡できませんでした。

テスト済みの作業スクリプトです。

デフォルトルートが必要

スクリプトに入れなかったことの1つは、デフォルトルートの設定です。そのはず

route add default gw 192.168.1.254

するとroute -n、それが唯一のデフォルトルート(Dest:0.0.0.0)になります。

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

#iptablesのリセット/フラッシュ
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -tマングル-F
iptables -tマングル-X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

#Reset / Flush / Setup IP Route(表4)
ip route flush table 4
ip route show table main | grep -Ev ^ default | ROUTEを読みながら ip route add table 4 $ ROUTEを実行します。やった
ip route add 192.168.0.1を介したデフォルトのテーブル4

#一致するD.Portでパケットをマーク
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNATルール
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

#IPルート
ipルールはfwmark 4テーブル4を追加します
IPルートフラッシュキャッシュ

#IPスタック
#これはガイドの欠落部分です
エコー1> / proc / sys / net / ipv4 / ip_forward
/ proc / sys / net / ipv4 / conf / * / rp_filterのf echo 0> $ fを実行します。やった
エコー0> / proc / sys / net / ipv4 / route / flush

PS1:要するに、MASQUERADE何らかのロードバランシングを必要とする、または着信トラフィックを処理するためにDNATを必要とする複数の外部IPを持つNATに対しては(ほとんどの場合、そして間違いなくあなたの場合は)動作しません。SNAT方向制御が必要です。

PS2:純粋なiptablesでは不十分です。


まず、スクリプトに直接アクセスしてください。
トルクス

うーん、大幅な修正が必要な場合があります。結果を教えてください。
ジョンシウ

改訂され、現在動作しているはずです。
ジョンシウ

甘い、短い時間であなたに戻ります:D
トルクス

私はあなたを愛し、頭痛がとても多く、あなたはそれを解決しました!ありがとうございました!
Torxed

5

注:古いスクリプトを無視して、最初のスクリプトのみを検討しました。

  • 現在のiptablesを使用して、netfilterモジュールを手動でmodprobeする必要はありません。これは、カスタム接続トラッカーにのみ必要です。
  • 混同しないでくださいrouteip route。これは純粋な悪です。ipどこでも使うだけでifconfigroute
  • /etc/iproute2/rt_tables再起動後もリセットされません。同じエントリを何度も追加するのは得策ではありません。一度行うだけで済みます。rt_tables名前エイリアスを数値に定義するだけで、構成は変更されないことに注意してください。

  • さあ、iptablesあなたのFORWARDチェーンで、LANから4Gへのパケットをドロップします。これは悪いです。FORWARDフックが行われ、ルーティングの後に使用されています。この時点で、すべてのポリシールーティングが完了し、パケットを4GとADSLのどちらに送信するかはすでにわかっています。中FORWARDまたは後に再ルーティングは行われませんFORWARD(厳密に言えばPOSTROUTING、深刻な場合には後で再ルーティングを行うことができますが、ポイントに戻ります)。

ルーティングについて:Ubuntuはデフォルトでリバースパスフィルタリングを有効にしていることに注意してください。リバースパスフィルタリングは次のように機能します:カーネルがインターフェイスAからパケットを(転送される場合も転送されない場合も)受け取ると、送信元アドレスと宛先アドレスを反転し、結果のパケットがインターフェイスA経由でルーティングされるかどうかを確認します。そうでない場合、パケットはアドレススプーフィングの試みとしてドロップされます。

から受信したパケットの場合eth0、これは問題ではありません。から受信したパケットの場合eth1、これも問題ではありません。ソースIPアドレスと宛先IPアドレスを逆にするとき、カーネルはそれをtableのデフォルトルートにするからですmain。からeth2マークされていないから受信したパケットの場合、これは問題です。これは、カーネルがtableのデフォルトルートにヒットし、mainこれらのパケットがから受信されたはずだと考えるためですeth1。最も簡単な解決策は、eth1でリバースパスフィルタリングを無効にすることです。

sysctl -w net.ipv4.conf.eth1.rp_filter=0

すべての素晴らしいコメントとはい、私の側にはいくつかの誤ったロジックがあります。たとえば、毎回rt_tablesに追加し、特に特定のテーブルをクリアしないだけでなく、私はそうする必要があります:)私はすべてを試してみますそれが機能する場合、もしそうなら、あなたに+50、そして最も重要なことは、あなたが背後の人をビットと平和に刻まれることから救った!:)
トルクス

以下のスクリプトは動作しますが、感謝の気持ちもあります。考えてみてください。rp_filter= 0は大いに役立ちました。:D
Torxed

@BatchyXは非常に有益で、あなたにも賛成票を投じます。
ジョンシウ

@Torxed私が見た投稿では、すべてのインターフェイスのrp_filterを無効にする必要があると述べました。それが他の方法で動作するかどうかはわかりません。
ジョン・シュー

@JohnSiu:問題のあるインターフェースでrpフィルターを無効にするだけです。その場合、マークが設定されていない場合、そのインターフェイスに向かうルートがないため、eth1です。eth2にはこのような問題はありません。デフォルトルートがそのインターフェースに入るためです。eth0の場合、実際にはrpフィルターを有効にしておくと便利です。そうしないと、LAN上の誰かがソースアドレスがインターネット上にあり、宛先アドレスがLAN上にあるIPパケットを偽造でき、ルーターはそれを喜んで受け入れて転送します戻る... eth0。
BatchyX
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.