デーモンは同じLinux上で複数動作させることができます。つまり、1台のサーバーで複数のサービスをユーザーに提供できます。
そのため、同じLinux上で動作するサービスを区別するための識別子のようなものが必要です。

それが、「ポート」と呼ばれる番号です。IPアドレスでLinuxのサーバーを特定して、ポート番号で、そのIPアドレスで提供されている特定のサービスにアクセスできるというわけです。

ポートはサーバー上のサービスにアクセスするためのいわば窓口と言えます。ただ、その窓口の後ろでデーモンが動作しているわけですが、必ずしも全ての人に公開しておく必要はありません。

むしろ、公開しておくことで悪意あるユーザーに狙われてしまうなどのセキュリティ上の問題を引き起こす可能性が高まります。

そのため、ポートは必要最低限なものだけを公開しておくようにする必要があります。
最近では、セキュリティ意識がずいぶん高くなってきて、動かす必要のないデーモンは一切動かさないことが常識です。

ポート番号に対してのアクセスを制限するために「firewalld」という仕組みを使います。
firewalldでは、どのポートに対するアクセスか、どのIPアドレスから行われているアクセスかといった規則に従ってアクセスを制限できます。

firewalldとは

ファイアウォールには静的ファイアウォールと動的ファイアウォールがあります。CentOS 7、RHEL 7からは動的ファイアウォールの仕組みとして、firewalldが新たに追加されました。

firewalldではネットワークを抽象化して「ゾーン」に分けて管理します。これはiptablesには存在しなかった仕組みです。
ただ、既に世の中ではこの考え方は浸透しています。ネットワークを設計をする際、各ネットワークをゾーンという単位で区切ります。この概念をファイアウォールにそのまま実装できるようになったというわけです。

firewalldではネットワークインターフェースは、どこかのゾーンに属します。何も設定していないネットワークインターフェースはデフォルトゾーンに所属します。そして、ゾーンに対して各種サービスの許可ルールを追加していきます。

サービスは事前にある程度定義されており、そのサービスの定義の中にTCPやUDPのポート番号などの情報が定義されています。
この、ゾーンにサービスを割り当てるという概念は、従来型の静的ファイアウォールのルールを記述していたエンジニアにとっては斬新な仕組みと受け取れることでしょう。

firewalldは旧方式のiptablesと同じく、Linuxが持つパケットフィルタリングの仕組みの「Netfilter」を利用してフィルタリング処理を行っています。しかし両者は、ファイアウォールを設定するときの考え方が違います。firewalldでは、ACLを定義するスタイルではなく、目的のサービスに関連するポートを開放するというスタイルで設定していきます。

firewall-cmdで設定する

firewalldを設定するコマンドラインツールとして、firewall-cmdが用意されています。firewall-cmdコマンドにより、ゾーンにサービスを追加したり、ネットワークインターフェースが属するゾーンを変更したりできます。
firewall-cmdのほかに、GUIから設定するfirewall-configや、D-BusのAPIを使ったアプリケーションからfirewalldを設定できます。

ゾーンという考え方

ネットワーク管理者が、管理対象ネットワークのセキュリティを確保するためにTrusted/Untrustedという分け方でネットワークを分離する設計手法があります。
分離されたくくりをゾーン(セキュリティゾーン)と呼びます。特にネットワーク間のファイアウォールを設計する際に、このような分け方をするでしょう。
ただし、現実にはTrusted/Untrusted以外にも、おおむね信用できるが攻撃されるかもしれないというゾーンが存在するときもあり、左記の2つだけでは足りない場合があります。

firewalldには、事前定義済みゾーンが9つあります。

publicゾーンもしくはdmzゾーンは、インターネットに公開するサービスがある場合に利用され、おおむね信用できるが攻撃されるかもしれないゾーンと言えます。

trustedゾーンは、すべてのパケットを通過させます。家庭内LANなど絶対的に信用できるゾーンと言えます。
一見すると重複するゾーンがありあすが、実際どれを使うかはユーザーの自由です。どのゾーンにしようかと迷ったらデフォルトのpublicゾーンをベースに許可するサービス追加していくと良いでしょう。

ゾーンという考え方を理解するために、まずはfirewalldに事前に定義されているゾーンの一覧を取得しましょう。
次のように、firewall-cmdに–get-zonesオプションを付けて実行します。

# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

この例では、9つのゾーンが定義されていることが確認できます。

デフォルトのゾーンを確認するには、–get-default-zoneオプションを付けて実行します。

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

「public」がデフォルトのゾーンになっています。

サービスの一覧を取得する

事前に定義されているサービスの一覧を取得するには、–get-servicesオプションを付けて実行します。
これらのサービスの定義は、/usr/lib/firewalld/services/ディレクトリ以下にXML形式で格納されています。ここは直接書き換えてはいけません。ユーザー定義のサービスをfirewalldに追加したい場合は、/etc/firewalld/services/の中へ追加する必要があります。なお、同じサービス名の場合、/usr/lib/firewalld/services/よりも/etc/firewalld/services/の中にあるファイルが優先されます。

# firewall-cmd --get-services
RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind rsyncd samba samba-client smtp ssh telnet tftp tftp-client transmission-client vdsm vnc-server wbem-https

httpサービスの定義を見る

たとえば、firewalldのhttpサービスが定義されているXMLファイルを確認してみましょう。httpサービスの説明と共に、プロトコルがTCPで、ポートが80であると定義されているのが分かります。

# cat /usr/lib/firewalld/services/http.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>WWW (HTTP)</short>
  <description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
  <port protocol="tcp" port="80"/>
</service>

sambaサービスの定義を見る

次はfirewalldのsambaサービスの定義を見てみましょう。sambaサービスではhttpサービスと異なり、複数のポート指定とNetfilter Conntrackモジュールの指定が行われています。

# cat /usr/lib/firewalld/services/samba.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Samba</short>
  <description>This option allows you to access and participate in Windows file and printer sharing networks. You need the samba package installed for this option to be useful.</description>
  <port protocol="udp" port="137"/>
  <port protocol="udp" port="138"/>
  <port protocol="tcp" port="139"/>
  <port protocol="tcp" port="445"/>
  <module name="nf_conntrack_netbios_ns"/>
</service>

このように、firewalldで事前に定義されたサービスを利用すると、1つ1つポート番号を指定しなくとも、一括で複数の関連するポートに対して通過を許可できます。