ファイアウォールの設定

iptables
iptables

同じネットワークの中にいるパソコンからも攻撃を受けるケースもあるので、iptablesを使ってRaspberry Pi にファイアウォールを設定します。

WordPress専用で使用するので、WEBサーバに必要な通信以外は全て遮断します。

  1. WEBサーバで受信を許可する通信(ポート番号)
    • Teraterm(SSH)で使用するTCPのポート番号23
    • WEB(HTTP)で使用するTCPのポート番号80
  2. WEBサーバからインターネットに送信する通信(ポート番号)
    • 全て許可
  3. ネットワークはIPv4のみ使用。

iptablesのインストール

ファイアウォール本体のiptablesをインストールします。

$ sudo apt-get install iptables
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libip6tc2 libnetfilter-conntrack3 libnfnetlink0
Suggested packages:
  firewalld
The following NEW packages will be installed:
  iptables libip6tc2 libnetfilter-conntrack3 libnfnetlink0
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 452 kB of archives.
After this operation, 2,313 kB of additional disk space will be used.
Do you want to continue? [Y/n] y          <=yを入力
Get:1 http://deb.debian.org/debian bullseye/main arm64 libip6tc2 arm64 1.8.7-1 [34.3 kB]
Get:2 http://deb.debian.org/debian bullseye/main arm64 libnfnetlink0 arm64 1.0.1-3+b1 [12.0 kB]
Get:3 http://deb.debian.org/debian bullseye/main arm64 libnetfilter-conntrack3 arm64 1.0.8-3 [38.2 kB]
Get:4 http://deb.debian.org/debian bullseye/main arm64 iptables arm64 1.8.7-1 [368 kB]
Fetched 452 kB in 0s (1,513 kB/s)
Selecting previously unselected package libip6tc2:arm64.
(Reading database ... 42423 files and directories currently installed.)
Preparing to unpack .../libip6tc2_1.8.7-1_arm64.deb ...
Unpacking libip6tc2:arm64 (1.8.7-1) ...
Selecting previously unselected package libnfnetlink0:arm64.
Preparing to unpack .../libnfnetlink0_1.0.1-3+b1_arm64.deb ...
Unpacking libnfnetlink0:arm64 (1.0.1-3+b1) ...
Selecting previously unselected package libnetfilter-conntrack3:arm64.
Preparing to unpack .../libnetfilter-conntrack3_1.0.8-3_arm64.deb ...
Unpacking libnetfilter-conntrack3:arm64 (1.0.8-3) ...
Selecting previously unselected package iptables.
Preparing to unpack .../iptables_1.8.7-1_arm64.deb ...
Unpacking iptables (1.8.7-1) ...
Setting up libip6tc2:arm64 (1.8.7-1) ...
Setting up libnfnetlink0:arm64 (1.0.1-3+b1) ...
Setting up libnetfilter-conntrack3:arm64 (1.0.8-3) ...
Setting up iptables (1.8.7-1) ...
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/iptables-nft to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-nft to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/arptables-nft to provide /usr/sbin/arptables (arptables) in auto mode
update-alternatives: using /usr/sbin/ebtables-nft to provide /usr/sbin/ebtables (ebtables) in auto mode
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u3) ...

iptableは指示された内容に基づきファイアウォールの機能を実現しますが、指示された内容を記憶はしません。

そこで、サーバを起動したとき、設定ファイルに基づきiptableに指示を出してファイアウォールの機能を実現させるのが下記のiptables-persistentです。

インストールする時に、IPv4とIPv6それぞれどのプロトコルに指示をするか聞いてくるので、IPv4のみを指示してインストールします。

$ sudo apt-get install iptables-persistent
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  netfilter-persistent
The following NEW packages will be installed:
  iptables-persistent netfilter-persistent
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 23.4 kB of archives.
After this operation, 91.1 kB of additional disk space will be used.
Do you want to continue? [Y/n] y          <=yを入力
Get:1 http://deb.debian.org/debian bullseye/main arm64 netfilter-persistent all 1.0.15 [11.0 kB]
Get:2 http://deb.debian.org/debian bullseye/main arm64 iptables-persistent all 1.0.15 [12.4 kB]
Fetched 23.4 kB in 0s (92.7 kB/s)
Preconfiguring packages ...

Package configuration
 lqqqqqqqqqqqqqqqqqqqqu Configuring iptables-persistent tqqqqqqqqqqqqqqqqqqqqk
 x                                                                           x
 x Current iptables rules can be saved to the configuration file             x
 x /etc/iptables/rules.v4. These rules will then be loaded automatically     x
 x during system startup.                                                    x
 x                                                                           x
 x Rules are only saved automatically during package installation. See the   x
 x manual page of iptables-save(8) for instructions on keeping the rules     x
 x file up-to-date.                                                          x
 x                                                                           x
 x Save current IPv4 rules?                                                  x
 x                                                                           x
 x                    <Yes>    <=Yesを選択       <No>                       x
 x                                                                           x
 mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

