今回は、これまで使っていた管理ツールであるUFWをアンインストールし、nftablesへ移行した。
UFWは手軽だが、その実体はPythonで動いている。対してnftablesは、Linuxカーネルのパケット処理エンジンを直接動かす。余計なツールを挟まずによりシンプルな構成が作れる。
ufwとは
UFW(Uncomplicated Firewall)は、Linuxで動作するパケットフィルタリング(通信制限)を簡単に管理するためのツールだ。本来、Linuxカーネルが持つ複雑な防火壁の仕組みを、短いコマンドで直感的に操作できる。
ちなみにGUFWは、コマンド操作のUFWを、画面上のマウス操作だけで扱えるようにしたグラフィカルな管理ツールだ。複雑なコマンドを覚える必要がなく、スイッチを切り替えるような感覚で防壁のオンとオフを制御できる。
デスクトップ環境でセキュリティを管理したいなら手軽だが、サーバーのように画面がない環境や、ミニマルな構成を目指すならインストールせずにCUIで管理するのが一般的だ。
設定ファイルを書く手間が省けるため、Ubuntuなどの主要な配布版で標準採用されている。特定のポートを開けたり、特定の接続元を拒否したりする作業が数秒で完了する。専門知識がなくても、ネットワークの安全性をすぐに高められるのが最大の特徴だ。
その実体はPythonで書かれた「管理用の表層ツール」に過ぎない。動作の裏側では、別の古い仕組みであるiptablesを呼び出して通信を制御している。システムを極限まで軽くしたい場合や、最新の制御エンジンを直接動かしたいときには物足りない。
nftableとは
nftablesは、Linuxカーネルに組み込まれた最新のパケットフィルタリング(通信制御)基盤だ。長年使われてきたiptablesや、その簡易版であるUFWの後継として開発された。
最大の特徴は、IPv4とIPv6、さらにブリッジなどの通信を一括で管理できる点にある。従来のツールでは、通信の種類ごとに別々のコマンドや設定ファイルが必要だったが、nftablesなら「inet」という枠組みで効率よく記述できる。
また、設定がカーネル内で直接実行されるため、動作が非常に速い。Pythonなどの外部プログラムを介さず、OSが立ち上がると同時に防壁が機能する。設定ファイルも直感的な構文で書けるため、複雑なネットワーク条件も一行でスマートに表現できる。
nftablesに移行する際のメリット
システム管理をUFWからnftablesへ切り替えると、ネットワーク制御の仕組みが根本から効率化される。これまでツールを介して行っていた操作を、OSの中核機能で直接実行できるようになるからだ。
記述がスマートで読みやすい
nftablesの最大の利点は、設定ファイルの可読性が圧倒的に高い点にある。UFWでは複数のコマンドに分かれていたルールも、一行でまとめて記述できる。たとえば、複数のポート開放を「udp dport { 137, 138 }」のように中括弧で括るだけで済む。
また、IPv4とIPv6を「inet」という共通のファミリーで一括管理できる。同じルールを二回書く手間が省け、設定ミスも起こりにくくなる。
動作が速くリソースを消費しない
UFWのようなPython製のフロントエンドを介さず、カーネル内でルールが直接読み込まれる。そのため、OSの起動と同時に防壁が機能し始め、起動直後の無防備な時間を最小限に抑えられる。
余計な常駐プログラムを減らせるため、メモリ消費量もわずかに抑えられる。システム全体の「純度」を高め、ネットワーク処理を常にスムーズな状態で維持できる。
UFWを停止して nftablesを導入する具体的な手順
既存の防御壁を安全に取り除き、新しい仕組みへと切り替える。作業は慎重に進めるが、手順自体は非常にシンプルだ。
1. UFWを停止し削除する
まずは動作中のUFWを止め、自動起動の設定も解除する。その後、パッケージごと削除してシステムを真っ新な状態に戻す。
# UFWを停止して無効化する
sudo ufw disable
# パッケージを削除する(Ubuntu/Debian系の場合)
sudo apt purge ufw
2. nftablesを導入する
次に、新しい制御エンジンであるnftablesをインストールする。OSごとにパッケージ管理コマンドを使い分けて導入する。
# Void Linuxの場合
sudo xbps-install -S nftables
# Ubuntu/Debian系の場合
sudo apt update
sudo apt install nftables
3. 設定ファイルの一括書き込み
以下のコマンドをコピーして実行すると、現在のUFWルールを再現した設定ファイルが作成される。LAN内通信の許可やKDE Connect、Sambaなどの必要なポートを網羅している。
sudo tee /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# ループバックを許可
iif "lo" accept
# 確立済みの通信を維持
ct state established,related accept
# 1. LAN内からの通信を全許可
ip saddr 192.168.1.0/24 accept
# 2. KDE Connect (TCP/UDP 1714-1764)
tcp dport 1714-1764 accept
udp dport 1714-1764 accept
# 3. Syncthing
tcp dport 22000 accept
udp dport { 22000, 21027 } accept
# 4. Samba
udp dport { 137, 138 } accept
tcp dport { 139, 445 } accept
# 5. SSH (22) を拒否
tcp dport 22 drop
# ICMP (ping) 許可
icmp type echo-request accept
icmpv6 type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
4. nftablesを有効化する
最後に、システム起動時に自動でルールが読み込まれるよう設定する。使っているOSの管理方式に合わせてコマンドを選択する。
# Ubuntu/Debian系 (systemd) の場合
sudo systemctl enable --now nftables
# Void Linux (runit) の場合
sudo ln -s /etc/sv/nftables /var/service/
sudo nft list ruleset で設定が正しくできたか確認できる。これで、無駄のない強固な防壁が完成する。
fail2ban との連携
外部に公開しているサーバーやPCを守る際、パスワードを何度も間違えて侵入を試みる攻撃への対策は欠かせない。そこで役立つのがfail2banだ。
fail2banとは
fail2banは、ログファイルを監視して不正なアクセスを繰り返す接続元を自動で遮断するツールだ。たとえば、SSHやWebサービスに対して短時間に何度もログインに失敗したIPアドレスを検知し、あらかじめ決めた時間だけその通信を拒否する。
手動でIPアドレスを調べてブロックする手間が省け、総当たり攻撃(ブルートフォースアタック)のリスクを大幅に下げられる。サーバーの玄関先に「怪しい動きをする者を自動で締め出す門番」を立たせるような仕組みだ。
nftablesとfail2banを連携させる設定
fail2banは、不正なアクセスを検知して「犯人のIPアドレスを遮断ルールに放り込む」役割を持つ。一方で、実際に通信をブロックする「壁」の役割を果たすのがnftablesだ。
この二つを連携させると、fail2banが捕まえた攻撃者の情報を、nftablesのルールセットの中に直接書き込めるようになる。
だが、軽量なnftablesへ移行しても、fail2banが古いiptablesを操作しようとすると設定が噛み合わない。両者を正しく連携させれば、すべてのルールをnftables側で一元管理できるようになる。
fail2banの設定を切り替える
fail2banは標準でiptablesを使おうとする。これをnftables専用の動作に変更するには、設定ファイル(jail.local)で動作を指定する。
この設定を行うことで、fail2banが検知した不正なIPアドレスは、nftablesの中に専用のテーブル(f2b-table)を作って格納されるようになる。翻訳層を通さないため、管理が非常にスムーズだ。
# jail.localを作成してnftablesを指定する
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# nftablesを直接操作するように指定
banaction = nftables-multiport
banaction_allports = nftables-allports
[sshd]
enabled = true
port = ssh
EOF
# 設定を反映させる(Void Linux/runitの場合)
sudo sv restart fail2ban
# systemdの場合
sudo systemctl restart fail2ban
連携がうまくいっているか確認する
設定が済んだら、実際に正しく動くかテストする。自分のIPを間違えてロックアウトされないよう、架空のIPアドレスを使って動作を確認する。
# 1. テスト用に架空のIPをBANしてみる
sudo fail2ban-client set sshd banip 1.2.3.4
# 2. nftablesの中に反映されているか見る
sudo nft list ruleset
# 3. テストが終わったら解除する
sudo fail2ban-client set sshd unbanip 1.2.3.4
sudo nft list ruleset を実行したとき、結果の中に table inet f2b-table という項目が現れれば連携は成功だ。これで、手動の設定と自動の遮断ルールがひとつの画面ですべて把握できる。
jail.local を書き換えて nftables を直接操作する手順
fail2ban が検知した不正な IP アドレスを、直接 nftables のルールセットに放り込むように設定を変更する。これで iptables などの互換ツールを介さずに、カーネルレベルで効率よく遮断できるようになる。
1. jail.local ファイルを作成・編集する
設定の競合を防ぐため、元の jail.conf は触らずに jail.local を新規作成して上書き設定を書き込む。
# 設定ファイルを新規作成、または追記する
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# nftablesを直接操作するアクションを指定
banaction = nftables-multiport
banaction_allports = nftables-allports
[sshd]
enabled = true
port = ssh
# ログの場所はOSに合わせて自動設定を利用
logpath = %(sshd_log)s
backend = %(sshd_backend)s
EOF
2. 設定のポイントと動作の仕組み
banaction に nftables-multiport を指定するのが最大の肝だ。これだけで、fail2ban は遮断時に nft コマンドを発行するようになる。
内部では f2b-table という専用のテーブルが nftables 内に自動で生成される。手動で書いた nftables.conf のルールを汚すことなく、動的な遮断リストだけを別枠で管理できるため、メンテナンス性が非常に高い。
3. 設定を反映して動作を確かめる
書き換えが終わったら、サービスを再起動して設定を読み込ませる。
# Ubuntu / Debian (systemd) の場合
sudo systemctl restart fail2ban
# Void Linux (runit) の場合
sudo sv restart fail2ban
再起動後、sudo nft list ruleset を実行して、結果の中に table inet f2b-table という記述が見つかれば成功だ。これで、自作のルールと fail2ban の自動遮断がひとつの仕組みとして統合された。
まとめ
UFWはPythonで書かれたプログラムだ。人間が打ったコマンドを解析し、それをさらに別のツールに翻訳して、ようやくOSの中核(カーネル)に伝える。一方でnftablesなら、設定ファイルの内容が直接「ネットフィルタ」というカーネル内のエンジンに読み込まれる。翻訳機を使わずに、その国の言葉で直接会話するようなスムーズさがある。
普段のブラウジングで速さを感じることは稀だが、OSの起動時には違いが出る。UFWはサービスが立ち上がるまでに少し時間がかかるが、nftablesはカーネルがロードされるのとほぼ同時に壁を作れるため、起動直後の無防備な瞬間が最小限になる。マシンのリソースを無駄使いせず、純粋な形でシステムを守っているという満足感がnftablesを使う最大のメリットだ。



