CentOS 7でFirewallDを使用してファイアウォールを設定する方法
CentOS 7を使用していませんか?別のバージョンまたはディストリビューションを選択してください。
紹介
Firewalldは、多くのLinuxディストリビューションで利用可能なファイアウォール管理ソリューションで、Linuxカーネルによって提供されるiptablesパケットフィルタリングシステムのフロントエンドとして機能します。このガイドでは、サーバー用のファイアウォールを設定する方法を説明し、firewall-cmd管理ツールを使用してファイアウォールを管理する基本を紹介します(CentOSでiptablesを使用したい場合は、このガイドに従ってください)。
注意: この文書が書かれた時点での firewalld よりも新しいバージョンで作業している可能性があるか、またはあなたのサーバーがこのガイド全体で使用されているサンプルサーバーとは若干異なる設定がされている可能性があります。このガイドで説明するいくつかのコマンドの動作は、あなたの特定の設定に応じて異なる場合があります。
ファイアウォールにおける基本概念
実際に firewall-cmd ユーティリティを使用してファイアウォールの設定を管理する方法について話し始める前に、このツールが導入するいくつかの基本的な概念に慣れておくべきです。
ゾーン
firewalld デーモンは「ゾーン」と呼ばれるエンティティを使用してルールのグループを管理します。ゾーンは基本的に、コンピュータが接続されているネットワークに対する信頼のレベルに応じて、どのトラフィックを許可すべきかを指示するルールのセットです。ネットワークインターフェースには、ファイアウォールが許可すべき動作を示すためにゾーンが割り当てられます。
ネットワークを頻繁に移動する可能性のあるコンピュータ(例えばノートパソコン)の場合、このような柔軟性は環境に応じてルールを変更する良い方法を提供します。公共のWiFiネットワークを使用しているときにはほとんどのトラフィックを禁止する厳格なルールを設けているかもしれませんが、自宅のネットワークに接続しているときにはより緩い制限を許可することがあります。サーバーの場合、これらのゾーンはあまり重要ではありません。なぜなら、ネットワーク環境はほとんど、あるいは全く変わらないからです。
ネットワーク環境がどれほど動的であっても、firewalldの各事前定義ゾーンの一般的な考え方に慣れておくことは依然として有用です。信頼度が低いものから信頼度が高いものへ、firewalld内の事前定義ゾーンは以下の通りです:
- ドロップ: 最低レベルの信頼。すべての着信接続は応答なしで切断され、発信接続のみが可能です。
- ブロック: 上記と同様ですが、単に接続を切断するのではなく、受信するリクエストは
icmp-host-prohibitedまたはicmp6-adm-prohibitedメッセージで拒否されます。 - パブリック: 公共の信頼できないネットワークを表します。他のコンピュータを信頼していませんが、場合によっては選択した受信接続を許可することがあります。
- 外部: ファイアウォールをゲートウェイとして使用している場合の外部ネットワーク。内部ネットワークがプライベートでありながらアクセス可能であるように、NATマスカレードのために設定されています。
- 内部: 外部ゾーンの反対側、ゲートウェイの内部部分に使用されます。コンピュータはかなり信頼でき、いくつかの追加サービスが利用可能です。
- DMZ:DMZ(他のネットワークにアクセスできない孤立したコンピュータ)にあるコンピュータ用です。特定の受信接続のみが許可されています。
- 作業: 作業機械に使用されます。ネットワーク内のほとんどのコンピュータを信頼します。他にいくつかのサービスが許可される可能性があります。
- ホーム: ホーム環境です。一般的に、他のコンピュータのほとんどを信頼していることを意味し、いくつかのサービスが受け入れられることを示しています。
- 信頼された: ネットワーク内のすべてのマシンを信頼します。利用可能なオプションの中で最もオープンなものであり、控えめに使用するべきです。
ファイアウォールを使用するには、ルールを作成し、ゾーンのプロパティを変更し、最も適切なゾーンにネットワークインターフェースを割り当てることができます。
ルールの永続性
firewalldでは、ルールを永続的または即時として指定できます。ルールが追加または変更されると、デフォルトでは、現在実行中のファイアウォールの動作が変更されます。次回の起動時には、変更が破棄され、古いルールが適用されます。
ほとんどのfirewall-cmd操作には、非一時的なファイアウォールが対象であることを示す--permanentフラグを使用できます。これにより、起動時に再読み込みされるルールセットに影響が及びます。この分離により、アクティブなファイアウォールインスタンスでルールをテストし、問題があれば再読み込みすることができます。また、--permanentフラグを使用して、再読み込みコマンドが発行されたときに一度に適用される一連のルールを時間をかけて構築することもできます。
ファイアウォールをインストールしてブート時に起動するように有効にしてください
firewalld は、一部のLinuxディストリビューション、特にCentOS 7の多くのイメージにデフォルトでインストールされています。しかし、firewalldを自分でインストールする必要があるかもしれません:
- sudo yum install firewalld
firewalldをインストールした後、サービスを有効にしてサーバーを再起動できます。firewalldを有効にすると、サービスが起動時に立ち上がることに注意してください。潜在的な問題を避けるために、この動作を構成する前にファイアウォールルールを作成し、それをテストする機会を持つことが最善の方法です。
- sudo systemctl enable firewalld
- sudo reboot
サーバーが再起動すると、ファイアウォールが起動し、ネットワークインターフェースは設定したゾーンに配置されるべきであり(または設定されたデフォルトゾーンに戻ります)、ゾーンに関連するルールが関連するインターフェースに適用されます。
サービスが実行中であり、アクセス可能であることを確認するには、次のように入力します。
- sudo firewall-cmd --state
running
これは、私たちのファイアウォールがデフォルト構成で稼働していることを示しています。
現在のファイアウォールルールに慣れる
変更を始める前に、デーモンが提供するデフォルトの環境とルールに慣れておくべきです。
デフォルトを探る
現在、デフォルトとして選択されているゾーンを見るには、次のように入力します:
- firewall-cmd --get-default-zone
public
デフォルトゾーンから逸脱するようなコマンドを firewalld に与えていないため、またインターフェースのいずれも別のゾーンにバインドするように設定されていないため、そのゾーンは唯一の「アクティブ」ゾーン(インターフェースのトラフィックを制御しているゾーン)となります。それを確認するには、次のように入力します:
- firewall-cmd --get-active-zones
public
interfaces: eth0 eth1
ここでは、例のサーバーにファイアウォールによって制御されている2つのネットワークインターフェース(eth0とeth1)があることがわかります。これらは現在、パブリックゾーンに定義されたルールに従って管理されています。
それでは、公共ゾーンに関連するルールがどのように分かるのでしょうか?デフォルトゾーンの設定を印刷するには、次のように入力します:
- sudo firewall-cmd --list-all
public (default, active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
出力から、このゾーンがデフォルトであり、かつアクティブであること、eth0およびeth1インターフェースがこのゾーンに関連付けられていることがわかります(これは以前の調査からすでに知っていました)。しかし、このゾーンがDHCPクライアント(IPアドレス割り当てのため)およびSSH(リモート管理のため)に関連する通常の操作を許可していることも確認できます。
代替ゾーンの探求
現在、デフォルトゾーンとアクティブゾーンの設定について良いアイデアがあります。他のゾーンについての情報も知ることができます。
利用可能なゾーンのリストを取得するには、次のように入力してください:
- firewall-cmd --get-zones
block dmz drop external home internal public trusted work
ゾーンに関連付けられた特定の設定は、--list-all コマンドに --zone= パラメータを含めることで見ることができます:
- sudo firewall-cmd --zone=home --list-all
home
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns samba-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
すべてのゾーン定義を出力するには、--list-all-zonesオプションを使用します。出力をより簡単に表示するために、パイプでページャに送ることをお勧めします:
- sudo firewall-cmd --list-all-zones | less
インターフェースのためのゾーンの選択
ネットワークインターフェースを別に設定していない限り、ファイアウォールが起動されたときに各インターフェースはデフォルトゾーンに配置されます。
インターフェースのゾーンを変更する
セッション中に、--zone= パラメーターと --change-interface= パラメーターを組み合わせて使用することで、ゾーン間でインターフェースを切り替えることができます。ファイアウォールを変更するすべてのコマンドと同様に、sudo を使用する必要があります。
例えば、次のように入力することで、eth0 インターフェースを「home」ゾーンに移行できます:
- sudo firewall-cmd --zone=home --change-interface=eth0
success
注意: インターフェースを新しいゾーンに移行する際は、運用されるサービスが変更される可能性があることに注意してください。たとえば、ここではSSHが利用可能な「ホーム」ゾーンに移動しています。これは、私たちの接続が切断されないことを意味します。他のゾーンの中には、デフォルトでSSHが有効になっていないものもあり、これらのゾーンを使用しているときに接続が切断されると、再度ログインできなくなることがあります。
これが成功したことを、再度アクティブゾーンを求めることで確認できます。
- firewall-cmd --get-active-zones
home
interfaces: eth0
public
interfaces: eth1
デフォルトゾーンの調整
すべてのインターフェイスを単一のゾーンで最適に処理できる場合、おそらく最適なデフォルトゾーンを選択し、それを設定に使用する方が簡単です。
デフォルトゾーンは--set-default-zone=パラメータを使用して変更できます。これにより、デフォルトに戻っていたインターフェースはすぐに新しいゾーンに変更されます:
- sudo firewall-cmd --set-default-zone=home
success
アプリケーションのルールを設定する
提供したいサービスのためのファイアウォールの例外を定義する基本的な方法は非常に簡単です。ここで基本的な考え方を説明します。
ゾーンにサービスを追加する
最も簡単な方法は、使用しているゾーンに必要なサービスやポートを追加することです。再度、--get-servicesオプションを使用して、利用可能なサービスのリストを取得できます:
- firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync 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 ディレクトリ内の関連する .xml ファイルを見ればわかります。例えば、SSHサービスは次のように定義されています:
<?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>
ゾーンにサービスを有効にするには、--add-service= パラメーターを使用します。この操作は、デフォルトのゾーンまたは--zone= パラメーターで指定されたゾーンを対象とします。デフォルトでは、これは現在のファイアウォールセッションのみを調整します。--permanent フラグを含めることで、永続的なファイアウォール構成を調整できます。
たとえば、従来のHTTPトラフィックを提供するWebサーバーを実行している場合、このセッションのために「公開」ゾーンのインターフェースでこのトラフィックを許可するには、次のように入力できます:
- sudo firewall-cmd --zone=public --add-service=http
デフォルトゾーンを変更したい場合は、--zone=を省略することができます。操作が成功したかどうかは、--list-allまたは--list-servicesの操作を使用して確認できます:
- sudo firewall-cmd --zone=public --list-services
dhcpv6-client http ssh
すべてが正常に動作していることを確認したら、再起動後でもサービスが利用可能であるように、永続的なファイアウォールルールを変更したいと思うでしょう。「public」ゾーンの変更を永続的にするには、次のように入力します:
- sudo firewall-cmd --zone=public --permanent --add-service=http
success
この操作が成功したことを確認するには、--list-services 操作に --permanent フラグを追加してください。--permanent 操作を行うには sudo を使用する必要があります。
- sudo firewall-cmd --zone=public --permanent --list-services
dhcpv6-client http ssh
あなたの「公開」ゾーンは、今後ポート80でHTTPウェブトラフィックを許可します。ウェブサーバーがSSL/TLSを使用するように設定されている場合は、httpsサービスも追加する必要があります。それを現在のセッションおよび永続的なルールセットに追加するには、以下のように入力します:
- sudo firewall-cmd --zone=public --add-service=https
- sudo firewall-cmd --zone=public --permanent --add-service=https
適切なサービスが利用できない場合はどうしますか?
firewalldのインストールに含まれるファイアウォールサービスは、アクセスを許可したいアプリケーションの最も一般的な要件の多くを表しています。しかし、これらのサービスがあなたの要件に合わないシナリオも考えられます。
この状況では、あなたには二つの選択肢があります。
あなたのゾーンのためのポートを開く
特定のアプリケーションのサポートを追加する1つの方法は、適切なゾーンで使用されているポートを開くことです。これは、開く必要のあるポートまたはポート範囲、および関連するプロトコルを指定することによって行います。
たとえば、私たちのアプリケーションがポート5000で実行され、TCPを使用している場合、--add-port=パラメーターを使用して、このセッションの「公開」ゾーンに追加することができます。プロトコルはtcpまたはudpのいずれかです。
- sudo firewall-cmd --zone=public --add-port=5000/tcp
success
この操作が成功したことを、--list-ports操作を使用して確認できます:
- sudo firewall-cmd --zone=public --list-ports
5000/tcp
ポートの順次範囲を指定することも可能で、範囲の開始ポートと終了ポートをダッシュで区切ることができます。例えば、私たちのアプリケーションがUDPポート4990から4999を使用する場合は、次のようにして「public」でこれらを開くことができます:
- sudo firewall-cmd --zone=public --add-port=4990-4999/udp
テスト後、これらを恒久的なファイアウォールに追加したいと思います。次のように入力することでそれができます:
- sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp
- sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp
- sudo firewall-cmd --zone=public --permanent --list-ports
success
success
5000/tcp 4990-4999/udp
サービスの定義
ゾーンのポートを開くのは簡単ですが、それぞれのポートが何のためにあるのかを把握するのは難しいことがあります。サーバー上でサービスを廃止する場合、開放されたポートの中でまだ必要なものを思い出すのが難しいかもしれません。このような状況を避けるために、サービスを定義することが可能です。
サービスは、関連する名前と説明を持つポートのコレクションです。サービスを使用する方がポートよりも管理が容易ですが、最初に少しの作業が必要です。始める良い方法は、既存のスクリプト(/usr/lib/firewalld/servicesにあります)をコピーして、ファイアウォールが非標準の定義を探す/etc/firewalld/servicesディレクトリに配置することです。
例えば、SSHサービスの定義をコピーして「例」サービスの定義として使用することができます。このように、拡張子.xmlを除いたファイル名が、ファイアウォールサービスリスト内でのサービスの名前を決定します:
- sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/example.xml
今、コピーしたファイルに見つかった定義を調整できます:
- sudo vi /etc/firewalld/services/example.xml
まず、ファイルにはコピーしたSSHの定義が含まれています:
<?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>
この定義の大部分は実際にはメタデータです。<short> タグ内でサービスの短い名前を変更する必要があります。これはあなたのサービスの人間が読み取れる名前です。また、サービスを監査する必要がある場合に備えて、説明を追加することも重要です。サービスの機能に実際に影響を与える唯一の構成は、開放したいポート番号とプロトコルを特定するポート定義になるでしょう。これは複数回指定できます。
私たちの「例」サービスの場合、TCP用にポート7777を、UDP用にポート8888を開く必要があると想像してください。iを押してINSERTモードに入ることで、既存の定義を次のように変更できます。
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Example Service</short>
<description>This is just an example service. It probably shouldn't be used on a real system.</description>
<port protocol="tcp" port="7777"/>
<port protocol="udp" port="8888"/>
</service>
「ESC」を押してから、:xと入力してファイルを保存して閉じてください。
新しいサービスにアクセスするにはファイアウォールを再ロードしてください:
- sudo firewall-cmd --reload
これは現在利用可能なサービスのリストにあることがわかります:
- firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch example freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync 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
今、あなたのゾーンで通常通りこのサービスを利用できるようになりました。
自分のゾーンを作成する
事前に定義されたゾーンは、ほとんどのユーザーにとって十分かもしれませんが、機能をより明確に示す独自のゾーンを定義することも役立ちます。
例えば、ウェブサーバー用に「publicweb」と呼ばれるゾーンを作成したいかもしれません。しかし、プライベートネットワークで提供するDNSサービス用に別のゾーンを設定したい場合もあります。そのために「privateDNS」と呼ばれるゾーンを作りたいかもしれません。
ゾーンを追加する際は、それを永久的なファイアウォール設定に追加する必要があります。次に、設定を実行中のセッションに反映させるためにリロードできます。たとえば、上で話し合った2つのゾーンを作成するには、次のように入力できます:
- sudo firewall-cmd --permanent --new-zone=publicweb
- sudo firewall-cmd --permanent --new-zone=privateDNS
これらがあなたの永続的な設定に存在することを確認するには、次のように入力します:
- sudo firewall-cmd --permanent --get-zones
block dmz drop external home internal privateDNS public publicweb trusted work
前述のように、これらは現在のファイアウォールのインスタンスではまだ利用できません:
- firewall-cmd --get-zones
block dmz drop external home internal public trusted work
これらの新しいゾーンをアクティブ構成に取り込むためにファイアウォールを再読み込みしてください:
- sudo firewall-cmd --reload
- firewall-cmd --get-zones
block dmz drop external home internal privateDNS public publicweb trusted work
さて、適切なサービスとポートをゾーンに割り当てることを始めることができます。通常、アクティブインスタンスを調整し、その後、テスト後にそれらの変更を永久的な構成に転送するのが良い考えです。たとえば、「publicweb」ゾーンの場合、SSH、HTTP、およびHTTPSサービスを追加したいかもしれません。
- sudo firewall-cmd --zone=publicweb --add-service=ssh
- sudo firewall-cmd --zone=publicweb --add-service=http
- sudo firewall-cmd --zone=publicweb --add-service=https
- sudo firewall-cmd --zone=publicweb --list-all
publicweb
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh http https
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
同様に、私たちは「privateDNS」ゾーンにDNSサービスを追加できます:
- sudo firewall-cmd --zone=privateDNS --add-service=dns
- sudo firewall-cmd --zone=privateDNS --list-all
privateDNS
interfaces:
sources:
services: dns
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
それから、これらの新しいゾーンにインターフェースを変更してテストすることができます:
- sudo firewall-cmd --zone=publicweb --change-interface=eth0
- sudo firewall-cmd --zone=privateDNS --change-interface=eth1
この時点で、構成をテストする機会があります。これらの値があなたのために機能する場合、同じルールを永続的な構成に追加することをお勧めします。--permanentフラグを使ってルールを再適用することでそれを行うことができます:
- sudo firewall-cmd --zone=publicweb --permanent --add-service=ssh
- sudo firewall-cmd --zone=publicweb --permanent --add-service=http
- sudo firewall-cmd --zone=publicweb --permanent --add-service=https
- sudo firewall-cmd --zone=privateDNS --permanent --add-service=dns
これらのルールを永続的に適用した後、ネットワークを再起動し、ファイアウォールサービスを再読み込みできます:
- sudo systemctl restart network
- sudo systemctl reload firewalld
正しいゾーンが割り当てられていることを確認してください。
- firewall-cmd --get-active-zones
privateDNS
interfaces: eth1
publicweb
interfaces: eth0
そして、両方のゾーンに対して適切なサービスが利用可能であることを確認してください。
- sudo firewall-cmd --zone=publicweb --list-services
http https ssh
- sudo firewall-cmd --zone=privateDNS --list-services
dns
自分のゾーンを正常に設定しました!これらのゾーンの1つを他のインターフェースのデフォルトにしたい場合は、--set-default-zone=パラメーターを使用してその動作を設定することを忘れないでください:
sudo firewall-cmd --set-default-zone=publicweb
結論
あなたは今、CentOSシステムで日常的にfirewalldサービスを管理する方法についてかなり良い理解を持っているはずです。
firewalldサービスは、ネットワーク環境を考慮した持続可能なルールやルールセットを構成することを可能にします。ゾーンを使用することで、異なるファイアウォールポリシーの間をシームレスに移行でき、管理者はポート管理をより親しみやすいサービス定義に抽象化する能力を与えられます。このシステムについての実践的な知識を身につけることで、このツールが提供する柔軟性と力を利用できるようになります。
