夜中の2時に起きた本当の話
VPSにFedoraをセットアップしたばかりの頃、デフォルトのパスワード認証・ポート22のままSSHを放置していました。翌朝ログを開いたら、異なるIPから4,000件以上のログイン失敗が記録されていました——自動ブルートフォースです。パスワードが十分強かったので被害はありませんでしたが、その時に「最初からちゃんとやろう」と決めました。SSHキー認証+ハードニング+firewalld、妥協なしで。
Fedoraをメインの開発マシンとして2年使っています。一点注意すべきなのは、Fedoraはパッケージの更新が早く、OpenSSHも頻繁に新バージョンが入ること——設定オプションが変わったり非推奨になったりすることがあります。この記事は実際に使っている手順をまとめたもので、Fedora 40/41向けに更新しています。
なぜデフォルトのSSHは危険なのか?
Fedora Serverにはデフォルトでopenssh-serverがインストールされていますが、デフォルト設定にはいくつか問題があります:
- ポート22 ——ボットが24時間365日このポートをスキャンしている
- PasswordAuthentication yes ——ブルートフォース攻撃が可能
- PermitRootLogin yes(または
prohibit-password)——rootログインが可能 - ユーザー制限なし ——すべてのアカウントでSSH接続できる
FedoraのfirewalldはデフォルトでSSH(ポート22)をpublicゾーンで許可しています。つまりマシンを起動した瞬間から、ポート22がインターネットに開放されています。上記の緩い設定と組み合わさると、あなたのサーバーは即座に攻撃対象となります。
対策の選択肢
方法1:SSHポートを変更する
ポート22を別のポート(例:2222)に変えるだけで済ませる人も多いですが、実際にはnmapでのポートスキャンで数分以内に発見されます。これはセキュリティ・バイ・オブスキュリティ——ログのノイズを減らすだけで、本質的なセキュリティにはなりません。
方法2:Fail2ban
N回失敗したIPを自動でブロックします。方法1よりは優れていますが、パスワード認証は残ります。攻撃者が数百のIPをローテーションする分散ボットネットを使えば、Fail2banは効果がありません。
方法3:SSHキー+パスワード認証無効化+firewalldルール
他の2つより根本的に優れているため、この方法を選んでいます。3層の組み合わせ:キーベース認証のみ許可、sshd_configのハードニング、可能ならfirewalldでIPをホワイトリスト化。ブルートフォースボットは完全に無力化されます——推測するパスワードがなく、ブルートフォースする対象もありません。
実践:FedoraでSSHキーをセットアップする
ステップ1:OpenSSHの確認とインストール
# インストール済みか確認
dnf list installed openssh-server
# インストールされていない場合
sudo dnf install -y openssh-server
# サービスの有効化と起動
sudo systemctl enable --now sshd
# 状態を確認
sudo systemctl status sshd
ステップ2:クライアントマシンでSSHキーペアを生成する
このステップはローカルマシンで実行します。サーバー上ではありません:
# ED25519 ——モダンなアルゴリズムで、RSA 2048より安全
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/fedora_server
# より広い互換性が必要な場合はRSA 4096を使用
# ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/fedora_server
生成されるのは2つのファイル:~/.ssh/fedora_server(秘密鍵——絶対に共有しない)と~/.ssh/fedora_server.pub(公開鍵——サーバーに配置する)。
ステップ3:公開鍵をサーバーにコピーする
# 最も簡単な方法
ssh-copy-id -i ~/.ssh/fedora_server.pub username@server_ip
# ssh-copy-idが使えない場合は手動で
cat ~/.ssh/fedora_server.pub | ssh username@server_ip \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ステップ4:ハードニング前に接続をテストする
# 作成したキーでテスト——現在のセッションは閉じないこと
ssh -i ~/.ssh/fedora_server username@server_ip
# 便利に使えるよう ~/.ssh/config に追加
Host fedora-server
HostName server_ip
User username
IdentityFile ~/.ssh/fedora_server
IdentitiesOnly yes
重要:ハードニング作業中は既存のSSHセッションをそのまま開いておいてください。自分自身を締め出すことは十分ありえます——古いセッションが脱出経路になります。
sshd_configのハードニング
メインの設定ファイルは/etc/ssh/sshd_configです。Fedora 40以降では、/etc/ssh/sshd_config.d/*.confでオーバーライドする方法が推奨されています——元のファイルを変更せずに済み、ロールバックがずっと簡単です。
# 専用のオーバーライドファイルを作成
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
ファイルの内容:
# パスワード認証を無効化
PasswordAuthentication no
KbdInteractiveAuthentication no
# rootの直接ログインを禁止
PermitRootLogin no
# SSHを許可するユーザーを限定(「youruser」を実際のユーザー名に変更)
AllowUsers youruser
# 認証試行回数を制限
MaxAuthTries 3
# アイドルセッションのタイムアウト(300秒=5分)
ClientAliveInterval 300
ClientAliveCountMax 2
# 使用しない場合はX11フォワーディングを無効化
X11Forwarding no
# 不要な認証メソッドを無効化
GSSAPIAuthentication no
UsePAM yes
設定を適用する:
# 再起動前にシンタックスを確認
sudo sshd -t
# エラーがなければ
sudo systemctl restart sshd
firewalldとの連携
Ubuntuがufwを使うのとは異なり、Fedoraはfirewalldをゾーンとサービスの概念で使います。より柔軟ですが、変更前にその仕組みを理解しておく必要があります。
現在の設定を確認する
# アクティブなゾーンを確認
sudo firewall-cmd --get-active-zones
# publicゾーンで許可されているサービスを確認
sudo firewall-cmd --zone=public --list-services
SSHポートの変更とfirewalldの更新
ログのノイズを減らすためにポートを変更する場合(例:2222):
# ハードニングファイルに追記
echo "Port 2222" | sudo tee -a /etc/ssh/sshd_config.d/99-hardening.conf
# 新しいポートをSELinuxに登録(FedoraはデフォルトでSELinux enforcingを使用)
sudo semanage port -a -t ssh_port_t -p tcp 2222
# firewalldを更新:デフォルトのsshサービス(ポート22)を削除し、新しいポートを追加
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
# sshdを再起動
sudo systemctl restart sshd
固定IPがある場合はホワイトリスト化する
オフィスや固定VPNなど固定IPで作業している場合——これが実施できる中で最も強力な保護層になります:
# SSH管理用の専用ゾーンを作成
sudo firewall-cmd --permanent --new-zone=ssh-management
sudo firewall-cmd --permanent --zone=ssh-management --add-port=2222/tcp
# 自分のIPのみ許可
sudo firewall-cmd --permanent --zone=ssh-management --add-source=YOUR.OFFICE.IP/32
# publicゾーンにSSHが含まれないことを確認
sudo firewall-cmd --permanent --zone=public --remove-service=ssh
sudo firewall-cmd --permanent --zone=public --remove-port=2222/tcp
sudo firewall-cmd --reload
# 確認
sudo firewall-cmd --zone=ssh-management --list-all
レート制限のためのリッチルール
Fail2banを追加インストールしたくない場合、firewalld自体でレート制限を処理できます:
# 1つのIPから1分間に5つの新しいSSH接続に制限
sudo firewall-cmd --permanent --add-rich-rule=\
'rule service name="ssh" limit value="5/m" accept'
sudo firewall-cmd --reload
確認とモニタリング
# 実行中のSSH設定を確認
sudo sshd -T | grep -E 'passwordauth|permitroot|port|allowusers'
# ログインログをリアルタイムで確認
sudo journalctl -u sshd -f
# 過去1時間のエラーをフィルタリング
sudo journalctl -u sshd --since "1 hour ago" | grep -i fail
最終チェックリスト
古いセッションを閉じる前に、以下のリストを確認しています:
- 別のターミナルから新しいキーでSSH接続が成功する ✓
PasswordAuthentication noが有効になっている(パスワードでSSH接続を試みて拒否されることを確認) ✓- rootログインがブロックされている ✓
firewall-cmd --list-allで正しいポート/ゾーンが表示される ✓- 新しいポートでSELinuxがAVC denialを報告していない(確認方法:
sudo ausearch -m avc -ts recent) ✓
全体のプロセスは約15〜20分かかります。SELinuxで見慣れないエラーメッセージが出て読み込みに時間がかかるため、初回は45分ほどかかるかもしれません。ただし慣れてしまえば、新しいFedoraサーバーのセットアップはずっと速くなります——sshd_config.d/のドロップイン設定はクリーンで、firewalldはゾーンが明確で、他のディストリビューションより迷う場所が少ないと感じています。
