この記事を作った動機
私が使っている家庭用ルータの挙動が怪しく、時々特定 IP にアクセスできなくなったり、NAT 越えして VPN 接続する際に接続ができなかったりするときがあるなど、安定性に欠けることがあることが分かった。
そこで、使っていないミニ PC に Linux 環境をインストールし、そこで何かしら設定をすれば、ルータ化できるのではないかという話が、Gemini にいろいろ投げつけると出てきたので、実際にそれができるのか検証も兼ねて、自分で設定し試してみた。
そもそも私自身がネットワークについて授業でレポートを作るためなど、単位を取るために軽く触った程度で、実際に自分で使うために運用して体験してみたり、試す実戦経験に疎いところがある。その点も兼ねて今回実際に検証してみて、難しいと思うことに関しては自分なりにノートを取ってみることにしたというのが、この記事を書いた動機である。
今回の設定がうまくいかない場合、再起動後にルータとして機能しない に書いているように、nftables自体がFirewalldの動作に干渉しているかもしれないので確認する。
設定のまとめ
今回の話のネットワーク構成の前提
いきなり本番環境で動かすのはリスクが高すぎるので、既存の家庭用ルータが形成するLANをWANとして見立てて、そこにぶら下げるようにして今回ルータ化するPCを配置し、実際に動作するか検証する形にした。
設定の全体像
sudo firewall-cmd --list-all --zone=LAN; sudo firewall-cmd --list-all --zone=WAN
# LAN (active)
# target: ACCEPT
# ingress-priority: 0
# egress-priority: 0
# icmp-block-inversion: no
# interfaces: [LAN側のインターフェース名]
# sources:
# services: mdns ssh
# ports: 3389/tcp 3389/udp
# protocols:
# forward: yes
# masquerade: no
# forward-ports:
# source-ports:
# icmp-blocks:
# rich rules:
# WAN (active)
# target: DROP
# ingress-priority: 0
# egress-priority: 0
# icmp-block-inversion: no
# interfaces: [WAN側のインターフェース名]
# sources:
# services:
# ports:
# protocols:
# forward: no
# masquerade: yes
# forward-ports:
# source-ports:
# icmp-blocks:
# rich rules:
sudo sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 1
ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
# link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# inet 127.0.0.1/8 scope host lo
# valid_lft forever preferred_lft forever
# inet6 ::1/128 scope host noprefixroute
# valid_lft forever preferred_lft forever
#
# 2: [LAN側のインターフェース名]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
# link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
# inet 192.168.0.3/24 scope global [LAN側のインターフェース名]
# valid_lft forever preferred_lft forever
# inet6 fe80::725a:fff:fe3f:8c93/64 scope link proto kernel_ll
# valid_lft forever preferred_lft forever
# ...
# 4: [WAN側のインターフェース名]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default # qlen 1000
# link/ether yy:yy:yy:yy:yy:yy brd ff:ff:ff:ff:ff:ff
# inet 192.168.1.19/24 brd 192.168.1.255 scope global [WAN側のインターフェース名]
# valid_lft forever preferred_lft forever
# inet6 fe80::3695:dbff:fe2b:1a6d/64 scope link proto kernel_ll
# valid_lft forever preferred_lft forever
インストールするパッケージ
yay -S firewalld net-tools dhclient
具体的なコマンド操作
# 起動時にfirewalldが起動するようにする
sudo systemctl enable --now firewalld
# すでに有効化していたり、一時的に立ち上げた状態にしたい場合
# sudo systemctl start firewalld
# NetworkManagerは手動でfirewalldに設定した項目を上書きする可能性があるので使わない
# sudo systemctl disable NetworkManager
# public ゾーンに紐づけられているインターフェースを確認し引きはがす
sudo firewall-cmd --list-all
sudo firewall-cmd --remove-interface=[publicに紐づけられているインターフェース名] --permanent
# 新しいゾーン LAN と WAN を作成し、
# LAN側にしてスイッチに接続するインターフェースと、WAN側にして上流の外部ネットワークに接続するインターフェースを紐づける
sudo firewall-cmd --new-zone=LAN --permanent
sudo firewall-cmd --new-zone=WAN --permanent
sudo firewall-cmd --zone=LAN --add-interface=[LAN側のインターフェース名] --permanent
sudo firewall-cmd --zone=WAN --add-interface=[WAN側のインターフェース名] --permanent
# 各ゾーンのパケットの扱いを設定
sudo firewall-cmd --zone=LAN --set-target=ACCEPT --permanent
sudo firewall-cmd --zone=WAN --set-target=DROP --permanent
# LANゾーンにおいて転送、WANゾーンにおいてマスカレード設定の有効化
firewall-cmd --zone=LAN --add-forward --permanent
firewall-cmd --zone=WAN --add-masquerade --permanent
# 設定を反映
sudo systemctl restart firewalld
Systemd で起動時に実行する内容 (root,initRouter.sh)
※ 保存してスクリプトを作成し終わったら、chmod +x [filename]で実行権限を付与することを忘れないこと。
#!/bin/bash
sleep 20
# kernel parameter を設定し、異なるインターフェース間をパケットが行き来できるようにする
sudo sysctl -w net.ipv4.ip_forward=1
# LAN (192.168.0.0/24 ネットワークにおいてルータとしてゲートウェイや管理のためにアクセスできるようにするためにIPを設定)
sudo ip addr add 192.168.0.3/24 dev [LAN側のインターフェース名]
# WAN (IPアドレス等を自動取得)
sudo dhclient [WAN側のインターフェース名]
# DNS setting (dhclient が勝手に書き換えてしまうので dhclient 実行後に手動で設定)
# 今回は例として "8.8.8.8" の Google の DNS サーバを指しているが、
# 任意で "1.1.1.1" や個別に自前で運用している DNS サーバに指定可能である
sleep 5
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
# なんかスイッチとかに繋がってリンクを確立しているのに、"DOWN"していることがあったので一定時間待ってから明示的に"UP"にする
sleep 20
sudo ip link set up dev [LAN側のインターフェース名]
sleep 5
sudo ip link set up dev [WAN側のインターフェース名]
# もし DHCP サーバとして kea をインストールしている場合
# sleep 5
# sudo systemctl restart kea-dhcp4
/etc/systemd/system/routerINIT.serviceとして配置する systemd スクリプトの例
[Unit]
Description=init router function.
After=display-manager.service # 起動前からケーブルなどのセットアップは済んでいることを想定している。
[Service]
Type=simple
User=root
ExecStart=/path/to/initRouter.sh & # スクリプトを配置した場所に書き換える必要がある。
Restart=on-abort
[Install]
WantedBy=multi-user.target
sudo systemctl enable routerINIT
課題
- 一時的な停電があったとき、電力が復旧したら自動的に起動するように BIOS に設定する必要がある。
NetworkManagerやdhcpcdを使っていないので、ネットワークの構成が変わったことを検出して自動的に IP を取得するスクリプトが必要である。- DHCP サーバを立てないと LAN側に接続されたクライアントに IP 自動的に割り振られたりしない。
設定に対する考えや経緯など
nftablesを使う案からFirewalldをnftablesのフロントエンドとして使う発想に至るまで
当初はnftablesを使った方法が考えられていたが、設定が煩雑で難しく、現時点では以下のイメージの理解しか持ててないところがある。
- テーブル
ネットワーク処理設定の入れ物? - チェーン
いつ処理を実行するか鎖を特定のタイミングに結び付ける - ルール
具体的な処理内容を決める
また、私は普段 Linux 環境には Firewalldもセットでインストールしておりすでにnftablesに大量の設定があり、Firewalldと折り合いをつけながら現実的に変に設定が上書きされたりするのを避けたりしながら、netablesを直接使い、整合性をもって運用することが難しいと考えた。
sudo nft list ruleset
# table inet firewalld { # progname firewalld
# ... ここに大量の設定が出てくる
# }
そこで、Firewalldだけで、今回はマスカレード(仮面)を設定することで、WAN 側に見立てた LAN 側では一つのIPアドレスから、LAN 側に見立てた側の内側からの複数の端末によるアクセスを実現することを目指すことになった。私は完全には理解しておらず、設定内容やツールの使い方について確証を持っているわけではないが、少なくとも家庭用ルータの NAT 機能に最低限あるような以下の点に関して検証を行うことで、正しく機能していることを確かめようとした。
- LAN に見立てた側から WAN に見立てた側の内部ネットワークに属するサーバや、Google などのグローバル空間の Web サービスなどにアクセスできる。ネットワークの内側から外側に通信を開始し、外側から帰ってきた応答をネットワークの内側までルータ化したPCを通して、クライアントが受け取れるのか検証する。
- WAN 側に見立てた LAN 内のネットワークにおいて、ルータや LAN に見立てた側のルータ化したPC越しのネットワークに対して、外側から接続ができないことを試す。具体的には、LAN に見立てた側に対して、WAN に見立てた側から、ルータ化したPC自身やその先にあるクライアントに対し、SSH 接続を試みたり、RDP 接続を試みたり、ping を試みて、実際に接続できないことや疎通の確認が取れないことを確認する。ネットワークの外側から内側に接続を開始できないことを確認する。
今回は、確認してみたことで、ping が通じるかの例は示した。
Firewalldを設定するにあたって考慮したこととか
今回Firewalldの設定で重要であったポイントには以下の点がある。
マスカレード と SNAT、DNAT の違い (WAN 側に対するゾーンの設定)
- マスカレード
WAN 側などに対して、固定された IP (仮面)を使わず、動的に取得した IP を LAN 側から来たパケットの仮面とて利用する方式。(What is IP Masquerade?)一つのグローバル IP や WAN 側に見立てられる LAN 内における一つのプライベート IP において、複数 LAN 内に繋がる機器を外側のネットワークにアクセスできるようにする。外側からアクセスを開始することができなため、セキュリティのために通常のインターネット利用などにおいて、安全のために利用されることがある。LAN 内 HTTP サーバーやファイル共有サーバを立てても、NAT越えしたりして直接内部のLANにアクセスしないと、立てたサーバにアクセスできない。
以下は、What is IP Masquerade?の引用である。
2.1. What is IP Masquerade? IP Masquerade is a networking function in Linux similar to the one-to-many (1:Many) NAT (Network Address Translation) servers found in many commercial firewalls and network routers. For example, if a Linux host is connected to the Internet via PPP, Ethernet, etc., the IP Masquerade feature allows other “internal” computers connected to this Linux box (via PPP, Ethernet, etc.) to also reach the Internet as well. Linux IP Masquerading allows for this functionality even though these internal machines don’t have an officially assigned IP address.
MASQ allows a set of machines to invisibly access the Internet via the MASQ gateway. To other machines on the Internet, the outgoing traffic will appear to be from the IP MASQ Linux server itself. In addition to the added functionality, IP Masquerade provides the foundation to create a HEAVILY secured networking environment. With a well built firewall, breaking the security of a well configured masquerading system and internal LAN should be considerably difficult to accomplish.
If you would like to know more on how MASQ (1:Many) differs from 1:1 (true) NAT and Proxy solutions, please see the Section 7.6 FAQ entry.
- SNAT (Source Network Address Translation)
ネットワークパケットのヘッダなどに含まれる、送信側と宛先側のアドレスの内、送信側(ソース)のIPアドレスを換する方式である。WAN 側などに対して、固定された IP (仮面)を使い、事前に設定し取得した IP を LAN 側か来たパケットの仮面として利用する。一つのグローバル IP や WAN 側に見立てられる LAN 内における一つのプライベーIPにおいて、複数の LAN 内に繋がる機器を外側のネットワークにアクセスできるようにする。外側からアクセスを開することができないため、セキュリティのために通常のインターネット利用などにおいて、安全のために利用されことがある。LAN内にHTTP サーバーやファイル共有サーバを立てても、NAT 越えしたりして直接内部の LAN にアクセしないと、立てたサーバにアクセスできない。 - DNAT (Destination Network Address Translation)
ネットワークパケットのヘッダなどに含まれる、送信側と宛先側のアドレスの内、宛先側(目的地、ディスティネーョン)の IP アドレスを変換する方式である。私はこれをまともに使った事がないので細かいことが分からないが、説を見ていろいろなサイトの図解とか見ている限りでは、プライベートIPアドレスを持っている内部 LAN あるサーバにして、外部からグローバル IP などを叩かれて WAN 側に相当するネットワークからパケットが送られてきた場合、内部サーバに宛先アドレスを書き換え、サーバからクライアントに戻る際にはサーバが自身のプライベートIPを送信元ドレスとして応答しているので、それをグローバル IP に書き換えるというような動作になるように見受けられた。単には、SNAT やマスカレードが内部ネットワークから外部ネットワークへのアクセスを想定していたのに対し、DNAT は外部ネットワークから内部ネットワークへのアクセスを想定している形態になっているように見える。DNAT は SNAT やマスカレードとは IP アドレスや、ものによってはポート番号を書き換える点では同じであるが、どんな目的のたにどのように宛先や送信元の情報を書き換えるかは異なるといった印象を受ける。
| マスカレード | SNAT | DNAT | |
|---|---|---|---|
| IPアドレスを変換する | ✅ YES | ✅ YES | ✅ YES |
| 固定されたIPに置き換える | ❌ NO | ✅ YES | ✅ YES |
| 動的に取得されたIPに置き換える | ✅ YES | ❌ NO | ❌ NO |
| 内部から外部への通信の開始 | ✅ YES | ✅ YES | ❌ NO |
| 外部から内部への通信の開始 | ❌ NO | ❌ NO | ✅ YES |
| 送信元IPを書き換える | ✅ YES | ✅ YES | ❌ NO |
| 宛先IPを書き換える | ❌ NO | ❌ NO | ✅ YES |
| 外部ネットワークの脅威から守る | ✅ YES | ✅ YES | ❌ NO |
| 外部ネットワークからNAT先のサーバに接続させる | ❌ NO | ❌ NO | ✅ YES |
転送設定やマスカレード設定 (LANやWAN側のゾーンそれぞれの設定)
Firewalldにおいて、ルータ機能を実現するために以下のような設定にした。
- LAN側のゾーンにおいて、
forward(転送)の項目を有効化する。 - WAN側のゾーンにおいて、
masquerade(仮面)の項目を有効化する。
ターゲット設定
Firewalldには、特定ゾーンに入ったパケットをどう処理するか設定項目があり、パケットを破棄するか制御する項目がある。今回は、WAN側からのアクセスの開始を拒絶するために、WAN側のゾーンにはDROPを、LAN側からの内部からのアクセスの開始を許可するためにLAN側のゾーンにはACCEPTを設定した。
当初はWAN側はゾーン作成時のデフォルトである、defaultを利用していたが、WAN側に見立てたネットワーク側からping したりするとそれが通ってしまう。これでは、IP Scanとかでルータの実態があることが目立ってしまうという状態である。
また、以下に示すfirewall-cmdの man ページの説明のように基本的にdefaultターゲットはREJECTターゲットと同じ挙動で要求を破棄するのではなく拒絶し相手に拒絶されたことを伝えて存在を目立たせてしまうことが分かった。defaultターゲットでも、SNATやマスカレード機能として外部からの通信を開始させない目的は達成されるが、まだセキュリティとしては脆弱だと考え、最終的にはサイレントに拒絶されたことも伝えず存在しないかのようにWAN側にはふるまうDROPターゲットを適切だとして、WAN側のゾーンには設定した。
--permanent [--zone=zone] [--policy=policy] --set-target=target
Set the target.
For zones target is one of: default, ACCEPT, DROP, REJECT
For policies target is one of: CONTINUE, ACCEPT, DROP, REJECT
default is similar to REJECT, but it implicitly allows ICMP packets.
ACCEPT allows traffic to be forwarded from the zone, either to the same zone or other zones.
カーネルパラメーターの設定
Linux環境においては、パケットがルータ化する PC に接続された 2 つ以上の NIC 間を行き来することを許可することがルータ化には必要である。
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 1
確認してみたこと
外部から内部ネットワークにアクセスできないこと
WAN 側に見立てた側から内部ネットワークにアクセスできない、pingが通らないことを確認する。
ip a
# ...
# 2: eno1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
# link/ether tt:tt:tt:tt:tt:tt brd ff:ff:ff:ff:ff:ff
# inet 192.168.1.CC/24 brd 192.168.1.255 scope global noprefixroute eno1
# valid_lft forever preferred_lft forever
# inet6 xxxx::b4c5:7141:xxxx:9580/64 scope link
# valid_lft forever preferred_lft forever
# ...
# でたらめな IP を入力したとき
ping 192.168.1.32
# PING 192.168.1.32 (192.168.1.32) 56(84) バイトのデータ
# 送信元 192.168.1.CC icmp_seq=1 目的のホストへ届きません。
# 送信元 192.168.1.CC icmp_seq=2 目的のホストへ届きません。
# 送信元 192.168.1.CC icmp_seq=3 目的のホストへ届きません。
# 送信元 192.168.1.CC icmp_seq=4 目的のホストへ届きません。
# 送信元 192.168.1.CC icmp_seq=5 目的のホストへ届きません。
# 送信元 192.168.1.CC icmp_seq=6 目的のホストへ届きません。
# ^C
# --- 192.168.1.32 ping 統計 ---
# 送信パケット数 7, 受信パケット数 0, +6 エラー, 100% packet loss, time 6127ms
# pipe 4
# ルータの WAN 側の IP を入力したとき
ping 192.168.1.19
# PING 192.168.1.19 (192.168.1.19) 56(84) バイトのデータ
# ^C
# --- 192.168.1.19 ping 統計 ---
# 送信パケット数 27, 受信パケット数 0, 100% packet loss, time 26615ms
# ルータの NAT の先にある LAN 側にあるクライアントに対してアクセスを試みてみるとき
ping 192.168.0.34
# PING 192.168.0.34 (192.168.0.34) 56(84) バイトのデータ
# ^C
# --- 192.168.0.34 ping 統計 ---
# 送信パケット数 28, 受信パケット数 0, 100% packet loss, time 27665ms
内部から外部ネットワークへアクセスできること
LAN 側に見立てた側から外部ネットワークやグローバルネットワークにアクセスできることを確認し、ブラウジング出来たり、WAN側に見立てたLANネットワーク内部での疎通やサービスが利用可能かを確認する。
ifconfig
# イーサネット アダプター Embedded LOM 1 Port 1:
# 接続固有の DNS サフィックス . . . . .:
# リンクローカル IPv6 アドレス. . . . .: fe80::2971:1249:57ad:9714%15
# IPv4 アドレス . . . . . . . . . . . .: 192.168.0.34
# サブネット マスク . . . . . . . . . .: 255.255.255.0
# デフォルト ゲートウェイ . . . . . . .: 192.168.0.3
# グローバルネットワークへの接続テスト
ping google.com
# google.com [172.217.211.101]に ping を送信しています 32 バイトのデータ:
# 172.217.211.101 からの応答: バイト数 =32 時間 =13ms TTL=114
# 172.217.211.101 からの応答: バイト数 =32 時間 =12ms TTL=114
# 172.217.211.101 からの応答: バイト数 =32 時間 =12ms TTL=114
# 172.217.211.101 からの応答: バイト数 =32 時間 =12ms TTL=114
#
# 172.217.211.101 の ping 統計:
# パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
# ラウンド トリップの概算時間 (ミリ秒):
# 最小 = 12ms、最大 = 13ms、平均 = 12ms
# ルータ化したPC自身への接続テスト
ping 192.168.0.3
# 192.168.0.3 に ping を送信しています 32 バイトのデータ:
# 192.168.0.3 からの応答: バイト数 =32 時間 <1ms TTL=64
# 192.168.0.3 からの応答: バイト数 =32 時間 <1ms TTL=64
# 192.168.0.3 からの応答: バイト数 =32 時間 <1ms TTL=64
# 192.168.0.3 からの応答: バイト数 =32 時間 <1ms TTL=64
#
# 192.168.0.3 の ping 統計:
# パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
# ラウンド トリップの概算時間 (ミリ秒):
# 最小 = 0ms、最大 = 0ms、平均 = 0ms
# WAN 側に見立てた LAN にあるサーバに対しての接続テスト
ping 192.168.1.XX
# 192.168.1.XX に ping を送信しています 32 バイトのデータ:
# 192.168.1.XX からの応答: バイト数 =32 時間 <1ms TTL=63
# 192.168.1.XX からの応答: バイト数 =32 時間 <1ms TTL=63
# 192.168.1.XX からの応答: バイト数 =32 時間 <1ms TTL=63
# 192.168.1.XX からの応答: バイト数 =32 時間 <1ms TTL=63
#
# 192.168.1.XX の ping 統計:
# パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
# ラウンド トリップの概算時間 (ミリ秒):
# 最小 = 0ms、最大 = 0ms、平均 = 0ms
# WAN 側に見立てた LAN を形成するルータへの接続テスト
ping 192.168.1.1
# 192.168.1.1 に ping を送信しています 32 バイトのデータ:
# 192.168.1.1 からの応答: バイト数 =32 時間 =1ms TTL=63
# 192.168.1.1 からの応答: バイト数 =32 時間 <1ms TTL=63
# 192.168.1.1 からの応答: バイト数 =32 時間 <1ms TTL=63
# 192.168.1.1 からの応答: バイト数 =32 時間 =1ms TTL=63
#
# 192.168.1.1 の ping 統計:
# パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
# ラウンド トリップの概算時間 (ミリ秒):
# 最小 = 0ms、最大 = 1ms、平均 = 0ms
挙動不審なことや設定漏れをテスト
- 実際に数日負荷テストをして実用してみる。あえて大きなファイル転送や、こまごまとしたランダムリード的な負荷のかかる使い方をしてみる。
躓いたこと
NetworkManager が Firewalld の設定を邪魔する
NetworkManager は Firewalld と密接に結びついているらしく、問題が起きることが分かった。私が検証した場合には新しく、WAN と LAN というゾーンを作って、そこにインタフェースを紐づけるために、デフォルトで設定されてインタフェースが紐づけられている Public ゾーンからインターフェースを剥がして、WANやLANのゾーンにインターフェースをくっつける作業をしていた。すると、Firewalldを再起動して設定を反映しようとしたときに NetworkManager に勝手に特定のインターフェースが public ゾーンに紐づけられて設定を戻されてしまうことがあった。
NetworkMangerが勝手に設定したり操作しないように設定する方法もあるが、今回は単純さと簡単さのために、NetworkManagerが勝手に設定を書き換えて不本意な動作をしないよう、それをアンインストールし、手動でip addr addなどをするスクリプトを書き、自分で必要な設定をルータ化するPCの起動時にSystemdで実行させるようにすることを選んだ。
感想としては、NetworkManagerはLinux環境をクライアントOSとして使うためには、有効だが、組み込み的な特定の動作を期待して実装していくような用途には向かない気もした。
Firewalldの--permanentの意味
どこかのサイトとかに書いていたわけでもないが、実際に動かしてみてFirewalldを操作していると、特定の設定項目に関しては、設定の読み出しに関しても--permanentという引数をつける必要があることが分かった。
私の検証前の--permanentのイメージは、設定を書き換えるときに永続化するというイメージであったが違うようである。例えば特定ゾーンに対して--permanent引数を渡さずにターゲット設定を読みだそうとすると、以下のようなエラーが出る。
sudo firewall-cmd --zone=WAN --get-target
# usage: 'firewall-cmd --help' for usage information or see firewall-cmd(1) man page
# Option can be used only with --permanent.
sudo firewall-cmd --zone=WAN --get-target --permanent
# DROP
実際には、Firewalldが動的に動いているメモリ上の設定に対して読み書きする場合には、--permanent引数をつけず、静的に保存されている設定を読み書きする場合には--permanent引数をつけて操作を行うといった認識の方が、正確なように見受けられた。
ちなみにfirewall-cmdの man ページには以下のようなことが書いてあった。読んでいる感じだと直接--permanent引数が、静的な設定を読み書きするか、動的な設定を読み書きするかというスイッチになっていることは直接書かれていないが、--permanent引数が必須かどうかについては、書いてあるようである。
Permanent Options
--permanent
The permanent option --permanent can be used to set options permanently. These changes are not effective immediately, only after service
restart/reload or system reboot. Without the --permanent option, a change will only be part of the runtime configuration.
If you want to make a change in runtime and permanent configuration, use the same call with and without the --permanent option.
The --permanent option can be optionally added to all options further down where it is supported.
...
[--permanent] [--zone=zone] [--policy=policy] --list-all
List everything added or enabled.
--permanent [--zone=zone] [--policy=policy] --get-target
...
再起動後にルータとして機能しない
ルータ化した PC を完全に再起動すると、正しく機能しない場合があることが分かった。具体的にはnftablesの systemd サービスが有効になっていると、Firewalldだけでなく、/etc/nftables.conf配下にある設定がnftablesの動的な設定に対してfilterというテーブル名で起動時に追加され、ルータ機能を阻害することが分かった。対処としては、nftablesサービスがそもそも起動しないように無効化したりマスクすることがあった。
sudo systemctl disable nftables
sudo systemctl mask nftables
以下は今回問題となった、nftablesデフォルトで付属する/etc/nftables.confの例である。以下が有効になっている場合、Firewalldと合わせてtcpdump -i [LAN側のインターフェース] icmpとしてパケットの流れを監視すると設定に書かれている通りの動作をし、admin-prohibitedと表示され、パケットが拒否される。
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:
# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.
destroy table inet filter
table inet filter {
chain input {
type filter hook input priority filter
policy drop
ct state invalid drop comment "early drop of invalid connections"
ct state {established, related} accept comment "allow tracked connections"
iif lo accept comment "allow from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
tcp dport ssh accept comment "allow sshd"
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
counter
}
chain forward {
type filter hook forward priority filter
policy drop
}
}
また、Red Had 社の Chapter 40. Using and configuring firewalld | Configuring and managing networking | Red Hat Enterprise Linux | 8 | Red Hat Documentation の解説ページにおいても設定の競合を避けるために、nftablesとFirewalldの systemd サービスを同時に起動する設定にしないように書かれていることを確認した。
Important
To prevent the different firewall-related services (firewalld, nftables, or iptables) from influencing each other, run only one of them on a RHEL host, and disable the other services.
関連のある記事
使った画像とか
- Windows 7(Vista) デフォルトのアイコン
- ルーター
- PCのアイコン
- インターネット的なアイコン
- ディスプレイのアイコン
- File:Tux.svg - Wikimedia Commons (lewing@isc.tamu.edu Larry Ewing and The GIMP, CC0, via Wikimedia Commons)
https://commons.wikimedia.org/wiki/File:Tux.svg (2026年2月26日)
参考にしたサイトとか
-
nftables - ArchWiki
https://wiki.archlinux.jp/index.php/Nftables (2026年2月25日) -
What is nftables? - nftables wiki
https://wiki.nftables.org/wiki-nftables/index.php/What_is_nftables%3F (2026年2月25日) -
nft(8) — Arch manual pages
https://man.archlinux.org/man/nft.8 (2026年2月25日) -
centos - Can’t remove interface from zone with NetworkManager enabled. - Firewalld / Centos8 - Unix & Linux Stack Exchange
https://unix.stackexchange.com/questions/559980/cant-remove-interface-from-zone-with-networkmanager-enabled-firewalld-cent (2026年2月25日) -
Network Namespace と nftables で Source NAT を試す - CUBE SUGAR CONTAINER
https://blog.amedama.jp/entry/netns-nftables-snat (2026年2月25日) -
42.3. nftables を使用した NAT の設定 | ネットワークの設定および管理 | Red Hat Enterprise Linux | 8 | Red Hat Documentation
https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-nat-using-nftables_getting-started-with-nftables#configuring-masquerading-using-nftables_configuring-nat-using-nftables (2026年2月25日) -
Configuring destination NAT nftables entire subnet - Server Fault
https://serverfault.com/questions/1156428/configuring-destination-nat-nftables-entire-subnet (2026年2月25日) -
Network Namespace と nftables で Destination NAT を試す - CUBE SUGAR CONTAINER
https://blog.amedama.jp/entry/netns-nftables-dnat (2026年2月25日) -
linuxのnftables(nft)でルータ機能を作る - それマグで!
https://takuya-1st.hatenablog.jp/entry/2023/06/23/021732 (2026年2月25日) -
What does “masquerade” mean exactly? : r/HomeNetworking
https://www.reddit.com/r/HomeNetworking/comments/1cbvyoj/what_does_masquerade_mean_exactly/ (2026年2月25日) -
How do I request a new IP address from my DHCP server using Ubuntu Server? - Server Fault
https://serverfault.com/questions/24515/how-do-i-request-a-new-ip-address-from-my-dhcp-server-using-ubuntu-server (2026年2月25日) -
Google Gemini
https://gemini.google.com/app (2026年2月26日) -
NAPT(IPマスカレード / PAT)とは
https://www.infraexpert.com/study/ip11.5.html (2026年2月26日) -
IPマスカレードとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word11980.html (2026年2月26日) -
BIG-IP - SNAT Pool / AutoMapの設定
https://www.infraexpert.com/infra/bigip31.html (2026年2月26日) -
ip nat inside source list - ダイナミックNAT
https://www.infraexpert.com/study/natz1.html (2026年2月26日) -
デスティネーションNATとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word110634.html (2026年2月26日) -
「DNAT(ダイナミックNAT)」と「DNAT(デスティネーションNAT)」の違い|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/diff981network.html (2026年2月26日) -
Understanding Destination NAT - NetEngine AR5700, AR6700, and AR8000 V600R023C00 Configuration Guide - NAT and IPv6 Transition Technologies Configuration - Huawei
https://support.huawei.com/enterprise/en/doc/EDOC1100336498/db0d306d/understanding-destination-nat (2026年2月26日) -
「ソースNAT(SNAT)」と「デスティネーションNAT(DNAT)」の違い|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/diff970network.html (2026年2月26日) -
Source Network Address Translationとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word110635.html (2026年2月26日) -
firewall-cmdの man ページ (2026年2月26日) -
What is IP Masquerade?
https://tldp.org/HOWTO/IP-Masquerade-HOWTO/ipmasq-background2.1.html (2026年2月26日) -
Arch Linux - firewalld 2.4.0-6 (any)
https://archlinux.org/packages/extra/any/firewalld/ (2026年2月26日) -
Arch Linux - dhclient 4.4.3.P1-4 (x86_64)
https://archlinux.org/packages/extra/x86_64/dhclient/ (2026年2月26日) -
Chapter 40. Using and configuring firewalld | Configuring and managing networking | Red Hat Enterprise Linux | 8 | Red Hat Documentation
https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/using-and-configuring-firewalld_configuring-and-managing-networking (2026年2月27日)