Package configuration
 lqqqqqqqqqqqqqqqqqqqqu Configuring iptables-persistent tqqqqqqqqqqqqqqqqqqqqk
 x                                                                           x
 x Current iptables rules can be saved to the configuration file             x
 x /etc/iptables/rules.v6. These rules will then be loaded automatically     x
 x during system startup.                                                    x
 x                                                                           x
 x Rules are only saved automatically during package installation. See the   x
 x manual page of ip6tables-save(8) for instructions on keeping the rules    x
 x file up-to-date.                                                          x
 x                                                                           x
 x Save current IPv6 rules?                                                  x
 x                                                                           x
 x                    <Yes>                       <No>    <=Noを選択        x
 x                                                                           x
 mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
Preparing to unpack .../libip6tc2_1.8.7-1_arm64.deb ...
Unpacking libip6tc2:arm64 (1.8.7-1) ...
Selecting previously unselected package libnfnetlink0:arm64.
Preparing to unpack .../libnfnetlink0_1.0.1-3+b1_arm64.deb ...
Unpacking libnfnetlink0:arm64 (1.0.1-3+b1) ...
Selecting previously unselected package libnetfilter-conntrack3:arm64.
Preparing to unpack .../libnetfilter-conntrack3_1.0.8-3_arm64.deb ...
Unpacking libnetfilter-conntrack3:arm64 (1.0.8-3) ...
Selecting previously unselected package iptables.
Preparing to unpack .../iptables_1.8.7-1_arm64.deb ...
Unpacking iptables (1.8.7-1) ...
Setting up libip6tc2:arm64 (1.8.7-1) ...
Setting up libnfnetlink0:arm64 (1.0.1-3+b1) ...
Setting up libnetfilter-conntrack3:arm64 (1.0.8-3) ...
Setting up iptables (1.8.7-1) ...
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/ipta
update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6
update-alternatives: using /usr/sbin/iptables-nft to provide /usr/sbin/iptable
update-alternatives: using /usr/sbin/ip6tables-nft to provide /usr/sbin/ip6tab
update-alternatives: using /usr/sbin/arptables-nft to provide /usr/sbin/arptab
update-alternatives: using /usr/sbin/ebtables-nft to provide /usr/sbin/ebtable
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u3) ...
Selecting previously unselected package netfilter-persistent.stent
(Reading database ... 42643 files and directories currently installed.)
Preparing to unpack .../netfilter-persistent_1.0.15_all.deb ...
Unpacking netfilter-persistent (1.0.15) ...
Selecting previously unselected package iptables-persistent.
Preparing to unpack .../iptables-persistent_1.0.15_all.deb ...
Unpacking iptables-persistent (1.0.15) ...
Setting up netfilter-persistent (1.0.15) ...
Created symlink /etc/systemd/system/multi-user.target.wants/netfilter-persistent                                                                               .service → /lib/systemd/system/netfilter-persistent.service.
Setting up iptables-persistent (1.0.15) ...
update-alternatives: using /lib/systemd/system/netfilter-persistent.service to p                                                                               rovide /lib/systemd/system/iptables.service (iptables.service) in auto mode
Processing triggers for man-db (2.9.4-2) ...

ファイアウォールの設定

インターネットから飛んでくる下記のポート番号以外全て廃棄するよう設定します。

  • Teraterm(SSH)で使用するTCPのポート番号23
  • WEB(HTTP)で使用するTCPのポート番号80

設定は下記のファイルにします。

$ sudo vi /etc/iptables/rules.v4

