Armadilloフォーラム

【A6E】 iptablesで外部からのアクセスを制限すると外向きの通信もブロックされる

k-nishiki

2025年3月12日 9時21分

==========
製品型番:A6E Cat.1 WLAN/BT(BTOモデル)
Debian/ABOSバージョン:base_os 3.20.3-at.7
カーネルバージョン:5.10.230-0
3G/LTE モジュール情報 (Debianのみ):
その他:
==========
グローバル固定IPアドレス付きのSIMを用い、インターネット上のサーバからのインバウンド通信を許可する際に、特定のサーバのIPアドレスに対するIPフィルタリングを設定しています。添付ファイルの apply_ipfilter.sh によりiptablesを変更した後に、デバイス側から外部へのアウトバンド通信がブロックされてしまいます(例えば、ping 8.8.8.8 や curl "https://1.1.1.1" などの通信が失敗)。添付ファイルの clear_ipfilter.sh によりiptablesを元に戻した後は、アウトバンド通信がブロックされず正常に通信が行えています。どのようにルールを修正すれば、インバウンド通信のみ制限し、アウトバンド通信は制限しないことを実現できますでしょうか?

ファイル ファイルの説明
apply_ipfilter.sh IPフィルターを追加する処理
clear_ipfilter.sh 追加したIPフィルターを削除する処理
コメント

at_dominique.m…

2025年3月12日 10時12分

k-nishikiさん

お世話になっています、
マルティネです。

apply_ipfilter.sh を見たところ「接続済み」のパケットを受ける設定はないからです。

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT」を drop前に追加していただければ、期待通りに動くと思います。

全般な案内で申し訳ないですが、全体的に参考にできる資料はいくつか見つかりましたので、よろしければご参考にしていただければ幸いです:

弊社の標準ガイド: https://manual.atmark-techno.com/armadillo-guide-std/armadillo-guide-st…
外部のサイトですが、各ルールを説明してくれてます: https://knowledge.sakura.ad.jp/4048/

よろしくお願いします

マルティネさん、
いつもお世話になっております。

アドバイスの通りに修正後は期待した動作になりました。
参考情報の提供もあわせて、ありがとうございます。

マルティネさん、

修正後にアウトバンド通信はブロックされなくなったのですが、本来ブロックされるはずのインバンド通信で奇妙な動作をします。
・アクセスを許可したIPアドレスからの要求 ping、ssh、httpはすべて許可(正常)
・アクセスを許可していないIPアドレスからの要求 ping、sshは拒否されますが、http要求は許可されています
なにか見落としている点がありましたらご教示ください。

at_dominique.m…

2025年3月12日 17時24分

マルティネです。

> ・アクセスを許可していないIPアドレスからの要求 ping、sshは拒否されますが、http要求は許可されています

問い合わせ時に添付していただいた apply ファイルに related,established のルールを追加しただけの変更ですね?

そのスクリプトを見た限りでは http (tcp/80か443) と ssh (tcp/22)に違いがあるには見えませんので、
念のため「iptables -S」の出力を共有していたでけますか?(特定な IP をマスクしていただいた構いません)
(スクリプトの頭でテーブルを削除してますので、違いはないはずですが…)

また、/proc/net/nf_conntrack を確認すると接続状態も確認できますので、
そのファイルから間違って許可された接続の行も確認させてください。

よろしくお願いします

マルティネさん、
お世話になっております。

修正した点は、 related,established のルールを追加した以外に、INPUTのデフォルトポリシーをDROPに変更しました。
念のため、修正したシェルプログラムを添付します。また設定後の内容も添付します。
ご面倒をおかけしますが、よろしくお願いいたします。

ファイル ファイルの説明
ipfilter-1.txt IPフィルター適用後の設定
apply_ipfilter-1.sh 修正後のIPフィルター設定

at_dominique.m…

2025年3月12日 18時31分

マルティネです

> 念のため、修正したシェルプログラムを添付します。また設定後の内容も添付します。

