VPSセキュリティ入門:SSHキー、ファイアウォール、Fail2ban

読了時間 6分
Tropic

VPSセキュリティ入門:SSHキー、ファイアウォール、Fail2ban

Ubuntuをインストールした直後のVPSは、すぐに安全な状態になっているとは限りません。アクセス設定が終わる前からサーバーはスキャナーに発見され、SSHパスワードの総当たりや、公開された管理パネル、よくある脆弱性の探索が行われます。このガイドでは、VPSをゼロから保護する基本手順を説明します。専用ユーザーの作成、SSHキーによるログイン、UFWによるネットワークポートの制限、Fail2banの導入までを扱います。各手順は、sudo 権限を持つユーザーでコマンドを実行する場合、Ubuntu 22.04および24.04に対応しています。

設定前にポートの一覧を作る

「念のため」という理由でポートを開放しないでください。一般的なWebサーバーで必要になるのは、次のポートです。

  • 22/tcp — SSH。可能であればIPアドレスで制限します。別のポートへ変更する場合も、あくまで追加対策と考えてください。
  • 80/tcp — HTTP。通常はHTTPSへのリダイレクトや証明書の検証に使います。
  • 443/tcp — HTTPS。

NginxやCaddyを前段で使う場合、300080809000 などのアプリケーション用ポートをインターネットから直接アクセスできる状態にしてはいけません。アプリケーションを 127.0.0.1 にバインドするか、ポートへのアクセスを内部ネットワークだけに許可してください。まず、サーバー上で何が待ち受けているか確認します。

sudo ss -tulpn

Dockerをインストールした後は、iptablesのルールも別途確認してください。-p 3000:3000 の公開によって、想定していた構成を経由せずにポートが開くことがあります。公開サービスでは、HTTPSプロキシを使い、内部ポートを外部から見えないようにする方が安全です。

ステップ1:システムを更新して管理者ユーザーを作成する

発行されたアカウントでVPSに接続し、更新をインストールします。

sudo apt update
sudo apt full-upgrade -y
sudo apt install -y ufw fail2ban unattended-upgrades

個人用のユーザーを作成します。alex の部分は自分の名前に置き換えてください。

sudo adduser alex
sudo usermod -aG sudo alex

新しいアカウントを別のターミナルで確認するまで、最初に使ったアクセス方法を削除しないでください。現在のセッションが開いたままなら、SSH設定のミスを修正しやすくなります。

ステップ2:SSHキーを作成してサーバーに登録する

Linux、macOS、またはWindows PowerShellを使っている自分のコンピューターで、次のコマンドを実行します。

ssh-keygen -t ed25519 -C "alex@my-computer"

Enterキーを押して標準ファイルに保存し、passphrase(パスフレーズ)を設定してください。秘密鍵をチャットに送ったり、リポジトリに置いたり、VPSへコピーしたりしてはいけません。サーバーへ転送するのは、.pub 拡張子の公開鍵ファイルだけです。

ssh-copy-id alex@SERVER_IP

ssh-copy-id が使えない場合は、PowerShellで Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub を実行して公開鍵を表示し、次の手順でサーバーに追加します。

sudo install -d -m 700 -o alex -g alex /home/alex/.ssh
sudo nano /home/alex/.ssh/authorized_keys
sudo chown alex:alex /home/alex/.ssh/authorized_keys
sudo chmod 600 /home/alex/.ssh/authorized_keys

鍵を1行のまま貼り付け、パスワード認証を無効にする前にログインを確認します。

ssh alex@SERVER_IP
sudo whoami

最後のコマンドで期待される結果は root です。SSHクライアントが鍵を見つけられない場合は、明示的に指定します。ssh -i ~/.ssh/id_ed25519 alex@SERVER_IP

ステップ3:rootログインとパスワードログインを禁止する

SSH設定のバックアップを作成します。

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

ファイルに次のパラメーターがあることを確認してください。

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
MaxAuthTries 3