設定内容はコメント(行頭に#が入っている行)を参照ください。

# ポリシーの設定 OUTPUTのみACCEPTにする
*filter
:INPUT   DROP   [0:0]
:FORWARD DROP   [0:0]
:OUTPUT  ACCEPT [0:0]

# ループバック(自分自身からの通信)を許可する
-A INPUT -i lo -j ACCEPT

# データを持たないパケットの接続を破棄する
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# SYNflood対策
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# ステルススキャン対策
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# icmp(ping)の設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# -hashlimit-name t_icmp  記録するファイル名
# -hashlimit 1/m               リミット時には1分間に1パケットを上限とする
# -hashlimit-burst 10        規定時間内に10パケット受信すればリミットを有効にする
# -hashlimit-mode srcip    ソースIPを元にアクセスを制限する
# -hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_icmp --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# 確立済みの通信は、ポート番号に関係なく許可する
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

# 任意DNSアクセスの戻りパケットを受け付ける
-A INPUT -p udp --sport 53 -j ACCEPT

# SSHを許可する設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# -hashlimit-name t_sshd 記録するファイル名
# -hashlimit 1/m              リミット時には1分間に1パケットを上限とする
# -hashlimit-burst 10       規定時間内に10パケット受信すればリミットを有効にする
# -hashlimit-mode srcip   ソースIPを元にアクセスを制限する
# -hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p tcp -m state --syn --state NEW --dport 22 -m hashlimit --hashlimit-name t_sshd --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# 個別に許可するプロトコルとポートをここに書き込む。
# この例では、HTTP(TCP 80)
-A INPUT -p tcp --dport 80   -j ACCEPT
# -A INPUT -p tcp --dport 443  -j ACCEPT

COMMIT

設定した内容が合ってるか確認するため、下記コマンドでiptableに適用します。

エラーが出なければOKです。

$ sudo iptables-apply /etc/iptables/rules.v4
Applying new iptables rules from '/etc/iptables/rules.v4'... done.
Can you establish NEW connections to the machine? (y/N) y         <=yを入力
... then my job is done. See you next time.

iptablesに指示されている内容を下記コマンドで確認します。

$ sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request limit: up to 1/min burst 10 mode srcip htable-expire 120000
ACCEPT     tcp  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     udp  --  anywhere             anywhere             udp spt:domain
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN limit: up to 1/min burst 10 mode srcip htable-expire 120000
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Teraterm(SSH)で、新しくログインできれば大丈夫です。

また、ブラウザからのWordPressのアクセスに何ら影響がなければ大丈夫です。

さあ、Raspberry Piを再起動して再度確認します。

$ sudo reboot

Raspberry Piが再起動したら、下記コマンドでファイアウォールの機能が有効か確認します。

下記内容が表示されれば機能しています。

$ sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request limit: up to 1/min burst 10 mode srcip htable-expire 120000
ACCEPT     tcp  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     udp  --  anywhere             anywhere             udp spt:domain
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN limit: up to 1/min burst 10 mode srcip htable-expire 120000
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Teraterm(SSH)での新しくログインして問題なければ大丈夫です。

ブラウザからのWordPressのアクセスに何ら影響がなければ大丈夫です。

これで、ファイアウォールの設定は完了です。

ファイアウォールのテスト

さて、本当にファイアウォールの機能が本当に機能しているか試してみたいと思います。

今、ブラウザからWordPressにアクセスできていると思いますが、このブラウザからのアクセスを廃棄するように設定します。

ファイアウォールの設定を変更します。

$ sudo vi /etc/iptables/rules.v4
# ポリシーの設定 OUTPUTのみACCEPTにする
*filter
:INPUT   DROP   [0:0]
:FORWARD DROP   [0:0]
:OUTPUT  ACCEPT [0:0]

# ループバック(自分自身からの通信)を許可する
-A INPUT -i lo -j ACCEPT

# データを持たないパケットの接続を破棄する
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# SYNflood対策
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# ステルススキャン対策
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# icmp(ping)の設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# -hashlimit-name t_icmp  記録するファイル名
# -hashlimit 1/m               リミット時には1分間に1パケットを上限とする
# -hashlimit-burst 10        規定時間内に10パケット受信すればリミットを有効にする
# -hashlimit-mode srcip    ソースIPを元にアクセスを制限する
# -hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_icmp --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# 確立済みの通信は、ポート番号に関係なく許可する
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

# 任意DNSアクセスの戻りパケットを受け付ける
-A INPUT -p udp --sport 53 -j ACCEPT

# SSHを許可する設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# -hashlimit-name t_sshd 記録するファイル名
# -hashlimit 1/m              リミット時には1分間に1パケットを上限とする
# -hashlimit-burst 10       規定時間内に10パケット受信すればリミットを有効にする
# -hashlimit-mode srcip   ソースIPを元にアクセスを制限する
# -hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p tcp -m state --syn --state NEW --dport 22 -m hashlimit --hashlimit-name t_sshd --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# 個別に許可するプロトコルとポートをここに書き込む。
# この例では、HTTP(TCP 80)
# -A INPUT -p tcp --dport 80   -j ACCEPT
# -A INPUT -p tcp --dport 443  -j ACCEPT

COMMIT

設定ファイルの赤い行の通り、HTTP(80)のポートを許可していた行をコメント(行頭に#を挿入)にします。

Raspberry Piを再起動して確認を行います。

$ sudo reboot

Raspberry Piが起動したら、ブラウザでWordPressにアクセスしてください。

これまでと違い、Raspberry Piからの反応が無くなります。

ファイアウォールが、ブラウザの要求を廃棄しているからです。

これでファイアウォールが機能している事が確認できました。

ももぶろ
ももぶろ

さあ、設定ファイルを元に戻して再起動しましょう。

お疲れ様です。

タイトルとURLをコピーしました