私の別のスレッドで私はいくつかの興味深いことについて話していました iptablesポリシーと状態について 、私はもっと理解したいと思いますDHCPがどのように動作し、iptablesがそれを理解するかについて。
ETH0は、ルーターから動的IPを受信するメインスイッチに接続され、インターネットアクセスだけでなく、外部ネットワークへのアクセスも取得します。
ETH1は、XクライアントがそのサーバーからIPSこのサーバーから受信する内部スイッチに接続されている内部カードです
ETH1ネットワークは192.168.1.0/255.255.255.0で、サーバーIPは192.168.1.254です。
私が理解したところによると、dhcpはbootpプロトコルなので、すべてを削除するファイアウォールポリシーがある場合でも、ネットワークはDHCPを受信します。これは、私が行ったテストではtrueのようです。
Tcpdumpから:
root@test:~# tcpdump -i eth1 port 67 or 68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:34:03.943928 IP 192.168.1.2.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:03.957647 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
11:34:06.492153 IP 192.168.1.2.bootpc > 192.168.1.254.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:06.506593 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
Iptablesが何をするかを確認するために簡単なログルールを作成しました:
root@test:~# tail -f /var/log/syslog
Oct 15 11:30:58 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9527 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:31:43 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9529 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:33:32 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9531 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:34:03 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9533 PROTO=UDP SPT=68 DPT=67 LEN=311
これがその瞬間の私のiptablesルールです:
# deny all traffic
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
# Use stateful inspection feature to only allow incoming connections
# related to connections I have already established myself
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# allow all traffic on lo interface
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
したがって、すべてをドロップするデフォルトのポリシーを使用しても、ネットワークでDHCPを取得できますが、IPの更新などにはかなり時間がかかります。
ファイアウォールに次のルールを追加すると、
$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT
クライアントdhcpを更新するのに、かなり時間がかかります。
上記を考慮:
良いリンクを知っていれば、たくさん取ってもかまいません:)
私が答えます#2:いいえ。
IPアドレスを取得すると、dhcpデーモンはネットワークインターフェースへのrawソケットを作成し、UDPプロトコル自体を処理します。したがって、UDPパケットはiptablesを通過しません。
DhcpデーモンがUDPを実装する必要があるのは、インターフェースがIPアドレスを持っている場合、カーネルはUDP(実際にはすべてのTCP/IPスイート)しか処理できないためです。以前は、dhcpデーモンは最初にインターフェイスに0.0.0.0のIPアドレスを与えていましたが、それは機能しなくなりました。
追加
$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT
dHCPDの更新を高速化します。:)入力と出力の両方で機能します。 iptablesではなくebtablesでdhcpdをDROPできます。 IP内ではなく、0.0.0.0でリッスンするDHCPD
OpenWRT Kamikaze 7.09 = 2.4.34およびbusybox 1.4.2のudhcpcでの私の最近の観察:
私はOUTPUTチェーンとINPUT方向に「ACCEPT」ポリシーを持っていますが、もともとこのクラシックなキャッチオールルールに依存していました。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
WANインターフェース上で(私のudhcpcに)で)DHCP応答を許可します。つまり、これは、私のISPのアップストリームDHCPサーバーがIPアドレスを私に割り当てる場所です。
最初のDHCP交換(discover、offer、request、ack)とDHCPリースの更新(request、ack)の違いに注意してください。
ブート後、udhcpcは完全な初期交換によって開始されます。その交換は成功するでしょう。そして、もう1、2回の更新も成功します-要求と承認だけです。私のISPのDHCPサーバーは通常、約1時間から1.5時間の更新時間を要求するため、DHCPクライアントは30〜45分ごとに更新を要求します(この動作はRFCに基づいています)。
しかし、3回目か4回目の更新で、面白くなっていきます。 TCPdumpは約3回ほどの更新の試みを示し、その後完全な初期交換が行われます-ほんの数分または数秒の期間内で。 udhcpcがそれを取り戻したものが気に入らなかったかのように:-(そして、最終的に完全な交換に満足します。その後、30分での更なる更新が成功し、そして物語は再び繰り返されます。
何か問題があるのは、おそらくカーネルの接続追跡にあることがわかりました。 conntrackエントリが2時間ほどで期限切れになり、サーバーからのACKが実際にはソケットをリッスンしているudhcpcにならないため、その後のDHCP更新が失敗するかのように。 tcpdump(libpcap)はrawインターフェースで待機し、iptablesの対象になる前に、入ってくるすべてのパケットを確認できることに注意してください。 udhcpcが更新をあきらめ、絶望的に(DISCOVERで始まる)完全な交換を使用して最初からやり直そうとすると、カーネルは新しいconntrackエントリを確立し、関連するパケットをしばらく理解できます...
案の定、次のようなものを追加したら:
iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT
更新は永久に機能するようです。
次のtcpdump cmdline argsが役立つ場合があります。
tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68
注:-vv
は、詳細なディセクタ出力を要求します。 eth0.1
is my WAN= port( "NAT outside"インターフェース)。
ACKパケットの興味深い属性は、LTです。フィールド=推奨/最大許可リース時間(秒)。 DHCP要求はポート68からポート67に送信されます。応答はポート67からポート68に送信されます。