【conoha VPS AlmaLinux9構築④】セキュリティ設定 その2

AlmaLinux9

nftables設定

firewalldは非推奨となりましたので、nftablesでフィルタリング設定を実施します

IPアドレスリスト作成

以下3つのIPアドレスリストを用意します
firewalldだとゾーンに該当するものです

①admin
管理用端末のIPアドレスを設定する
ssh、web管理画面等、管理者のみ許可するために使用

②domestic
国内IPアドレスを設定する
現状メールを見るときは国内からしか見ないのでimapsとsmtpsを国内でのみ許可するのに使用

まずはリストを格納するディレクトリを作成します

# mkdir /etc/nftables/list

リストを作成します
コメントだけの行はエラーになるそうなので、コメントは下記のようにIPアドレスの後ろに記入します

# vi /etc/nftables/list/admin
define admin = {
        xxx.xxx.xxx.xxx  # 管理用IPアドレス
}

日本国内IPアドレスを取得して、IPアドレスリストを作成するスクリプトを作成します

# vi nftables_domestic.sh
#!/bin/bash
 
LIST=/etc/nftables/list/domestic

cd /etc/nftables/list
wget http://nami.jp/ipv4bycc/cidr.txt.gz
gunzip cidr.txt.gz
echo "define domestic = {" > ${LIST}
for COUNTRY in 'JP'
do
    sed -n "s/^JP\t//p" cidr.txt | while read ADDRESS
    do
        echo "        ${ADDRESS}," >> ${LIST}
    done
done
echo "}" >> ${LIST}
rm cidr.txt

作成したスクリプトを実行します

# chmod 700 nftables_domestic.sh

# sh nftables_domestic.sh

# ls /etc/nftables/list
admin  domestic ←domesticが追加されていることを確認する

テーブル作成

# vi /etc/nftables/filter.nft
# 現在のルールセットを消去
flush ruleset
 
# 管理者用IPアドレスリストを読み込む
include "/etc/nftables/list/admin"
# 日本国内IPアドレスリストを読み込む
include "/etc/nftables/list/domestic"
 
table inet filter {
 
        set admin {
                type ipv4_addr
                elements = $admin
        }
 
        set domestic {
                type ipv4_addr
                flags interval
                elements = $domestic
        }
 
        chain input {
                type filter hook input priority 0; policy drop;
 
                # Ping floods
                ip protocol icmp icmp type echo-request limit rate 10/second accept
 
                # 関連・確立済みトラフィックは許可する
                ct state established,related accept
 
                # 不正なトラフィックは全て破棄する
                ct state invalid drop
 
                # ループバックインターフェイスのトラフィックは全て許可する
                iif lo accept
 
                # 新しいエコー要求 (ping) は許可する
                ip protocol icmp icmp type echo-request ct state new accept
 
                ip protocol udp ct state new jump UDP
                ip protocol tcp tcp flags & (fin | syn | rst | ack) == syn ct state new jump TCP
 
                # 他のルールによって処理されなかったトラフィックは全て拒否する
                ip protocol udp reject
                ip protocol tcp reject with tcp reset
        }
 
        chain forward {
                type filter hook forward priority 0; policy drop;
        }
 
        chain output {
                type filter hook output priority 0; policy accept;
        }
 
        chain TCP {
                # 管理者にのみ解放
                # ssh, OLS 管理画面
                tcp dport { 22 } ip saddr @admin accept
 
                # 日本国内にのみ開放
                # SMTPS, IMAPS
                tcp dport { 465, 993 } ip saddr @domestic accept
 
                # 全開放
                # SMTP, HTTP, HTTPS
                tcp dport { 25, 80, 443 } accept
        }
 
        chain UDP {
                # 全開放
                # http/3
                #udp dport { 443 } accept
        }
 
}

domesticは「flags interval」を入れることでIPアドレス範囲指定できるようにしています

filter.nftの設定を読み込むようにconfigを修正します

# vi /etc/sysconfig/nftables.conf

#include "/etc/nftables/main.nft"
include "/etc/nftables/filter.nft" ←追記

サービス起動

firewalldが起動している場合は終了します

# systemctl stop firewalld
# systemctl disable firewalld

nftablesを起動します

# systemctl start nftables
# systemctl enable nftables

fail2ban設定

設定方針

・会社や自宅のIPアドレスはbanされないようにする
・30分間で3回アクセス失敗したIPアドレスは1時間アクセスを禁止
・1日に3回BANされたIPアドレスは永久BANする
・BANされたIPアドレスのWHOIS情報をメール送信する

設定

fail2banはすでにインストールされていたので、whoisのみインストールします

dnf install whois

jail.confは直接いじらずに、jail.localを編集します
デフォルトだとiptablesが使用されてしまうので、nftablesが使用されるように設定を変更します
ban設定しているサービスは例なので、適宜環境によって変えてください

# vi /etc/fail2ban/jail.local

[DEFAULT]
###基本設定###
##会社や自宅IPアドレスの除外##
backend  = systemd
ignoreip = 127.0.0.1 xxx.xxx.xxx.xxx ←IPアドレスを指定

##nftablesを使用##
banaction = nftables-multiport
banaction_allports = nftables-allports

