firewalldを設定する

[CentOS][7.x]firewalldを設定する

環境

今回の環境は、以下をインストールした状態となります。

firewalldとは

iptablesなどと同じ、ファイアウォール機能を実現する実装のこと。
NIC単位でFirewallを設置するようなイメージで、アクセス制御を行うことができます。

CentOS 7.x からは、これまでの iptables ではなく、標準で firewalld が有効となっています。

firewalldの設定は、「firewalld-cmd」というコマンドを使います。

起動・停止方法

firewalldの起動・停止方法は、他のサービスと同じように「systemctl」コマンドで操作できます。

自動起動設定

firewalld が自動起動するかどうかを確認します。

# systemctl list-unit-files | grep firewalld
firewalld.service enabled

「firewalld.service」が「enabled」となっていれば、firewalldは自動起動する状態になっています。
「disabled」になっている場合は自動起動しませんので、以下のように enabled に変更しておきましょう。

# systemctl list-unit-files | grep firewalld
firewalld.service disabled
# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/basic.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.

# systemctl list-unit-files | grep firewalld
firewalld.service enabled

起動方法

「systemctl start firewalld.service」コマンドを実行します。

停止方法

「systemctl stop firewalld.service」コマンドを実行します。

状態確認

「systemctl status firewalld.service」コマンドを実行します。

起動中の状態

4行目が「active (running)」となっています。

