同じネットワークの中にいるパソコンからも攻撃を受けるケースもあるので、iptablesを使ってRaspberry Pi にファイアウォールを設定します。
WordPress専用で使用するので、WEBサーバに必要な通信以外は全て遮断します。
- WEBサーバで受信を許可する通信(ポート番号)
- Teraterm(SSH)で使用するTCPのポート番号23
- WEB(HTTP)で使用するTCPのポート番号80
- WEBサーバからインターネットに送信する通信(ポート番号)
- 全て許可
- ネットワークは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からの反応が無くなります。
ファイアウォールが、ブラウザの要求を廃棄しているからです。
これでファイアウォールが機能している事が確認できました。
さあ、設定ファイルを元に戻して再起動しましょう。
お疲れ様です。