firewalldの最も簡単な説明を目指す、その2
firewalldの最も簡単な説明を目指すの続きである。
デフォルトゾーンとアクティブゾーン
先に書いたが、firewalldには、あらかじめゾーンが複数用意されており、それぞれのゾーンに対してNICを割り当てたり、開けるポートを変更できる。さらに、自分で名前をつけた新たなゾーンを定義して自由な設定にすることもできる。しかし、必ずしもすべてのゾーンが使われるとは限らない。あらかじめ用意されている9つのゾーンのうち、一つか二つしか使わないかもしれない。
典型的なケースとして、レンタルサーバ屋さんでVPサーバを借りると、そこにNICが一つだけついているが、この場合、publicゾーンにそのNICが割り当てられた状態だろう。つまり、publicゾーンしか使われておらず、ここで開いているポートは、ほぼSSH用のみである。ともあれ、public以外の8つのゾーンは全く使われていない。
※おそらくfirewalldをいじりたいと思う、ほとんど大部分がこういうケースではないだろうか?大規模な場合には、そもそもこんなページの解説など読まないだろう。
ここで言葉を定義しておくが、まず、デフォルトゾーンとは、例えばNICがどこのゾーンにも属していない場合に、デフォルトで割り当てられるゾーンのこと。上の状況では、当然だが、デフォルトゾーンはpublicになっており、ここで新たにNICを接続すると(再度だが、これは物理的なものではなく、仮想的なものでもよい)、publicに属することになる。
次にアクティブゾーンだが、これは簡単だ。機能を果たしているゾーンをアクティブゾーンという。このケースの場合には、何らかのNICが属しているゾーンである。NICを入れてあげればそれはアクティブになるし、はずせばそうではなくなる。アクティブをON/OFFするスイッチのようなものはない。
ゾーンの状態を調べる
全ゾーンの名称を得るには以下のコマンド。ここでは、どの一つがデフォルトか、どの複数がアクティブかはわからない。
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
以下でアクティブゾーンを知ることができる。ここではpublic一つのみがアクティブになっている。複数のアクティブゾーンがあれば、それがNICと共に表示される。
# firewall-cmd --get-active-zones
public
interfaces: eth0
デフォルトゾーンを知る。publicになっている。
# firewall-cmd --get-default-zone
public
すべてのゾーン設定を表示する。この結果は長すぎるし、あまり意味がないので省略
# firewall-cmd --list-all-zones
デフォルトゾーンの状態を取得する。他の解説では、アクティブゾーン、つまり現在アクティブな複数のゾーンの状態を取得するとなっているものがあるが、間違いである。このコマンドはデフォルトゾーンの状態のみを取得する。
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports: 80/tcp 443/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
※なお、上の出力結果に「target: default」という文言があるが、これはデフォルトゾーンを示すものではない。デフォルトゾーンが何であるかは、「firewall-cmd –get-default-zone」を見る必要がある。
次に、特定のゾーンの状態だけを見る
# firewall-cmd --list-all --zone="block"
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
ゾーンの状態が意味するもの
さて。上で示したゾーン設定の文言は何を意味しているのだろうか?つまり、以下である。不思議なことに、いくら検索してもこの意味を解説しているページはなかなか出てこない。
firewalld のコマンドの使い方まとめ、Firewalls Using FirewallD: Red Hat Enterprise Linux 8、firewalldについてなどを参考にした。
target:
icmp-block-inversion:
interfaces:
sources:
services:
ports:
protocols:
masquerade:
forward-ports:
source-ports:
icmp-blocks:
rich rules:
target
例えば、あるポート番号に対して何の設定もされていなければ、ここに記述された処理が行われる。つまり、デフォルトの動作ということ。ACCEPT, REJECT, DROPの値がある。
- ACCEPT:すべて受け入れる。
- REJECT:拒否してICMP拒否メッセージを返信するため、送信元はシステムが拒否していることがただちにわかる。
- DROP:拒否して何も返信しない。送信元がブラウザの場合には、しばらく待たされた後タイムアウトになる。一般的にはDROPよりREJECTが望ましい。
さて、ここにdefaultと書くとどんな意味かだが、firewalld の target の default と REJECT の違いに記述があった。
※上では、拒否を「REJECT」と書いてあるが、これは省略形のようで、実際には「%%REJECT%%」と書くようだ。REJECTと%%REJECT%%の二種類があるわけではない模様。なぜこんなことになっているのかは不明。
icmp-block-inversion, icmp-blocks
ICMPというのは、平たくいえばpingコマンドを受け入れるかどうかで、不特定多数から受け入れても特に害は無い。
ファイアウォールでpingの疎通確認を拒否するで解説されているが、この意味は以下の通り。
-「icmp-block-inversion: yes」の時、icmp-blocksに記載されたICMP Typeを受け入れる。
-「icmp-block-inversion: no」の時、icmp-blocksに記載されたICMP Typeを拒否する。
つまり、「no, 記述無し」の場合は、何でも受け入れることになり、「yes, 記述無し」の場合はすべて拒否することになる。
interfaces
このゾーンに所属しているNIC。NICは一つのゾーンにしか所属できない。
sources
通常は、NIC集合である一つのゾーンについて、特定ポートを「不特定多数」に対して開放するか否かを指定するわけだが、ときには、インターネット上の特定集団にだけ開放したい場合がある。例えば、ある企業が特定のIPアドレス範囲を必ず使っているとして、その企業のみにアクセスを許したい場合に、そのIPアドレス範囲を指定する。こうすると、ポートは開いているものの、それ以外のIPアドレスからはアクセスすることができなくなる。
これを行うと、たとえ暗号鍵やパスワードが盗まれても外からは絶対にアクセスできない。上のような企業の特定のIPアドレス範囲でなくとも、例えば一つの回線を固定IPアドレス契約とし、そのIPアドレスのみに限定してしまうと、どうやっても他からはアクセスできなくなる。
services
firewalldの基本的機能はポートを開けてあげることだが、常に80番、443番などと記述してはわけがわからなくなるので、あらかじめ名前のついた「サービス」の定義を行い、その名前をここに記述することになっている。これらのサービスを定義したxmlファイル軍は、/usr/lib/firewalld/servicesディレクトリにある。私の環境では例えば、cockpit.xmlというファイルがあるが、その中身は以下である。
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Cockpit</short>
<description>Cockpit lets you access and configure your server remotely.</description>
<port protocol="tcp" port="9090"/>
</service>
これによって、services: cockpitと書くことで、9090番ポートが開けられることになる。
ports
番号を指定してポートを開放する。名前付きのservicesと同じ機能。
protocols
tcp udp icmp ospf等を記載するようだが、おそらくデフォルトでは、全プロトコルを通すものと思われる。もちろん、services, portsに指定されたものだけだろう。
上記以外
とりあえず不要、なおかつ機能が複雑すぎるので省略する。
公開サーバのユースケースで必要なこと
以前の記事で以下のユースケースを記述した。
例えば、ネット上に何らかのサーバマシンを借りて、そこでウェブサーバを運営し、その一方で、VPNを構成して手元のPCから自由な通信をしたいとする。この場合、サーバマシンの外部と接続している物理的なNICと、VPNを構成した場合の仮想的なNICの二つの構成になると思うが、その場合、以下の設定になるだろう。
- publicゾーンにてウェブサイトの80や443を開放するように変更し、物理的NICはここに属させる。
- trustedゾーンにVPNの仮想的NICを属させる。このVPNに所属する、例えば手元のPCは、サーバ側に自由にアクセスできる。
このユースケースに必要なことは以下だろう。
public
target: default
icmp-block-inversion: yes(ping拒否)、no(ping受け入れ)
interfaces: eth0
sources: 無し
services: http https sshなど
ports: 無し
masquerade: no
その他略
trusted
target: ACCEPT
icmp-block-inversion: no(ping受け入れ)
interfaces: VPNの仮想的NIC
sources: 無し
services: 無し
ports: 無し
masquerade: no
その他略
続く