Ubuntuでは、設定が /etc/ssh/sshd_config.d/*.conf に置かれている場合もあります。そのため、最終的に適用される設定を確認します。

sudo sshd -t
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries'

sshd -t でエラーが表示された場合は、構文を修正するまでサービスを再起動しないでください。検証に成功したら、設定を適用します。

sudo systemctl reload ssh

古いSSH接続は開いたままにし、新しいウィンドウで鍵を使ったログインを確認します。鍵でのログインを確認せずにパスワードを無効にすると、サーバーへアクセスできなくなることがあります。

ステップ4:SSHをブロックせずにUFWを設定する

UFWは、Linuxのネットワークルールを扱いやすくする仕組みです。まず安全なデフォルト値を設定し、その後でSSHとWebポートを許可します。

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable

SSHのルールを追加してから、UFWの有効化を確認してください。結果を表示します。

sudo ufw status verbose
sudo ufw status numbered

オフィスのIPアドレスが固定されている場合は、SSHをそのアドレスに制限できます。

sudo ufw delete allow 22/tcp
sudo ufw allow from YOUR.PUBLIC.IP to any port 22 proto tcp comment 'SSH office'

この方法は、IPが固定されており、プロバイダーのコンソールを利用できる場合だけ使ってください。アドレスが変わると、自分自身を締め出す可能性があります。

アプリケーションのポートを一時的に開く

サービスへ直接アクセスして確認する必要がある場合は、接続元を制限したルールを作成します。

sudo ufw allow from YOUR.PUBLIC.IP to any port 8080 proto tcp

テスト後、ufw status numbered に表示された番号を使って削除します。

sudo ufw delete RULE_NUMBER

sudo ufw allow 1:65535/tcp は使わないでください。このルールを設定すると、ファイアウォールが形式だけのものになってしまいます。

ステップ5:SSH用にFail2banを有効にする

Fail2banはログを分析し、ログインに何度も失敗した接続元に対して、一時的なブロックルールを追加します。SSHキーやファイアウォールの代わりにはなりませんが、自動的な総当たり攻撃によるノイズを減らせます。

パッケージの更新で設定が上書きされないように、ローカル設定を作成します。

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

[DEFAULT] セクションで、無理のない値を指定します。

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
banaction = ufw

[sshd]
enabled = true
port = 22

サービスを起動し、jailを確認します。

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

sshd の出力で、失敗した試行回数とブロックされたアドレスを確認します。自分のIPアドレスをbanリストに追加しないでください。恒久的な除外には、[DEFAULT]ignoreip = 127.0.0.1/8 YOUR.PUBLIC.IP パラメーターを使用します。

ステップ6:自動更新を有効にする

セキュリティパッケージの自動更新は有用ですが、カーネルの再起動が必要になる場合は別途管理する必要があります。

sudo dpkg-reconfigure -plow unattended-upgrades
sudo systemctl status unattended-upgrades

週に1回、再起動が必要か確認します。

test -f /var/run/reboot-required && echo 'Требуется перезапуск'

手動で再起動する前に、利用できる鍵とVPSコンソールへのアクセスがあることを確認してください。再起動後は、アプリケーション、Nginx、UFW、Fail2banのサービスを確認します。

ステップ7:外部から結果を確認する

設定ファイルの内容だけでなく、別のコンピューターから実際の保護状態を確認してください。

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no alex@SERVER_IP

このコマンドは拒否されるはずです。鍵を使った正常なログインは、別に確認します。

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alex@SERVER_IP

VPS上では、待ち受けているアドレスとルールを確認します。

sudo ss -lntup
sudo ufw status numbered
sudo fail2ban-client status sshd

直接アクセスを想定していないアプリケーションのポートは、127.0.0.1 で待ち受けるようにしてください。外部ノードからは nmap SERVER_IP を使えますが、スキャンするのは自分が管理するサーバーだけにしてください。許可なく他者のインフラを調査すると、法律やプロバイダーの規約に違反する可能性があります。

バックアップと復旧

SSHの保護だけでは、データの削除、管理者の操作ミス、アプリケーションの侵害からデータを守れません。データベース、設定、ユーザーファイルのコピーをVPSとは別の場所に保存してください。最低限の構成は、毎日のバックアップ、過去数日分の複数世代の保持、そして定期的な復元テストです。

パスワードやトークンを平文のスクリプトに書かないでください。秘密情報が漏えいした場合は、直ちにその秘密を失効させ、新しいものを発行します。

セキュアなプロジェクト向けVPSの選び方

セキュリティは、インフラをどれだけ管理できるかという点から始まります。VPSなら、OS、ファイアウォールのルール、アクセス方法、バックアップ、サービスの配置を自分で選択できます。小規模なサイトやAPIでは、仮想CPUの数が多いことよりも、安定したネットワーク、SSD、復旧用コンソールの方が重要になることがあります。

tropic.host でVPSにプロジェクトを立ち上げる場合は、公開する入口を最初に決めておきましょう。多くの場合、SSH、HTTP、HTTPSだけで十分です。データベースや管理パネルは内部ネットワークに残してください。プロジェクトが成長したら、アプリケーション、データベース、監視用にVPSを分けることで、障害の影響範囲を分離できます。

よくあるミス

  • 鍵でログインできることを確認する前に、パスワードを無効にする。現在のセッションを残し、新しいログインを別途テストしてください。
  • 信頼できるアドレスだけに制限できるのに、22/tcp を全世界に開放する。
  • Dockerのポートを直接公開する。まずDockerとUFWのルールを確認してください。
  • Fail2banをインストールした後、ログを一度も確認しない。変更後は journalctl -u ssh とjailの状態を確認してください。

まとめ

VPSの基本的な保護は、順番を守って実施すれば、長い時間を必要としません。専用ユーザーを作成し、SSHキーを登録し、アクセスを確認してから、rootログインとパスワード認証を禁止します。その後、UFW、Fail2ban、自動更新を有効にしてください。さらに、バックアップ、ログ記録、外部監視を追加します。

これらの手順でサーバーが無敵になるわけではありません。しかし、初期設定で起こりやすい問題の多くは防げます。次の段階では、アプリケーションに合わせて対策を調整し、依存関係を更新し、サービスの権限を制限し、管理パネルを保護し、公開ポートを定期的に確認してください。

FAQ

SSHの標準ポートは変更する必要がありますか?

必須ではありません。ポートを変更すると自動スキャンによるノイズは減りますが、SSHキー、パスワード認証の無効化、UFW、Fail2banの代わりにはなりません。ポートを変更する場合は、ファイアウォールのルールとFail2banのjailにある port パラメーターも更新してください。

UFWの設定後にアクセスできなくなった場合はどうすればよいですか?

プロバイダーのWebコンソールまたはレスキューコンソールを使い、SSHのルールと sshd の設定を確認してください。新しいログインが確認できるまで、以前の接続を閉じないでください。

SSHの保護にはFail2banだけで十分ですか?

いいえ。Fail2banは、ログインに失敗した後で反応する仕組みです。基本となるのはSSHキー、無効化したパスワード認証、最小限のユーザー権限、そして制限されたファイアウォールです。

SSHを1つのIPアドレスからだけ許可できますか?

アドレスが固定されている場合は可能です。そのIPアドレスからの接続だけを許可する allow from ルールをUFWに追加してください。IPが変わると接続できなくなるため、あらかじめプロバイダーのコンソールや予備のアクセス方法を用意しておきましょう。

VPSのセキュリティはどのくらいの頻度で確認すべきですか?

SSH、ファイアウォール、Dockerのポート公開を変更するたびに、ポート確認とログインテストを実行してください。定期的には、少なくとも週に1回、更新とログを確認します。バックアップからの復元テストも、継続的に行ってください。