手当たり次第に書くんだ

飽きっぽいのは本能

目次に戻る

概要

firewalldを設定します。firewalldはLinux OS上で有効なファイアウォールです。実態はnftables(CentOS7まではiptables)のフロントエンドであり、簡易的にファイアウォールを設定できます。

前提条件

OS

CentOS Stream 8を使用します。

SELinux

有効です。無効にする場合はこちらを参照して下さい。

Firewalld

無効です。有効化する場合はこちらを参照して必要な許可設定をして下さい。

その他

firewalldはルーターとして機能させる設定も可能ですが、本稿ではサーバーとして外部からのアクセスを制御することのみを取り上げます。

所感

ファイアウォールを実装すべき箇所

firewalldによらず、一般的なファイアウォール(L3/L4ファイアウォールの話です)はネットワーク上の様々な個所で有効化できます。firewalldのようにサーバーOS上、ルーター上、アプリケーション上等。このため実装しようとすれば、全てのファイアウォールを有効にできる個所に細かくファイアウォールを設定可能ですが、設定管理が煩雑となり、逆に設定ミスの元になりセキュリティの穴が生じる可能性もあります。ファイアウォールを有効にすべき個所は、主にネットワーク設計、または管理する範囲に依存します。具体的な例は別に記載します。

ファイアウォール機能の分離

ファイアウォールはサービスを提供するOS上ではなく、ルーター等のゲートウェイ上で実装するほうが良いです。これはサービスを提供するOSのroot権限が乗っ取られた場合、ファイアウォール設定を自由に変更できるためです。逆にファイアウォールは不特定多数に管理インターフェイスを提供することはまずありません。

マイクロセグメンテーション

サーバー間でL2通信が必要でなければ、/30のセグメントでサーバー毎に隔離し、ファイアウォールは接続するゲートウェイに任せたほうがよいです。高セキュリティが必要なサーバー(DMZのサーバー等)は、ゲートウェイの内側でアクセス先を制限します。このケースではサーバー側でファイアウォールを設定する必要性はあまりなく(サーバー管理者とルーター管理者が別でサーバー管理者が個別にファイアウォールを管理したい場合は必要です)、無効にしても良いかと思います。

本格的にファイアウォールとして使うには・・・

前述の通り、firewalldはnftables(iptables)のフロントエンドとして動作し、簡易的な設定が可能ですが、こういった類のものは例に漏れず細かい設定には向いていません。本格的にファイアウォールとして使用する場合は、nftables(iptables)を学ぶ必要があります。尚、CentOS8からはiptablesからnftablesに変更されていますが、iptablesコマンドも使用可能です。ただし、iptablesコマンドで設定した内容も実際はnftablesの設定に反映されています。nftablesの情報はまだまだ少ないので、現段階ではiptablesコマンドが使えるほうが楽ですね。

設定前に

下記のコマンドでデフォルトで定義されている全てのゾーンを確認できます。使用されているゾーンはactiveの記載があります。

[root@centos ~]# firewall-cmd --list-all-zones
block
  target: %%REJECT%%
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

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

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

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

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

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

nm-shared
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcp dns ssh
  ports:
  protocols: icmp ipv6-icmp
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule priority="32767" reject

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources:
  services: cockpit dhcpv6-client http ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

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

work
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

下記のコマンドでデフォルトゾーンを確認できます。CentOS8ではデフォルトでデフォルトゾーンがpublicに設定されています。デフォルトゾーンとは、明示的に設定していない全てのインターフェイスで有効になるゾーンとなり、デフォルトでcockpit、dhcpv6-client、sshの3つのサービスが許可されています。

[root@centos ~]# firewall-cmd --get-default-zone
public

下記のコマンドでアクティブゾーンを確認できます。アクティブゾーンは実際に使用されているゾーンでとなり、下記の例ではens33インターフェイスにpublicゾーンが割り当てられていることが確認できます。

[root@centos ~]# firewall-cmd --get-active-zone
public
  interfaces: ens33

設定例

設定例#1 デフォルトゾーンに対するサービス許可

設定例#1はデフォルトゾーンのpublicに公開したいサービスを追加します(コマンドでゾーンを指定しない場合はデフォルトゾーンが対象となります)。これは良くインターネットの記事で見かけます。下記の例ではhttpサービスを追加しています。尚、permanentは設定を永続化させるオプションです。permanentが無い場合、reloadすると設定が消えます(以下同様です)。

[root@centos ~]# firewall-cmd --permanent --add-service=http
[root@centos ~]# firewall-cmd --reload

