— セキュリティ強化の基本を、手戻りゼロで
- この記事で得られること
- 前提・想定環境
- ステップ0:新規の安全な管理ユーザーを用意(任意だが推奨)
- ステップ1:クライアント側でSSH鍵を作る
- ステップ2:サーバーに公開鍵を登録する
- ステップ3:公開鍵認証のみでログインできるかテスト
- ステップ4:パスワードログインを停止(安全確認を挟む)
- ステップ5:ファイアウォールでSSHを限定(任意だが強力)
- ステップ6:Fail2Ban の導入
- ステップ7:再犯者にさらに厳しく(recidive)
- ステップ8:運用のポイント(通知・ログ・解除)
- ステップ9:追加強化(任意)
- うまくいかない時のチェックリスト
- まとめ:最小コストで最大の効果を出す順番
- 付録:コピペ実行用スニペット(Ubuntu最短コース)
この記事で得られること
- 安全に SSH公開鍵認証 を導入できる
- パスワードログインを停止 して総当り攻撃をブロック
- Fail2Ban でログ監視→自動遮断、通知や再犯重課も設定
- つまずきにくい テスト手順/ロールバック手順 付き
前提・想定環境
- OS:Ubuntu 20.04/22.04/24.04 などのDebian系、または RHEL 8/9・AlmaLinux・Rocky Linux
- SSH はデフォルトポート 22(任意で変更手順も後述)
- 作業ユーザーは sudo 可能(
root
でもOK)
⚠️ 作業は 必ず既存セッションを閉じずに 新しいターミナルからテストしながら進めてください。設定ミス時は既存セッションで戻せます。
ステップ0:新規の安全な管理ユーザーを用意(任意だが推奨)
root直ログインを避け、普段は一般ユーザー + sudo にしましょう。
Ubuntu/Debian
sudo adduser adminuser
sudo usermod -aG sudo adminuser
RHEL/AlmaLinux/Rocky
sudo adduser adminuser
sudo passwd adminuser
sudo usermod -aG wheel adminuser
ステップ1:クライアント側でSSH鍵を作る
Ed25519 推奨(高速・短鍵長・強度十分)。古いサーバーで非対応なら RSA 4096 を。
# 基本(コメントは任意、-a でKDF反復回数を強化)
ssh-keygen -t ed25519 -a 100 -C "yourname@machine"
# 互換性重視(必要時のみ)
# ssh-keygen -t rsa -b 4096 -o -a 100 -C "yourname@machine"
生成物(デフォルト)
- 秘密鍵:
~/.ssh/id_ed25519
- 公開鍵:
~/.ssh/id_ed25519.pub
秘密鍵は厳重に保管。第三者と共有しないでください。必要ならパスフレーズも設定。
ステップ2:サーバーに公開鍵を登録する
2-1. ssh-copy-id で楽に配置(推奨)
# まだパスワードログインが有効なうちに実行
ssh-copy-id -i ~/.ssh/id_ed25519.pub adminuser@your.server.ip
2-2. 手動配置(代替)
# サーバー側
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 公開鍵の内容を authorized_keys に追記
echo "ssh-ed25519 AAAA...コメント" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
ステップ3:公開鍵認証のみでログインできるかテスト
既存セッションは閉じず、別ターミナルから接続確認
ssh -i ~/.ssh/id_ed25519 adminuser@your.server.ip
接続できたらOK。できない場合はこの時点で原因を解消(鍵の権限、ユーザー名、IP制限など)。
ステップ4:パスワードログインを停止(安全確認を挟む)
/etc/ssh/sshd_config
を編集します。ディストリにより sshd_config.d/*.conf
が優先される場合もあるので、同等設定が重複しないように。
# バックアップ
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
sudo nano /etc/ssh/sshd_config
追記/確認(存在すれば値を修正)
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM yes
PubkeyAuthentication yes
# ルート直ログイン禁止(後述のroot鍵運用しない場合はnoに)
PermitRootLogin no
# 任意:特定ユーザーのみ許可(誤ると自分も締め出すので要注意)
# AllowUsers adminuser
設定反映
# Ubuntu/Debian
sudo systemctl restart ssh
# RHEL系
sudo systemctl restart sshd
テスト:別ターミナルで再接続(鍵で成功、パスワードでは拒否されることを確認)。
ロールバック:もしログイン不可になったら、既存セッション で
sshd_config.bak
を戻し再起動。最悪はクラウドのコンソール接続/救出モードを使用。
ステップ5:ファイアウォールでSSHを限定(任意だが強力)
Ubuntu:UFW
sudo apt update
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
# SSH許可(デフォルト22番)
sudo ufw allow OpenSSH
# 任意:固定グローバルIPのみ許可
# sudo ufw allow from x.x.x.x to any port 22 proto tcp
sudo ufw enable
sudo ufw status verbose
RHEL系:firewalld
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
# 任意:単一IPのみ許可
# sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=x.x.x.x/32 service name=ssh accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
ステップ6:Fail2Ban の導入
インストール
- Ubuntu/Debian
sudo apt update sudo apt install -y fail2ban
- RHEL/AlmaLinux/Rocky
sudo dnf install -y epel-release sudo dnf install -y fail2ban
基本設定(jail.local)
Fail2Ban は /etc/fail2ban/jail.conf
を直接いじらず、上書き用の jail.local
(または jail.d/*.conf
)に書きます。
sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[DEFAULT]
# 誤BANを避けたいIP(自宅/踏み台など)を空白区切り
ignoreip = 127.0.0.1/8 ::1
bantime = 1h # 初回のBAN時間(1時間)
findtime = 10m # 失敗回数カウント対象期間
maxretry = 5 # この回数失敗でBAN
backend = systemd # Ubuntu/RHELともsystemdジャーナル監視が安定
# 再犯重課(段階的にBAN延長)
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w # 最大で1週間まで延長
destemail = root@localhost
sender = fail2ban@$(hostname -f)
mta = sendmail
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
mode = aggressive # ブルートフォースに強いモード
action = %(action_)s # ローカルログのみ(メール不要ならこれ)
# メール通知も欲しい場合は下行に変更(MTAの設定が必要)
# action = %(action_mw)s
EOF
mode = aggressive
は OpenSSH のログからより多くの失敗パターンを拾います。誤検知が心配なら通常モードに。
起動・有効化
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
状態確認
sudo fail2ban-client status
sudo fail2ban-client status sshd
出力例(イメージ)
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| `- Total failed: 23
`- Actions
|- Currently banned: 2
`- Total banned: 4
ステップ7:再犯者にさらに厳しく(recidive)
短時間のBANをすり抜ける攻撃者に有効です。
sudo tee /etc/fail2ban/jail.d/recidive.local >/dev/null <<'EOF'
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
EOF
sudo systemctl restart fail2ban
sudo fail2ban-client status recidive
ステップ8:運用のポイント(通知・ログ・解除)
- 手動で解除(誤BAN時)
# 現在BANされているIP一覧
sudo fail2ban-client status sshd
# 単一IPの解除
sudo fail2ban-client set sshd unbanip 203.0.113.45
- メール通知
action = %(action_mw)s
にすると BAN 時に whois 情報付きメール。
送信にはsendmail
/postfix
等のMTA設定が必要。 - ログの見方
- Ubuntu/Debian:
/var/log/auth.log
(またはjournalctl -u ssh
) - RHEL系:
/var/log/secure
(またはjournalctl -u sshd
) - Fail2Ban 自体のログ:
/var/log/fail2ban.log
- Ubuntu/Debian:
ステップ9:追加強化(任意)
9-1. SSHポート変更(効率的なノイズ削減)
「隠蔽」ではありますが、botスキャンの大半を避けられます。/etc/ssh/sshd_config
Port 22222
ファイアウォール許可 → SSH再起動 → 新ポートで接続テスト成功を確認してから 旧ポート閉鎖。
# UFW 例
sudo ufw allow 22222/tcp
sudo systemctl restart ssh
ssh -p 22222 adminuser@your.server.ip
# うまくいったら
sudo ufw delete allow OpenSSH
9-2. ルート直ログインの扱い
PermitRootLogin no
を基本に。どうしても必要なら prohibit-password
(鍵のみ)だが、通常は root 直ログイン自体を避ける運用が安全。
9-3. ユーザー制限
管理者以外のログインを切る
AllowUsers adminuser
複数指定可(空白区切り)。設定前に対象ユーザーで鍵ログインできることを確認。
9-4. 多要素認証(上級者向け)
libpam-google-authenticator
などのTOTPを PAM と組み合わせ可能。ただし無人接続や自動化処理には影響が出るので要設計。
うまくいかない時のチェックリスト
- 鍵ファイルの権限(サーバー側)
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
- ユーザー名・ホームディレクトリ が正しいか
- sshd_config の二重定義(
/etc/ssh/sshd_config.d/*.conf
)で上書きされていないか - ファイアウォール/クラウドFW/セキュリティグループ でポートが開いているか
- ログ確認
journalctl -u ssh
/journalctl -u sshd
/var/log/auth.log
//var/log/secure
- 古いOpenSSH で Ed25519 非対応 → RSA 4096 を使う
- SELinux(RHEL系) が有効でポリシーに阻まれていないか
getenforce
で確認、/var/log/audit/audit.log
を参照
まとめ:最小コストで最大の効果を出す順番
- 公開鍵認証導入(鍵ログインテストまで)
- パスワードログイン停止(PermitRootLoginも見直し)
- Fail2Ban(sshd有効、段階的BANとrecidive)
- ファイアウォール(IP制限やポート変更でノイズ減)
この4点を抑えるだけで、一般的な総当り攻撃・スキャンはほぼ無害化できます。あとは定期的なOS更新(自動化推奨)と監視で堅牢性を維持しましょう。
付録:コピペ実行用スニペット(Ubuntu最短コース)
既存セッションを閉じずに、各行の意味を理解して 実行してください。
# 0) 管理ユーザー(存在するならスキップ)
sudo adduser adminuser && sudo usermod -aG sudo adminuser
# 1) クライアントで鍵作成(ローカル端末で)
# ssh-keygen -t ed25519 -a 100 -C "you@pc"
# 2) 公開鍵登録(ローカル端末で)
# ssh-copy-id -i ~/.ssh/id_ed25519.pub adminuser@your.server.ip
# 3) 鍵ログインテスト(別ターミナル)
# ssh -i ~/.ssh/id_ed25519 adminuser@your.server.ip
# 4) パスワードログイン停止(サーバー側)
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
grep -q '^PubkeyAuthentication' /etc/ssh/sshd_config || echo 'PubkeyAuthentication yes' | sudo tee -a /etc/ssh/sshd_config
grep -q '^PermitRootLogin' /etc/ssh/sshd_config || echo 'PermitRootLogin no' | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart ssh
# 5) UFW(任意)
sudo apt update && sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
# 6) Fail2Ban
sudo apt install -y fail2ban
sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
mode = aggressive
action = %(action_)s
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
よくある質問(FAQ)
Q. パスワードログインを完全に切るのは怖い…
A. まず鍵ログインが成功することを 別ターミナル で確認してから切り替えれば安全です。戻し方(ロールバック)も用意しておきましょう。
Q. ポート変更は必要?
A. 必須ではありませんが、スキャン雑音が減りログが見やすくなります。Fail2Banと併用で管理の手間が減ることが多いです。
Q. 自動化やCI/CDで鍵が使い回しになる
A. ジョブ専用の鍵を発行し、最小権限のユーザー・限定IPで使い分けましょう。期限管理も忘れずに。