LinuxのFirewallの設定をやってみた

自宅にあるLinuxFirewallの設定をいじってなかったんでいじくろうかと。

環境

bookstore@bookstoreUbuntu:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.1 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

Firewalldのインストール

LinuxではNetfilterなるものがあり、FirewallやRouterの役割を果たしてくれる。Netfilterの設定を変更するには以下のようなツールが存在する。

  • iptables ... 詳細な設定ができる。NetfilterのIPv4の実装がiptablesというのでそれに付随してるデフォルトのツールかと思う。
  • firewalld ... いくつかのテンプレートから設定を行う。高度なことをしない限りこちらを使うのが普通かと。
  • ufw ... iptables のフロントエンドツール

firewalldもufwも内部ではiptablesを使っている。

Wikipedia iptables

今回はfirewalldを使って簡単に設定をしてみよう。

firewalld.org

aptでインストール

bookstore@bookstoreUbuntu:~$ sudo apt install firewalld
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  firewalld
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
342 kB のアーカイブを取得する必要があります。
この操作後に追加で 2,362 kB のディスク容量が消費されます。
取得:1 http://jp.archive.ubuntu.com/ubuntu focal/universe amd64 firewalld all 0.8.2-1 [342 kB]
342 kB を 1秒 で取得しました (651 kB/s)
以前に未選択のパッケージ firewalld を選択しています。
(データベースを読み込んでいます ... 現在 269818 個のファイルとディレクトリがインストールされています。)
.../firewalld_0.8.2-1_all.deb を展開する準備をしています ...
firewalld (0.8.2-1) を展開しています...
firewalld (0.8.2-1) を設定しています ...
update-alternatives: /usr/share/polkit-1/actions/org.fedoraproject.FirewallD1.policy (org.fedoraproject.FirewallD1.policy) を提供するために自動モードで /usr/share/polkit-1/actions/org.fedoraproject.FirewallD1.server.policy.choice を使います
man-db (2.9.1-1) のトリガを処理しています ...
ureadahead (0.100.0-21) のトリガを処理しています ...
ureadahead will be reprofiled on next reboot
dbus (1.12.16-2ubuntu2.1) のトリガを処理しています ...
systemd (245.4-4ubuntu3.2) のトリガを処理しています ...

インストールが完了したらサービスも起動する。

bookstore@bookstoreUbuntu:~$ systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-09-20 18:09:41 JST; 1min 38s ago
       Docs: man:firewalld(1)
   Main PID: 4110 (firewalld)
      Tasks: 2 (limit: 19011)
     Memory: 24.7M
     CGroup: /system.slice/firewalld.service
             └─4110 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid

 9月 20 18:09:41 bookstoreUbuntu systemd[1]: Starting firewalld - dynamic firewall daemon...
 9月 20 18:09:41 bookstoreUbuntu systemd[1]: Started firewalld - dynamic firewall daemon.

Firewalldを設定

firewalld concepts

firewalldにはfirwalldデーモンと対話するツールが用意されている。上に載せたリンク先のページの上部にあるのそのツール。firewall-cmdを使うとコマンドラインで設定を行うことができる。他にもツールが用意されていらけれどGUI用らしい。

どのコマンドもfirewalldデーモンとD-Busを使ってやりとりする。D-BusAPIリファレンスはここに載ってた。

firewalld dbus

firewall-cmdをつかってzoneを設定していく。zoneというのはその接続に対する信頼レベルでネットワークインターフェースごとに設定できる。詳細はこちら。

firewalld zones

zoneは事前に設定されているものの中から選ぶこともできるし、自分で作ることもできるらしい。事前に設定されているものはこんな感じで表示できる。

root@bookstoreUbuntu:/home/bookstore# 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 (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp5s0
  sources:
  services: dhcpv6-client mdns samba-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

(以下略)

zoneを切り替えてみる。

root@bookstoreUbuntu:/home/bookstore# firewall-cmd --get-active-zones
dmz
  interfaces: enp5s0
root@bookstoreUbuntu:/home/bookstore# firewall-cmd --set-default-zone=home
success
root@bookstoreUbuntu:/home/bookstore# firewall-cmd --get-active-zones
home
  interfaces: enp5s0

enp5s0インターフェースがdmzからhomeに切り替わった。

zoneにはサービスを関連付けることでどういった通信を許可・拒否するかを定義できる。

firewall service

zoneごとに使用できるサービスはこんな感じで確認できる。

root@bookstoreUbuntu:/home/bookstore# firewall-cmd --zone=dmz --list-services
ssh
root@bookstoreUbuntu:/home/bookstore# firewall-cmd --zone=home --list-services
dhcpv6-client mdns samba-client ssh

zoneは自分で定義することもできる。というわけで特定の送信元からはhttpを許可するzoneを作って割り当ててみようと思う。firewall-cmdだけをつかってもできるんだけど、分かりづらい&設定のバックアップがやりづらいのでXMLのファイルを使って設定をしていこう。

firewalldには設定ファイルを置いておく場所が2つある。

  • /etc/firewalld/ ... ユーザが個別に設定したフィルを置いておくディレクト
  • /usr/lib/firewalld/ ... インストール時点での初期設定が置かれているディレクト
root@bookstoreUbuntu:/home/bookstore# ls /etc/firewalld/
firewalld.conf  firewalld.conf.old  helpers  icmptypes  ipsets  lockdown-whitelist.xml  services  zones
root@bookstoreUbuntu:/home/bookstore# ls /usr/lib/firewalld/
helpers  icmptypes  ipsets  services  zones

設定ファイルを1から作るのではなく、既存の設定ファイルをコピーして個別にカスタマイズするといいと思う。というわけで、home.xmlをもとにカスタマイズする。

root@bookstoreUbuntu:/home/bookstore# cp /usr/lib/firewalld/zones/home.xml /etc/firewalld/zones

firewalldは設定ファイル名をzone名として認識するので、既存のhome設定をコンフリクトしないように名前を変えておこう。

root@bookstoreUbuntu:/home/bookstore# mv /etc/firewalld/zones/home.xml /etc/firewalld/zones/home_custom.xml

home_custom.xmlを編集する。ルールを追加して特定のソースアドレスにはhttp通信を許可する。

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Home with http</short>
  <description>custom home zone</description>
  <service name="ssh"/>
  <service name="mdns"/>
  <service name="samba-client"/>
  <service name="dhcpv6-client"/>

  <rule family="ipv4">
    <source address="192.168.50.126"/>
    <service name="http"/>
    <accept/>
  </rule>

</zone>

firewallを一度リロードする。

root@bookstoreUbuntu:/home/bookstore# firewall-cmd --reload
success

ただしくzone設定ができているとzone一覧で表示される。

home_custom
  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:
    rule family="ipv4" source address="192.168.50.126" service name="http" accept

あとはこれを割り当てるだけ。

root@bookstoreUbuntu:/home/bookstore# firewall-cmd --set-default-zone=home_custom
success

これで設定が有効になった。

試しにnmapを使ってfirewallの設定が正しく反映されているかを確認してみる。

 ~/D/temp  sudo nmap 192.168.50.35
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-21 19:33 JST
Nmap scan report for bookstoreUbuntu (192.168.50.35)
Host is up (0.0022s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
MAC Address: BC:5F:F4:97:FD:29 (ASRock Incorporation)

Nmap done: 1 IP address (1 host up) scanned in 5.85 seconds

Not shown: 998 filtered ports から998のポートが閉じられている(応答なし)のがわかる。sshとhttpのポートは開いている。