下記のコマンドでhttpサービスが許可されていることを確認できます。記載の通り、cockpit、dhcpv6-client、sshも継続して許可されています。デフォルトで許可されているサービスを削除したい場合は、デフォルトで定義されているゾーンを編集するのではなく、新規にカスタムゾーンを作成するほうがお勧めです(設定例#2を参照)。

[root@centos ~]# firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources:
  services: cockpit dhcpv6-client http ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

設定例#2 カスタムゾーンの作成

設定例#2は新規にカスタムゾーンを作成して必要なサービスを許可します。下記のコマンドでmyzone(カスタムゾーン)を作成しています。

[root@centos ~]# firewall-cmd --permanent --new-zone=myzone

myzoneでsshとhttpサービスを許可し、reloadします。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --add-service=ssh --add-service=http
[root@centos ~]# firewall-cmd --reload

myzoneの内容を確認します。sshとhttpサービスのみ許可されています。

[root@centos ~]# firewall-cmd --zone=myzone --list-all
myzone
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: http ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

nmcliでmyzoneをens33インターフェイス(厳密にはプロファイルです。以下同じです。)に割り当て、再読み込みさせます。

[root@centos ~]# nmcli connection modify ens33 connection.zone myzone
[root@centos ~]# nmcli connection up ens33

ens33インターフェイスの状態を確認します(出力は抜粋しています)。

[root@centos ~]# nmcli connection show ens33
GENERAL.ZONE: myzone

デフォルトゾーンを確認します。下記の通り、publicであることが確認できます。

[root@centos ~]# firewall-cmd --get-default-zone
public

この段階では、明示的にmyzoneを割り当てたens33インターフェイス以外にインターフェイスが存在する場合は、それらのインターフェイスにはpublicが割り当てられます。publicでデフォルトで許可されたサービスがあるため、厳密にアクセス制御を行いたい場合は、デフォルトゾーンをdrop(すべて破棄)にします。これにより新規にインターフェイスを追加しても意図しないアクセスをブロックします。新規インターフェイスに対する許可設定は、myzoneとポリシーが同じであればmyzoneを割り当ててもよく、異なるのであれば別のゾーンを作成して割り当てます。

[root@centos ~]# firewall-cmd --set-default-zone=drop
[root@centos ~]# firewall-cmd --reload

デフォルトゾーンがdropに変更されたことが確認できます。

[root@centos ~]# firewall-cmd --get-default-zone
drop

設定例#3 送信元アドレスの制限

設定例#3は設定例#2をベースとして送信元アドレスを制限します。下記の例では送信元アドレスを10.0.0.0/24に制限します。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --add-source=10.0.0.0/24
[root@centos ~]# firewall-cmd --reload

myzoneの内容を確認します。sourcesに10.0.0.0/24が割り当てられていることが確認できます。この例では、10.0.0.0/24からsshとhttpサービスへのアクセスが許可されます。つまりsshは特定のネットワークからのみ、httpは全て許可という設定はできず、少々柔軟性に欠けます。用途ごとにインターフェイスを分けているケースでは違和感なく使えると思います。より柔軟に設定する場合はrich-ruleを使用します(設定例#4)。

[root@centos ~]# firewall-cmd --zone=myzone --list-all
myzone
  target: default
  icmp-block-inversion: no
  interfaces:
  sources: 10.0.0.0/24
  services: http ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

設定例#4 送信元アドレスとサービス制限

設定例#4は設定例#2をベースとしてsshは特定のネットワークから許可、httpは全て許可とします。まず、rich-ruleで送信元アドレスが10.0.0.0/24からのsshを許可します。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" service name=ssh accept'
[root@centos ~]# firewall-cmd --reload

次に定義済みのsshサービス許可を削除します。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --remove-service=ssh
[root@centos ~]# firewall-cmd --reload

myzoneの内容を確認します。rich-ruleで送信元アドレスが10.0.0.0/24からのsshが許可され、基本的な設定(rich-rule以外の設定)で全ての送信元アドレスからhttpが許可されています(rich-ruleは基本的な設定と独立しています)。また、基本的な設定では送信元アドレスしか制限できませんが、rich-ruleでは宛先アドレスも制限可能です。

[root@centos ~]# firewall-cmd --zone=myzone --list-all
myzone
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: http
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="10.0.0.0/24" service name="ssh" accept

設定例#5 ポート番号での制限

設定例#5はserviceに存在しないサービスをポート番号で許可します。設定例#4をベースとします。firewalldのserviceは/usr/lib/firewalld/services内にサービス毎に定義されており、ここに存在するサービス以外はfirewalldのserviceコマンドで使用できず(個別にカスタムサービスを作成可能ですが割愛します)、ポート番号での許可が必要です。下記の例ではtcp:12345を許可しています。udpの場合は単にtcpをudpに置き換えます。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --add-port=12345/tcp
[root@centos ~]# firewall-cmd --reload

rich-ruleで使用する場合も同様です。ポート番号だけ変えて許可しています。

[root@centos ~]# firewall-cmd --permanent --zone=myzone --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port=12346 protocol=tcp accept'
[root@centos ~]# firewall-cmd --reload

myzoneの内容を確認します。

[root@centos ~]# firewall-cmd --zone=myzone --list-all
myzone
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: http
  ports: 12345/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="10.0.0.0/24" service name="ssh" accept
        rule family="ipv4" source address="10.0.0.0/24" port port="12346" protocol="tcp" accept

その他

firewalldを無効化する場合

firewalldは他のサービスを同様、systemdで管理されていますので下記のコマンドで停止できます。

[root@centos ~]# systemctl disable --now firewalld.service

目次に戻る

CentOS 8 firewalld

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る