##メール設定##
destemail  = xxxxxxxx@xxxxxx.com ←送信先
sender     = fail2ban@xxxxxx.com ←送信元、分かりやすいように@前はfail2banとした

##BANされたIPアドレスのWHOIS情報をメール送信##
action  = %(action_mw)s

###BAN設定###
##30分間で3回アクセス失敗したIPアドレスは1時間アクセス禁止##
bantime  = 3600
findtime = 1800
maxretry = 3

##1日間に3回BANされたIPアドレスは永久BAN設定##
[recidive]
enabled  = true
bantime  = -1
findtime = 86400
maxretry = 3

[sshd]
enabled = true

[postfix]
enabled  = true
port     = smtp,smtps

[dovecot]
enabled = true
port    = smtp,smtps,imap,imaps,sieve

[postfix-sasl]
enabled  = true
port     = smtp,smtps,imap,imaps

サービス起動

fail2banを起動した状態でnftablesだけ再起動すると下記のようなエラーが出てしまい、banが機能しなくなってしまいます

[2084]: ERROR   Failed to stop jail 'sshd' action 'nftables-multiport': Error stopping action 
[2084]: ERRORJail('sshd')/nftables-multiport: 'Script error' Failed to execute unban jail 'sshd' action 'nftables-multiport' info 'ActionInfo({'ip': '210.xxx.xxx.xxx', 'family': 'inet4', 'fid': <function Actions.ActionInfo.<lambda> at 0x7f1842141670>, 'raw-ticket': <function Actions.ActionInfo.<lambda> at 0x7f1842141d30>})': Error unbanning 210.xxx.xxx.xxx

これを回避するために、fail2ban起動時の依存関係を設定します

# systemctl edit fail2ban

### Editing /etc/systemd/system/fail2ban.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

↓↓↓↓↓↓↓↓↓↓↓↓↓入力する内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓
[Unit]
Requires=nftables.service
PartOf=nftables.service

[Install]
WantedBy=multi-user.target nftables.service
↑↑↑↑↑↑↑↑↑↑↑↑↑入力する内容↑↑↑↑↑↑↑↑↑↑↑↑↑↑

### Lines below this comment will be discarded


nanoエディタ普段使わないので、使いづらいですね
入力後、Ctrl+Oで書き込みを行います
その際、ファイル名が「.#override.confxxxxxxx」といった名前で表示されますが、そのままエンターで保存します

fail2banを起動します

# systemctl start fail2ban
# systemctl enable fail2ban

動作確認

sshを一時的に管理用IPアドレス以外でもアクセスできるよう設定します

# vi /etc/nftables/filter.nft
# 現在のルールセットを消去
flush ruleset

(略)
 
        chain TCP {
                # 管理者にのみ解放
                # ssh, OLS 管理画面
                tcp dport 22 ip saddr @admin accept
 
                # 日本国内にのみ開放
                # SMTPS, IMAPS
                tcp dport { 465, 993 } ip saddr @domestic accept
 
                # 全開放
                # SMTP, HTTP, HTTPS
                tcp dport { 22, 25, 80, 443 } accept ←ここに22を追加します
        }
 
(略)

nftablesを起動します

# systemctl start nftables
# systemctl enable nftables

banされるIPが出るまで待ちます

(‘ω’) < アタックされるまで暇やな… )

banされたIPがあると下記コマンド実行時に「f2b-table」が自動作成されるので、定期的にコマンド実行して確認します
※ まだbanされたIPがない場合はf2b-tableは作成されません

# nft list tables
table inet filter
table inet f2b-table


テーブルが作成されたら、f2b-tableの中身を確認します
下記の通り211.xxx.xxx.xxx.xxxに対してport22通信をrejectする設定となったことがわかります

# nft list table inet f2b-table
table inet f2b-table {
        set addr-set-sshd {
                type ipv4_addr
                elements = { 211.xxx.xxx.xxx } ←banされたIPアドレス
        }

        chain f2b-chain {
                type filter hook input priority filter - 1; policy accept;
                tcp dport 22 ip saddr @addr-set-sshd reject with icmp port-unreachable
        }
}

忘れずにnftables設定を戻します

# vi /etc/nftables/filter.nft
# 現在のルールセットを消去
flush ruleset

(略)
 
        chain TCP {
                # 管理者にのみ解放
                # ssh, OLS 管理画面
                tcp dport 22 ip saddr @admin accept
 
                # 日本国内にのみ開放
                # SMTPS, IMAPS
                tcp dport { 465, 993 } ip saddr @domestic accept
 
                # 全開放
                # SMTP, HTTP, HTTPS
                tcp dport { 25, 80, 443 } accept ←22を削除します
        }
 
(略)

nftablesを再起動します

# systemctl start nftables
# systemctl enable nftables

参考

Red Hat Enterprise Linux 9 のファイヤーウォール設定 | Psychoco Laboratory
nftablesでSSHを日本国内からの接続に限定する (CentOS 8) | 稲葉サーバーデザイン (inaba-serverdesign.jp)
Debian 10 + nftables + fail2ban – 発声練習 (hatenadiary.jp)

コメント

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