# systemctl status firewalld.service
* firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2017-01-09 00:26:18 JST; 3s ago
Docs: man:firewalld(1)
Main PID: 8869 (firewalld)
CGroup: /system.slice/firewalld.service
`-8869 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jan 09 00:26:18 hostname systemd[1]: Starting firewalld - dynamic firewall daemon...
Jan 09 00:26:18 hostname systemd[1]: Started firewalld - dynamic firewall daemon.

停止中の状態

4行目が「inactive (dead)」となっています。

# systemctl status firewalld
* firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Mon 2017-01-09 00:45:16 JST; 3s ago
Docs: man:firewalld(1)
Process: 8869 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
Main PID: 8869 (code=exited, status=0/SUCCESS)

Jan 09 00:26:18 hsotname systemd[1]: Starting firewalld - dynamic firewall daemon...
Jan 09 00:26:18 hostname systemd[1]: Started firewalld - dynamic firewall daemon.
Jan 09 00:45:15 tk2-216-17559.vs.sakura.ne.jp systemd[1]: Stopping firewalld - dynamic firewall daemon...
Jan 09 00:45:16 hostname systemd[1]: Stopped firewalld - dynamic firewall daemon.

ゾーンの定義

firewalldでは、ゾーンという考え方を使います。

事前にゾーンを定義し、そのゾーンに対してアクセス許可を設定していきます。
定義したゾーンは、OSが認識している NIC(Network Interface Card) に紐付けて使います。

初期状態でいくつかのゾーンが定義されていますので、見ておきましょう。

初期設定ゾーン

初期状態で定義されているゾーンは、以下のようなものがあります。
(Redhatのドキュメントから引用)

ゾーン名用途
drop着信ネットワークパケットはすべて遮断され、返信されません。
送信ネットワーク接続のみが可能です。
blockIPv4 では icmp-host-prohibited メッセージで、IPv6 では icmp6-adm-prohibited メッセージですべての着信ネットワーク接続が拒否されます。
システム内で開始されたネットワーク接続のみが可能です。
public公開エリア用です。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターを信頼しません。
選択された着信接続のみが許可されます。
externalマスカレードを特別にルーター用に有効にした外部ネットワーク上での使用向けです。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターを信頼しません。
選択された着信接続のみが許可されます。
dmz公開アクセスが可能ではあるものの、内部ネットワークへのアクセスには制限がある非武装地帯にあるコンピューター用。
選択された着信接続のみが許可されます。
work作業エリア用です。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターをほぼ信頼します。
選択された着信接続のみが許可されます。
homeホームエリア用です。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターをほぼ信頼します。
選択された着信接続のみが許可されます。
internal内部ネットワーク用です。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターをほぼ信頼します。
選択された着信接続のみが許可されます。
trustedすべてのネットワーク接続が許可されます。

インストール時は、各NICには publicゾーン が紐付けられています。

初期ゾーンの定義ファイル

初期設定されているゾーンは、「/usr/lib/firewalld/zones」ディレクトリにあるファイルで定義されています。

# ls -l /usr/lib/firewalld/zones
total 36
-rw-r--r-- 1 root root 299 Nov 12 04:02 block.xml
-rw-r--r-- 1 root root 293 Nov 12 04:02 dmz.xml
-rw-r--r-- 1 root root 291 Nov 12 04:02 drop.xml
-rw-r--r-- 1 root root 304 Nov 12 04:02 external.xml
-rw-r--r-- 1 root root 369 Nov 12 04:02 home.xml
-rw-r--r-- 1 root root 384 Nov 12 04:02 internal.xml
-rw-r--r-- 1 root root 315 Nov 12 04:02 public.xml
-rw-r--r-- 1 root root 162 Nov 12 04:02 trusted.xml
-rw-r--r-- 1 root root 311 Nov 12 04:02 work.xml

中身は、以下のような感じになっています。

# cat /usr/lib/firewalld/zones/public.xml
<xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<zone>
 <short>Public</short>
 <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
 <service name="ssh"/>
 <service name="dhcpv6-client"/>
</zone>

これらのファイルは、マスターファイル的なものになりますので、ゾーンの設定を変更する場合でもこれらのファイルは編集しないようにしましょう。

設定を変更したい場合は、「/etc/firewalld/zones」ディレクトリにファイルをコピーして、コピーしたファイルの内容を修正してください。

確認コマンド

定義されているゾーンを確認するには、「firewall-cmd --list-all」コマンドを使います。

実行した結果は、以下のような感じです。

# firewall-cmd --list-all-zones
work
 target: default
 icmp-block-inversion: no
 interfaces:
 sources:
 services: dhcpv6-client ssh
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

drop
 target: DROP
 icmp-block-inversion: no
 interfaces:
 sources:
 services:
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

internal
 target: default
 icmp-block-inversion: no
 interfaces:
 sources:
 services: dhcpv6-client mdns samba-client ssh
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

external
 target: default
 icmp-block-inversion: no
 interfaces:
 sources:
 services: ssh
 ports:
 protocols:
 masquerade: yes
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

trusted
 target: ACCEPT
 icmp-block-inversion: no
 interfaces:
 sources:
 services:
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

home
 target: default
 icmp-block-inversion: no
 interfaces:
 sources:
 services: dhcpv6-client mdns samba-client ssh
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

dmz
 target: default
 icmp-block-inversion: no
 interfaces:
 sources:
 services: ssh
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

public (active)
 target: default
 icmp-block-inversion: no
 interfaces: eth0
 sources:
 services: dhcpv6-client https ssh
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

block
 target: %%REJECT%%
 icmp-block-inversion: no
 interfaces:
 sources:
 services:
 ports:
 protocols:
 masquerade: no
 forward-ports:
 sourceports:
 icmp-blocks:
 rich rules:

ディフォルトゾーン

新たなインターフェースに割り当てるデフォルトのゾーンを設定することができます。
ディフォルトゾーンの確認には、「--get-default-zone」オプションを使います。

以下の例では、ディフォルトゾーンは「pubulic」になっています。

# firewall-cmd --get-default-zone
public

firewall-cmd --list-all」コマンドでも確認することができます。

# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
sourceports:
icmp-blocks:
rich rules:

ゾーンの適用

NICに対してゾーンを適用する場合の手順を見てみましょう。

まず、対象NICに適用されているゾーンを確認するには、以下のようにコマンドを実行します。

# firewall-cmd --get-zone-of-interface=eth0
public

この例では、eth0 のゾーンは public が適用されていることが分かりますね。

では、eth0 のゾーンを trusted に変更してみましょう。

# firewall-cmd --add-interface=eth0 --zone=trusted
The interface is under control of NetworkManager, setting zone to 'trusted'.
success
# firewall-cmd --get-zone-of-interface=eth0
trusted

eth0 のゾーンが trusted に変わりました。
こんな感じで、NICにゾーンを適用することができます。

サービスの定義

サービスとは、TCPUDPのポート番号を定義したものです。

初期設定サービス

初期状態で定義されているサービスは、「firewall-cmd --get-services」コマンドで確認することができます。

実際に実行してみると、以下のような感じになっていました。

# firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client ceph ceph-mon dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp smtps snmp snmptrap squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

初期設定サービスの定義ファイル

これらのサービスは、「/usr/lib/firewalld/services」ディレクトリにあるファイルで定義されています。

# ls -l /usr/lib/firewalld/services/
total 324
-rw-r--r-- 1 root root 559 Nov 12 04:02 RH-Satellite-6.xml
-rw-r--r-- 1 root root 412 Nov 12 04:02 amanda-client.xml
-rw-r--r-- 1 root root 447 Nov 12 04:02 amanda-k5-client.xml
-rw-r--r-- 1 root root 320 Nov 12 04:02 bacula-client.xml
-rw-r--r-- 1 root root 346 Nov 12 04:02 bacula.xml
-rw-r--r-- 1 root root 294 Nov 12 04:02 ceph-mon.xml
-rw-r--r-- 1 root root 305 Nov 12 04:02 ceph.xml
-rw-r--r-- 1 root root 227 Nov 12 04:02 dhcp.xml
-rw-r--r-- 1 root root 305 Nov 12 04:02 dhcpv6-client.xml
-rw-r--r-- 1 root root 234 Nov 12 04:02 dhcpv6.xml
-rw-r--r-- 1 root root 346 Nov 12 04:02 dns.xml
-rw-r--r-- 1 root root 374 Nov 12 04:02 docker-registry.xml
-rw-r--r-- 1 root root 228 Nov 12 04:02 dropbox-lansync.xml
-rw-r--r-- 1 root root 836 Nov 12 04:02 freeipa-ldap.xml
-rw-r--r-- 1 root root 836 Nov 12 04:02 freeipa-ldaps.xml
-rw-r--r-- 1 root root 315 Nov 12 04:02 freeipa-replication.xml
-rw-r--r-- 1 root root 374 Nov 12 04:02 ftp.xml
-rw-r--r-- 1 root root 529 Nov 12 04:02 high-availability.xml
-rw-r--r-- 1 root root 353 Nov 12 04:02 http.xml
-rw-r--r-- 1 root root 448 Nov 12 04:02 https.xml
-rw-r--r-- 1 root root 327 Nov 12 04:02 imap.xml
-rw-r--r-- 1 root root 372 Nov 12 04:02 imaps.xml
-rw-r--r-- 1 root root 454 Nov 12 04:02 ipp-client.xml
-rw-r--r-- 1 root root 427 Nov 12 04:02 ipp.xml
-rw-r--r-- 1 root root 554 Nov 12 04:02 ipsec.xml
-rw-r--r-- 1 root root 264 Nov 12 04:02 iscsi-target.xml
-rw-r--r-- 1 root root 182 Nov 12 04:02 kadmin.xml
-rw-r--r-- 1 root root 233 Nov 12 04:02 kerberos.xml
-rw-r--r-- 1 root root 221 Nov 12 04:02 kpasswd.xml
-rw-r--r-- 1 root root 199 Nov 12 04:02 ldap.xml
-rw-r--r-- 1 root root 232 Nov 12 04:02 ldaps.xml
-rw-r--r-- 1 root root 385 Nov 12 04:02 libvirt-tls.xml
-rw-r--r-- 1 root root 389 Nov 12 04:02 libvirt.xml
-rw-r--r-- 1 root root 424 Nov 12 04:02 mdns.xml
-rw-r--r-- 1 root root 473 Nov 12 04:02 mosh.xml
-rw-r--r-- 1 root root 211 Nov 12 04:02 mountd.xml
-rw-r--r-- 1 root root 190 Nov 12 04:02 ms-wbt.xml
-rw-r--r-- 1 root root 171 Nov 12 04:02 mysql.xml
-rw-r--r-- 1 root root 324 Nov 12 04:02 nfs.xml
-rw-r--r-- 1 root root 389 Nov 12 04:02 ntp.xml
-rw-r--r-- 1 root root 335 Nov 12 04:02 openvpn.xml
-rw-r--r-- 1 root root 433 Nov 12 04:02 pmcd.xml
-rw-r--r-- 1 root root 474 Nov 12 04:02 pmproxy.xml
-rw-r--r-- 1 root root 460 Nov 12 04:02 pmwebapi.xml
-rw-r--r-- 1 root root 544 Nov 12 04:02 pmwebapis.xml
-rw-r--r-- 1 root root 348 Nov 12 04:02 pop3.xml
-rw-r--r-- 1 root root 357 Nov 12 04:02 pop3s.xml
-rw-r--r-- 1 root root 181 Nov 12 04:02 postgresql.xml
-rw-r--r-- 1 root root 509 Nov 12 04:02 privoxy.xml
-rw-r--r-- 1 root root 261 Nov 12 04:02 proxy-dhcp.xml
-rw-r--r-- 1 root root 424 Nov 12 04:02 ptp.xml
-rw-r--r-- 1 root root 414 Nov 12 04:02 pulseaudio.xml
-rw-r--r-- 1 root root 297 Nov 12 04:02 puppetmaster.xml
-rw-r--r-- 1 root root 520 Nov 12 04:02 radius.xml
-rw-r--r-- 1 root root 214 Nov 12 04:02 rpc-bind.xml
-rw-r--r-- 1 root root 311 Nov 12 04:02 rsyncd.xml
-rw-r--r-- 1 root root 384 Nov 12 04:02 samba-client.xml
-rw-r--r-- 1 root root 461 Nov 12 04:02 samba.xml
-rw-r--r-- 1 root root 337 Nov 12 04:02 sane.xml
-rw-r--r-- 1 root root 550 Nov 12 04:02 smtp.xml
-rw-r--r-- 1 root root 577 Nov 12 04:02 smtps.xml
-rw-r--r-- 1 root root 342 Nov 12 04:02 snmp.xml
-rw-r--r-- 1 root root 308 Nov 12 04:02 snmptrap.xml
-rw-r--r-- 1 root root 173 Nov 12 04:02 squid.xml
-rw-r--r-- 1 root root 463 Nov 12 04:02 ssh.xml
-rw-r--r-- 1 root root 496 Nov 12 04:02 synergy.xml
-rw-r--r-- 1 root root 444 Nov 12 04:02 syslog-tls.xml
-rw-r--r-- 1 root root 329 Nov 12 04:02 syslog.xml
-rw-r--r-- 1 root root 393 Nov 12 04:02 telnet.xml
-rw-r--r-- 1 root root 301 Nov 12 04:02 tftp-client.xml
-rw-r--r-- 1 root root 437 Nov 12 04:02 tftp.xml
-rw-r--r-- 1 root root 336 Nov 12 04:02 tinc.xml
-rw-r--r-- 1 root root 771 Nov 12 04:02 tor-socks.xml
-rw-r--r-- 1 root root 211 Nov 12 04:02 transmission-client.xml
-rw-r--r-- 1 root root 593 Nov 12 04:02 vdsm.xml
-rw-r--r-- 1 root root 475 Nov 12 04:02 vnc-server.xml
-rw-r--r-- 1 root root 310 Nov 12 04:02 wbem-https.xml
-rw-r--r-- 1 root root 509 Nov 12 04:02 xmpp-bosh.xml
-rw-r--r-- 1 root root 488 Nov 12 04:02 xmpp-client.xml
-rw-r--r-- 1 root root 264 Nov 12 04:02 xmpp-local.xml
-rw-r--r-- 1 root root 545 Nov 12 04:02 xmpp-server.xml

ファイルの内容は、以下のようになっています。

# cat /usr/lib/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
 <short>SSH</short>
 <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
 <port protocol="tcp" port="22"/>
</service>

これらのサービス定義ファイルも、ゾーンと同じようにマスターファイルの位置づけになりますので、編集しないようにしましょう。

新しいサービス定義を作成したい場合は、「/etc/firewalld/services」ディレクトリにファイルをコピーして、コピーしたファイルの内容を修正してください。

servicesを追加した場合は、以下のコマンドを実行して設定を再読込しておきます。

# firewall-cmd --reload

サービスの適用

firewalldでは、ゾーンに対して「サービス」を紐付けて通信許可設定を行います。

即時反映

ゾーンへのサービスの紐付けは、以下のように行います。

まずは、ゾーンに紐付いているサービスを確認します。

# firewall-cmd --list-services --zone=public
dhcpv6-client ssh

「dhcpv6-client」と「ssh」が紐付いていることが分かります。
ここに、「http」を追加してみます。

# firewall-cmd --add-service=http --zone=public
success
# firewall-cmd --list-services --zone=public
dhcpv6-client ssh http

サービス「http」が追加されました。
これで、ゾーン「public」が適用されたNICに対して、http(ポート80)への通信が許可されたことになります。
この設定は、コマンドを実行すると即時反映されますが、firewalldやOSを再起動すると設定する前の状態に戻ります。

永続的反映

再起動後も設定を有効にする場合には、オプション「--permanent」を付与してfirewall-cmdを実行しましょう。

# firewall-cmd --permanent --add-service=http --zone=public
success
# firewall-cmd --list-services --zone=public
dhcpv6-client ssh http

ここまでで見た目の変化はありませんが、--permanentオプションを付与すると、ゾーンの設定が書き換えられます。
「/etc/firewalld/zones」ディレクトリにゾーン定義ファイルがコピーされているので、確認しておきましょう。

# cd /etc/firewalld/zones/
# pwd
/etc/firewalld/zones
# ll
total 8
-rw-r--r--. 1 root root 366 Jan 10 04:31 public.xml
# cat public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="dhcpv6-client"/>
<service name="http"/>
<service name="ssh"/>
</zone>

これで、fierwalldやOSを再起動しても、httpの通信許可が設定された状態が維持されます。

即時反映と永続的反映について

Redhatのドキュメントには、以下のような記載があります。

コマンドを永続的にし、すぐに有効にするには、コマンドを --permanent を使用して 1 回、オプションなしで 1 回の合計 2 回入力します。
これは、ファイアーウォールのリロードには単にコマンドを繰り返すよりも時間がかかるためです (すべての設定ファイルをリロードし、ファイアーウォール設定全体を再作成する必要があります)。
リロード中に、安全上の理由により組み込みチェーンのポリシーは DROP に設定され、最終的に ACCEPT に再設定されます。したがって、リロード中にサービスが破棄されることがあります。

firewalldの稼動中に、サービスの紐付けを行いたい場合は、まずは--permanentオプションなしで即時反映してから、--permanentオプションを付与して永続的反映を行えば、通信へ影響を出さずにすみそうです。