- 1 firewall-cmdとは?
- 2 検証環境
- 3 firewall-cmdの起動、停止方法
- 4 ランタイムルール、パーマネントルールについて
- 5 ポートを開放する方法、ポートを閉じる方法
- 6 追加したポート番号はiptablesにどのように設定されているか?
- 7 ICMPタイプの表示、設定、削除方法
- 8 ダイレクトルールの使い方
- Z 参考情報
1 firewall-cmdとは?
firewall-cmdは、ファイアウォールの設定を行うコマンドです。firewall-cmdは、Ubuntuのufw,openSUSEのSUSEfirewall2と同じ位置づけのコマンドです。図に書くと、以下のようになります。ufwコマンドの使い方は、ufwコマンドの使い方(旧版) - hana_shinのLinux技術ブログを参照してください。
CentOS7 Ubuntu20.04 openSUSE(Leap42.3) +--------------+ +------------+ +---------------------+ -*- | firewall-cmd | | ufw | | SUSEfirewall2 | | +--------------+ +------------+ +---------------------+ | ユーザ空間 +-----------------------------------------------------------+ | | iptables command | | +-----------------------------------------------------------+ -*- +-----------------------------------------------------------+ -*- | | | | OS(netfilter) | カーネル空間 | | | +-----------------------------------------------------------+ -*-
2 検証環境
2.1 ネットワーク構成
サーバとクライアントの2台構成です。図中のens33はNICの名前です。
192.168.2.0/24 client(ens33) ------------------------------------------(ens33) server .105 .100
3 firewall-cmdの起動、停止方法
firewalldを起動すると、firewall-cmdが使えるようになります。
[root@server ~]# systemctl start firewalld.service [root@server ~]# firewall-cmd --version 0.6.3
firewalldを停止すると、firewall-cmdが使えなくなります。
[root@server ~]# systemctl stop firewalld.service [root@server ~]# firewall-cmd --version FirewallD is not running
4 ランタイムルール、パーマネントルールについて
種別 | ルールの保存先 |
---|---|
ランタイムルール | ランタイムルールはメモリ上に保存されます。firewalldをリスタートするとメモリからルールが消えます |
パーマネントルール | パーマネントルールはファイル(/etc/firewalld/zones配下)に保存されます。firewalldをリスタートすると、ルールがファイルから読み出され、メモリに展開されます |
4.1 ランタイムルールにルールを登録する方法
ランタイムルールはメモリ上に保存されるルールです。firewalldをリスタートすると、ランタイムルールが消えてしまいます。ここでは、firewalldをリスタートすることで、ランタイムルールが消えることを確認してみます。
ランタイムルールを確認します。ルールが登録れていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
TCPの11111番ポートへのアクセスを許可するルールをランタイムルールに登録します。
[root@server ~]# firewall-cmd --add-port=11111/tcp success
ランタイムルールを確認します。11111番ポートへのアクセスを許可するルールが登録されたことがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
firewalldを再起動します。
[root@server ~]# systemctl restart firewalld.service
ランタイムルールを確認します。ランタイムルールからルールが削除されたことがわかります(期待値)。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
4.2 ランタイムルールをパーマネントルールに保存する方法(--runtime-to-permanent)
ランタイムルールを確認します。ルールが登録されていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
TCPの11111番ポートへのアクセスを許可するルールをランタイムルールに登録します。
[root@server ~]# firewall-cmd --add-port=11111/tcp success
ランタイムルールを確認します。11111番ポートへのアクセスを許可するルールが登録されたことがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
ランタイムルールをパーマネントルールに保存します。
[root@server ~]# firewall-cmd --runtime-to-permanent success
パーマネントルールを確認します。ルールが設定ファイルに登録されたことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 <port protocol="tcp" port="11111"/>
firewalldを再起動します。
[root@server ~]# systemctl restart firewalld.service
ランタイムルールを確認します。11111番ポートが開放されていることがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
4.3 パーマネントルールを削除する方法
登録したルールをランタイムルールから削除します。
[root@server ~]# firewall-cmd --remove-port=11111/tcp success
ランタイムルールを確認します。登録したルールが削除されたことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
ランタイムルールをパーマネントルールに保存します。
[root@server ~]# firewall-cmd --runtime-to-permanent success
パーマネントルールの設定ファイルを確認します。ルールがファイルから削除されたことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 [root@server ~]#
4.4 ルールをパーマネントルールに直接保存する方法(--permanent)
ルールをランタイムルールに登録するのではなく、パーマネントルールの設定ファイルに直接保存する方法について説明します。
ランタイムルールを確認します。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
パーマネントルールを確認します。11111番ポートへのアクセスを許可するルールが登録されていないことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 [root@server ~]#
11111番ポートへのアクセスを許可するルールをパーマネントルールに保存します。
[root@server ~]# firewall-cmd --permanent --add-port=11111/tcp success
ランタイムルールを確認します。TCPの11111番ポートにアクセス許可するルールが登録されていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
パーマネントルールを確認します。ルールがパーマネントルールに登録されたことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 <port protocol="tcp" port="11111"/> [root@server ~]#
4.5 パーマネントルールをランタイムルールにロードする方法(--reload)
ランタイムルールを確認します。何も登録されていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
パーマネントルールを確認します。TCPの11111番ポートにアクセス許可するルールが登録されていないことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 [root@server ~]#
11111番ポートへのアクセスを許可するルールをパーマネントルールに保存します。
[root@server ~]# firewall-cmd --permanent --add-port=11111/tcp success
ランタイムルールを確認します。TCPの11111番ポートにアクセス許可するルールが登録されていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
パーマネントルールを確認します。ルールがパーマネントルールに登録されたことがわかります。
[root@server ~]# cat /etc/firewalld/zones/public.xml|grep 11111 <port protocol="tcp" port="11111"/>
パーマネントルールをランタイムルールにロードします。
[root@server ~]# firewall-cmd --reload success
ランタイムルールを確認します。TCPの11111番ポートにアクセス許可するルールが登録されていることがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
5 ポートを開放する方法、ポートを閉じる方法
5.1 数値を使う場合
ランタイムルールを確認します。以下の実行結果では、なにもルールが登録されていないことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
TCPの11111番ポートへのアクセスを許可するルールをランタイムルールに登録します
[root@server ~]# firewall-cmd --add-port=11111/tcp success
ランタイムルールを確認します。11111番ポートへのアクセス許可のルールが登録されたことがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
次に、11111番ポートへのアクセスを拒否するため、11111番ポートを閉じます。
[root@server ~]# firewall-cmd --remove-port=11111/tcp success
ランタイムルールを確認します。11111番ポートへのアクセス許可のルールが削除されたことがわかります。
[root@server ~]# firewall-cmd --list-ports [root@server ~]#
5.2 サービス名を使う場合
サービス名とはポート番号の別名です。サービス名とポート番号の対応関係は/etc/servicesに登録されていて、たとえば、httpなら80、sshなら22と登録されています。
アクセスが許可されているサービス名一覧を確認してみます。ssh(22番)とdhcpv6-client(546番)へのアクセスが許可されていることがわかる。
[root@server ~]# firewall-cmd --list-services dhcpv6-client ssh
httpへのアクセスを許可します。
[root@server ~]# firewall-cmd --add-service=http success
アクセスが許可されているサービス名一覧を確認してみます。dhcpv6-client、http、sshへのアクセスが許可されていることがわかります。
[root@server ~]# firewall-cmd --list-services dhcpv6-client http ssh
次に、登録したhttpへのアクセスを解除してみます。
[root@server ~]# firewall-cmd --remove-service=http success
アクセスが許可されているサービス名一覧を確認してみます。httpへのアクセス許可が解除されたことがわかります。
[root@server ~]# firewall-cmd --list-services dhcpv6-client ssh
6 追加したポート番号はiptablesにどのように設定されているか?
追加したポート番号やサービスが、iptablesにどのように設定されているのかを確認してみます。
まず、11111番ポートへのアクセスを許可します。
[root@server ~]# firewall-cmd --add-port=11111/tcp success
ランタイムルールを確認します。11111番ポートへのアクセスが許可されたことがわかる。
[root@server ~]# firewall-cmd --list-ports 11111/tcp [root@server ~]#
iptablesのINPUTチェインを確認します。
[root@server ~]# iptables -nvL INPUT Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67 158 9972 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 16 1692 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0 16 1692 INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0 16 1692 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID 16 1692 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
次に、INPUT_ZONESを確認します。
[root@server ~]# iptables -nvL INPUT_ZONES Chain INPUT_ZONES (1 references) pkts bytes target prot opt in out source destination 16 1692 IN_public all -- ens33 * 0.0.0.0/0 0.0.0.0/0 [goto] 0 0 IN_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
次に、IN_publicチェインを確認します。
[root@server ~]# iptables -nvL IN_public Chain IN_public (2 references) pkts bytes target prot opt in out source destination 16 1692 IN_public_log all -- * * 0.0.0.0/0 0.0.0.0/0 16 1692 IN_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0 16 1692 IN_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
最後にIN_public_allowチェインを確認すると、11111番ポートへのアクセスが許可されたルールが登録されていることがわかります。
[root@server ~]# iptables -nvL IN_public_allow Chain IN_public_allow (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:11111 ctstate NEW,UNTRACKED [root@server ~]#
INPUTチェインから、IN_public_allowチェインまでは、以下のような階層構造になっています。そして、IN_public_allowチェインで、11111番ポートへのアクセスを許可する設定が行われています。
INPUT + INPUT_ZONES + IN_public + IN_public_allow + ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:11111 ctstate NEW,UNTRACKED
ランタイムルールから11111番ポートへのアクセス許可のルールを削除します。
[root@server ~]# firewall-cmd --remove-port=11111/tcp success
IN_public_allowチェインを確認します。11111番ポートへのアクセス許可のルールが削除されたことがわかります。
[root@server ~]# iptables -nvL IN_public_allow Chain IN_public_allow (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED
7 ICMPタイプの表示、設定、削除方法
7.1 ICMPタイプを表示する方法(--get-icmptypes)
ICMPタイプの一覧を表示してみます。
[root@server ~]# firewall-cmd --get-icmptypes address-unreachable bad-header communication-prohibited destination-unreachable echo-reply echo-request fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable ip-header-bad neighbour-advertisement neighbour-solicitation network-prohibited network-redirect network-unknown network-unreachable no-route packet-too-big parameter-problem port-unreachable precedence-cutoff protocol-unreachable redirect required-option-missing router-advertisement router-solicitation source-quench source-route-failed time-exceeded timestamp-reply timestamp-request tos-host-redirect tos-host-unreachable tos-network-redirect tos-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit unknown-header-type unknown-option
7.2 ICMPタイプを設定する方法(--add-icmp-block)
ここでは、ICMP Echo要求をブロックする設定をしてみます。設定するICMPのタイプは、7.1で得たタイプを指定します。
[root@server ~]# firewall-cmd --add-icmp-block=echo-request success
ブロックしているICMPタイプを確認してみます。
[root@server ~]# firewall-cmd --list-icmp-blocks echo-request
ICMP Echo要求のブロック設定を行うと、IN_public_denyチェインに下記設定が行われます。
[root@server ~]# iptables -nvL IN_public_deny Chain IN_public_deny (1 references) pkts bytes target prot opt in out source destination 0 0 REJECT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 reject-with icmp-host-prohibited
IN_public_denyチェインは、以下のようにINPUTチェインから呼び出されています。
INPUT + INPUT_ZONES + IN_public + IN_public_deny + REJECT icmptype 8 reject-with icmp-host-prohibited
クライアントからサーバに対してpingを3回実行してみます。"Destination Host Prohibited"と表示され、サーバでICMP echo要求がブロックされていることがわかります。pingコマンドの詳細な使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
[root@client ~]# ping -c 3 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. From 192.168.2.100 icmp_seq=1 Destination Host Prohibited From 192.168.2.100 icmp_seq=2 Destination Host Prohibited From 192.168.2.100 icmp_seq=3 Destination Host Prohibited --- 192.168.2.100 ping statistics --- 3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2016ms [root@client ~]#
7.3 ICMPタイプを削除する方法(--remove-icmp-block)
ブロックしているICMPタイプを確認してみます。echo-requestが登録されていることがわかります。
[root@server ~]# firewall-cmd --list-icmp-blocks echo-request
echo-requestを削除します。
[root@server ~]# firewall-cmd --remove-icmp-block=echo-request success
ブロックしているICMPタイプを確認してみます。何も登録されtいないことがわかります。
[root@server ~]# firewall-cmd --list-icmp-blocks [root@server ~]#
8 ダイレクトルールの使い方
ダイレクトルールは、OSのNetfilterに直接アクセスするためのものです。ダイレクトルールを使うと、iptablesコマンドで設定できることは、ほぼ全て設定できるようになります。
8.1 ダイレクトルールの追加、削除する方法
TCPの宛先ポート番号が11111番へのパケットを廃棄(DROP)する設定をします。
[root@server ~]# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP success
ルールを確認します。作成したルールが登録されていることがわかります。
[root@server ~]# firewall-cmd --direct --get-all-rules ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP
登録したルールを削除します。
[root@server ~]# firewall-cmd --direct --remove-rule ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP success
ルールを確認します。ルールが削除されたことがわかります。
[root@server ~]# firewall-cmd --direct --get-all-rules [root@server ~]#
8.2 ポート番号の範囲を指定する方法(multiport)
指定したポート番号の範囲へのアクセス許可を設定する方法を示します。以下の例は、宛先TCPポート番号10000から10005までのパケットの受信許可をします。
[root@server ~]# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -i ens33 -p tcp -m multiport --dports 10000:10005 -j ACCEPT success
ルールを確認します
[root@server ~]# firewall-cmd --direct --get-all-rules ipv4 filter INPUT 1 -i ens33 -p tcp -m multiport --dports 10000:10005 -j ACCEPT
作成したルールを削除します。
[root@server ~]# firewall-cmd --direct --remove-rule ipv4 filter INPUT 1 -i ens33 -p tcp -m multiport --dports 10000:10005 -j ACCEPT success
ルールを確認します。ルールが削除されたことがわかります。
[root@server ~]# firewall-cmd --direct --get-all-rules [root@server ~]#
8.3 ユーザ定義チェインの追加、削除する方法
OUTPUT_direct_xxxxxという名前のユーザ定義チェインを作成します。
[root@server ~]# firewall-cmd --direct --add-chain ipv4 filter OUTPUT_direct_xxxxx success
ユーザ定義チェインを確認します。 OUTPUT_direct_xxxxxという名前のユーザ定義チェインが作成されたことがわかります。
[root@server ~]# firewall-cmd --direct --get-all-chains ipv4 filter OUTPUT_direct_xxxxx
OUTPUT_direct_xxxxxという名前のユーザ定義チェインを削除します。
[root@server ~]# firewall-cmd --direct --remove-chain ipv4 filter OUTPUT_direct_xxxxx success
ユーザ定義チェインを確認します。 OUTPUT_direct_xxxxxという名前のユーザ定義チェインが削除されたことがわかります。
[root@server ~]# firewall-cmd --direct --get-all-chains [root@server ~]#
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