ありがとうございます。

確認しますが、ipfilter-1.txt ファイルの conntrack ファイルによるとインバウンド通信の接続はなかったので、http リクエストを受信した後の出力でしょうか?
(dst=34.199.160.42 の https 接続は、Armadillo Twin agent による armadillo からの接続です。(netstat -npt で接続中のプロセスを確認できます)
Armadillo Twin サービスをご利用してなくても「困った時に後から登録して使えるように…」という理屈で接続しますが、クライアントの作りとして SWU の鍵がないと何もできないので、セキュリティの面では問題ないはずです。
ご迷惑でしたら「persist_file -d /etc/runlevels/default/armadillo-twin-agentd」等でサービスは起動時に起動されなくなります)

インバウンドで他の接続があればお手数ですがその時の conntrack ファイルで確認できれば幸いです。

それかアウトバウンドでもリストされた ip に制限したい場合は output でも似たようなルールを追加すればそういう制限も設定できますが、そういうつもりでしたか?

よろしくお願いします

マルティネさん、
お世話になっております。

> インバウンドで他の接続があればお手数ですがその時の conntrack ファイルで確認できれば幸いです。
ケース1:アクセス元のIP(113.xxx.xxx.xxx)を許可リストに入れて、ping と http (curl -s --head "http://")を実行後に取得
# cat /proc/net/nf_conntrack | grep 113.xxx.xxx.xxx
ipv4 2 icmp 1 13 src=113.xxx.xxx.xxx dst=192.168.15.152 type=8 code=0 id=49097 src=192.168.15.152 dst=113.xxx.xxx.xxx type=0 code=0 id=49097 mark=0 zone=0 use=2
ipv4 2 tcp 6 31 TIME_WAIT src=113.xxx.xxx.xxx dst=192.168.15.152 sport=62820 dport=80 src=10.88.0.4 dst=113.xxx.xxx.xxx sport=80 dport=62820 [ASSURED] mark=0 zone=0 use=2
ケース2:アクセス元のIP(113.xxx.xxx.xxx)を許可リストから除外して、pingとhttpを実行後に取得
# cat /proc/net/nf_conntrack | grep 113.xxx.xxx.xxx
ipv4 2 tcp 6 113 TIME_WAIT src=113.xxx.xxx.xxx dst=192.168.15.152 sport=61463 dport=80 src=10.88.0.4 dst=113.xxx.xxx.xxx sport=80 dport=61463 [ASSURED] mark=0 zone=0 use=2

> それかアウトバウンドでもリストされた ip に制限したい場合は output でも似たようなルールを追加すればそういう制限も設定できますが、そういうつもりでしたか?
いいえ、アウトバンド通信は制限しないつもりです。

よろしくお願いいたします。

at_dominique.m…

2025年3月13日 13時05分

k-nishikiさん

マルティネです。

> > インバウンドで他の接続があればお手数ですがその時の conntrack ファイルで確認できれば幸いです。
> ケース1:アクセス元のIP(113.xxx.xxx.xxx)を許可リストに入れて、ping と http (curl -s --head "http://")を実行後に取得
> # cat /proc/net/nf_conntrack | grep 113.xxx.xxx.xxx
> ipv4 2 icmp 1 13 src=113.xxx.xxx.xxx dst=192.168.15.152 type=8 code=0 id=49097 src=192.168.15.152 dst=113.xxx.xxx.xxx type=0 code=0 id=49097 mark=0 zone=0 use=2
> ipv4 2 tcp 6 31 TIME_WAIT src=113.xxx.xxx.xxx dst=192.168.15.152 sport=62820 dport=80 src=10.88.0.4 dst=113.xxx.xxx.xxx sport=80 dport=62820 [ASSURED] mark=0 zone=0 use=2

こちらは正常ですね。

> ケース2:アクセス元のIP(113.xxx.xxx.xxx)を許可リストから除外して、pingとhttpを実行後に取得
> # cat /proc/net/nf_conntrack | grep 113.xxx.xxx.xxx
> ipv4 2 tcp 6 113 TIME_WAIT src=113.xxx.xxx.xxx dst=192.168.15.152 sport=61463 dport=80 src=10.88.0.4 dst=113.xxx.xxx.xxx sport=80 dport=61463 [ASSURED] mark=0 zone=0 use=2

icmp が許可されなくて、http が許可されてしまったんですね…
すみません、再現できたところ、一つ大事なことを忘れてました。
今回、ping/ssh と http の違いは、http はコンテナから返事していると思いますが、合ってますか。

コンテナへの通信は、INPUT ではなく、コンテナが NAT してくれてますので FORWARD のテーブルで許可を設定する必要があります。
なので、iptables -A FORWARD -j MYCHAIN でコンテナへの通信に同じ制限をするといいです。
(分かりにくいことで、コンテナからの送信は FORWARD から通らず OUTPUT になりますので、許可されたままになります)

FORWARDについてもう一つ注意です。
INPUT 同様に RELATED,ESTABLISHED を許可するルールが必要ですが、podman がすでにやってくれていて MYCHAIN の処理が NETAVARK_FORWARD の後になると問題ないですが、念のためその処理を INPUT から MYCHAIN へ持った方がいいかもしれません。

まとめると以下の変更でいいかと思います:

--- apply1.sh	2025-03-13 13:00:32.164442993 +0900
+++ apply2.sh	2025-03-13 13:01:22.820823212 +0900
@@ -15,11 +15,13 @@
 
 # Clear MYCHAIN if exist
 iptables -D INPUT -j MYCHAIN 2>/dev/null || true
+iptables -D FORWARD -j MYCHAIN 2>/dev/null || true
 iptables -F MYCHAIN 2>/dev/null || true
 iptables -X MYCHAIN 2>/dev/null || true
 
-# Change default policy for INPUT
+# Change default policy for INPUT/FORWARD
 iptables -P INPUT DROP
+iptables -P FORWARD DROP
 
 # Create new chain
 iptables -N MYCHAIN
@@ -45,13 +47,14 @@
 iptables -A MYCHAIN -s "192.168.200.0/24" -j ACCEPT
 
 # Accept from RELATED,ESTABLISHED
-iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+iptables -A MYCHAIN -m state --state RELATED,ESTABLISHED -j ACCEPT
 
 # DROP Inboud packet which is not matched with above rules
 iptables -A MYCHAIN -j DROP
 
-# Add MYCHAIN to INPUT chain
+# Add MYCHAIN to INPUT/FORWARD chains
 iptables -A INPUT -j MYCHAIN
+iptables -A FORWARD -j MYCHAIN
 
 # Save above rules to /etc/iptables/rules-save
 /etc/init.d/iptables save

よろしくお願いします

マルティネさん、
お世話になっております。

一つ気づいた点がありますのでお伝えします。
Armadillo上で実行しているHTTPサーバ(lighttpd)は、コンテナを生成して、コンテナ上で実行(add_ports 80:80 443:443)しています。
デフォルトで設定されている以下のルールが、追加したルール(MYCHAIN)より先に適用されてしまい、HTTP要求が全て許可されてしまうのではないでしょうか?
Chain NETAVARK_FORWARD (1 references)
target prot opt source destination
DROP all -- anywhere anywhere ctstate INVALID
ACCEPT all -- anywhere 10.88.0.0/16 ctstate RELATED,ESTABLISHED
ACCEPT all -- 10.88.0.0/16 anywhere

上記が許可していないIPからのインバウント要求を通す原因とした場合に、対応方法をご教示いただけますでしょうか。

マルティネさん、
お世話になっております。

025年3月13日 13時05分のコメントを読む前に上記コメントを書いていました。
原因と対応方法については、おおむね理解しましたので実機での確認を進めたいと思います。ありがとうございました。