セキュアなSSHサーバの構築と運用ガイド(Ubuntu 上)

【概要】 Ubuntu上でのSSHサーバの構築と設定について,セキュアなリモートアクセス環境を実現するための手順を説明している.openssh-serverのインストールから始まり,sshd_configファイルでのセキュリティ設定,公開鍵認証の導入,TCP Wrapperによるアクセス制限,ufwを用いたポート制御,Fail2Banによる不正アクセス対策まで,包括的なセキュリティ対策を解説している.さらに,Windows/Ubuntuからの公開鍵・秘密鍵の生成と設定方法,パスワード認証の無効化,トラブルシューティングまでを詳述している.これらの設定により,パスワード認証に依存しない,より安全なSSHアクセス環境を構築できる.本ガイドは、セキュアなサーバ運用に関する知識を深め、学術研究や開発活動における安全な基盤構築に貢献することを目的としています。

SSH サーバの設定(SSH サーバは Ubuntu マシン)

1. OpenSSHのインストール

SSH接続を行うクライアント機能と、接続を受け付けるサーバ機能の両方をインストールします。サーバ機自身が他のSSHサーバへ接続する可能性も考慮し、クライアントもインストールしておくと便利です。

1.1. パッケージリストの更新

sudo apt -y update

1.2. OpenSSH クライアントのインストール

sudo apt -y install openssh-client

1.3. OpenSSH サーバのインストール

sudo apt -y update
sudo apt -y install openssh-server

2. SSHサーバ設定ファイル (`/etc/ssh/sshd_config`) の編集

SSHサーバの挙動を制御する主要な設定ファイル `/etc/ssh/sshd_config` を編集します。編集後はSSHサーバの再起動が必要です。この操作は、接続先(SSH サーバ側)のマシンで、システム管理者が実施してください。

基本的なセキュリティ設定:

ログ設定:

(オプション)ポート番号の変更:

アクセス制御:

3. 公開鍵認証の有効化

パスワード認証よりも安全な公開鍵認証を有効にします。

以下の操作は,接続先(SSH サーバ側)のマシンで,システム管理者が実施する.

/etc/ssh/sshd_config を編集します。

設定変更後、SSHサーバを再起動して設定を反映させます。

# systemd を使用する最近の Ubuntu の場合 (推奨)
sudo systemctl restart ssh

# 古いバージョンの Ubuntu や systemd を使用しないシステムの場合
# sudo service ssh restart

4. 接続ログの確認

SSHサーバへの接続試行や認証の成功・失敗に関するログは、通常 `/var/log/auth.log` に記録されます。不審なアクセスがないか、設定が正しく反映されているかを確認するために、定期的にログを確認することが重要です。ログには、成功/失敗したログイン試行、使用された認証方法、接続元IPアドレスなどの情報が含まれます。

# ログ全体を表示
cat /var/log/auth.log

# "ssh" を含む行をフィルタリングして表示 (より関連性の高いログのみ)
grep sshd /var/log/auth.log

# リアルタイムでログを監視
tail -f /var/log/auth.log

SSH サーバの再起動(Ubuntu の場合)

Ubuntu では,次のコマンドで SSH サーバを再起動.設定ファイルの書き換えを行った場合には, 再起動の後の動作確認を忘れないこと.

# systemd を使用する最近の Ubuntu の場合 (推奨)
sudo systemctl restart ssh

# 古いバージョンの Ubuntu や systemd を使用しないシステムの場合
# sudo service ssh restart

5. TCP Wrapper による IP アドレス制限 (注意点あり)

注意: TCP Wrapper (`/etc/hosts.allow`, `/etc/hosts.deny`) は、SSHサーバへのアクセス元 IP アドレスを制限する古典的な方法ですが、現代の Linux システムや OpenSSH のバージョンでは非推奨であり、期待通りに機能しない、あるいは全く無視される可能性があります。可能な限り、後述するファイアウォール (`ufw` など) を使用して IP アドレス制限を行うことを強く推奨します。

もし、システムが TCP Wrapper をサポートしており、これを使用する場合は、以下の設定を行います。(システム管理者権限で実施)

設定ファイル編集後は、通常サービスの再起動は不要ですが、反映されない場合は試してください。

6. ファイアウォール (`ufw`) によるアクセス制御

`ufw` (Uncomplicated Firewall) は、Ubuntu で標準的に利用可能なファイアウォール管理ツールです。不要なポートを閉じ、SSH アクセスを許可するポート(デフォルトは 22 番)のみを開けることで、セキュリティを強化します。

基本的な設定手順: (システム管理者権限で実施)

  1. ufw の有効化:
    sudo ufw enable
    

    (有効化すると、既存の接続が切断される可能性があるため注意)

  2. デフォルトポリシーの設定 (重要):
    • 受信 (Incoming) をすべて拒否:
      sudo ufw default deny incoming
      
    • 送信 (Outgoing) をすべて許可 (一般的):
      sudo ufw default allow outgoing
      

    (デフォルトで受信を拒否することで、許可した通信以外はすべて遮断されます)

  3. SSH ポートの許可:
    • デフォルトの SSH ポート (22) を許可:
      sudo ufw allow ssh
      

      (これは sudo ufw allow 22/tcp と同等です)

    • もし sshd_config でポート番号を変更した場合 (例: 2222):
      sudo ufw allow 2222/tcp
      
  4. (オプション) 他に必要なポートの許可:
    • Web サーバを運用している場合など:
      sudo ufw allow http  # ポート 80
      sudo ufw allow https # ポート 443
      
  5. (推奨) SSH ブルートフォース攻撃対策:
    sudo ufw limit ssh
    
    • 説明: 短時間に多数の接続試行があった場合に、その送信元からの接続を一時的に拒否します。ufw allow ssh の代わりに、または追加で設定することで、パスワード総当たり攻撃などを緩和できます。
  6. 設定状態の確認:
    sudo ufw status verbose
    

これらの設定により、許可されたポート以外へのアクセスは拒否され、SSH ポートへの不正アクセス試行も制限されます。

7. Fail2Ban による不正アクセス試行の自動検知・防御

Fail2Ban は、サーバのログファイル(例: `/var/log/auth.log`)を監視し、不正アクセス試行(例: パスワード総当たり攻撃)を検知すると、その送信元 IP アドレスからのアクセスを一定期間自動的にファイアウォールでブロックするツールです。

以下の操作は,接続先(SSH サーバ側)のマシンで,システム管理者が実施する.

インストールと設定: (システム管理者権限で実施)

  1. Fail2Ban のインストール:
    sudo apt -y update
    sudo apt -y install fail2ban
    

    (インストール後、デフォルトで sshd 用の監視 (jail) が有効になることが多い)

  2. sshd 監視状況の確認:
    sudo fail2ban-client status sshd
    

    (sshd jail が有効になっていれば、基本的な設定は完了しています)

  3. (オプション) カスタム ブラックリストフィルタの導入:
    • 記事で紹介されている方法は、公開されているブラックリストルールを導入する高度な設定です。
    • 注意: GitHub の `master` ブランチから直接ファイルをダウンロードする方法は、将来的に内容が変更される可能性があります。安定した運用のためには、リリースタグなどを確認するか、プロジェクトのドキュメントに従うことを推奨します。

      元の記事にある公開情報: https://github.com/mitchellkrogza/Fail2Ban-Blacklist-JAIL-for-Repeat-Offenders-with-Perma-Extended-Banning

    • 手順 (記事記載の例):
      # フィルタ定義ファイルのダウンロード
      sudo wget https://raw.githubusercontent.com/mitchellkrogza/Fail2Ban-Blacklist-JAIL-for-Repeat-Offenders-with-Perma-Extended-Banning/master/filter.d/blacklist.conf -O /etc/fail2ban/filter.d/blacklist.conf
      # アクション定義ファイルのダウンロード
      sudo wget https://raw.githubusercontent.com/mitchellkrogza/Fail2Ban-Blacklist-JAIL-for-Repeat-Offenders-with-Perma-Extended-Banning/master/action.d/blacklist.conf -O /etc/fail2ban/action.d/blacklist.conf
      
  4. (オプション) カスタム jail の設定 (`jail.local`):
    • `jail.conf` を直接編集せず、設定の上書きや追加は `/etc/fail2ban/jail.local` に記述します。ファイルが存在しない場合は新規作成します。
    • 記事記載の例:
      [DEFAULT]
      # デフォルト設定 (この例では port と filter を指定しているが、通常 DEFAULT セクションでの filter 指定は特殊)
      # port = 0:65535 # 監視対象ポート (通常は jail ごとに指定)
      # filter = %(__name__)s # フィルタ名 (通常は jail ごとに指定)
      
      [blacklist]
      enabled   = true                # この jail を有効にするか
      logpath   = /var/log/fail2ban.* # 監視するログファイル (注意: これは fail2ban 自身のログであり、通常は auth.log などを監視対象とする jail を定義する)
      filter    = blacklist           # 使用するフィルタ定義 (上記でダウンロードしたもの)
      banaction = blacklist           # BAN 時に実行するアクション (上記でダウンロードしたもの)
      action    = %(action_)s          # BAN アクションの詳細 (通常は %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]) のような形式
      bantime   = 31536000          # BAN する期間 (秒単位, ここでは 1 年)
      findtime  = 31536000          # 試行をカウントする期間 (秒単位, ここでは 1 年)
      maxretry  = 10                  # findtime 内に許容する最大試行回数
      
    • 補足: 上記の `[blacklist]` jail の設定は、`fail2ban` 自身のログを監視して、特定のパターン(おそらく他の jail によって BAN された IP)をさらに長期間 BAN する、という高度な使い方のように見えます。SSH の不正ログインを直接防ぐ標準的な設定 (`[sshd]` jail) とは異なる可能性があります。 標準的な `[sshd]` jail の設定は `/etc/fail2ban/jail.conf` を参照し、必要に応じて `jail.local` で上書きしてください (例: `bantime` の変更など)。
  5. (オプション) ブラックリストファイルの準備:
    sudo touch /etc/fail2ban/ip.blacklist
    sudo chmod 644 /etc/fail2ban/ip.blacklist # 権限はより制限的で良い場合が多い
    
  6. Fail2Ban サービスのリロード/再起動:
    • 設定ファイルを再読み込み:
      sudo fail2ban-client reload
      
    • サービスを再起動 (設定変更が大きい場合):
      sudo systemctl restart fail2ban
      # または sudo service fail2ban restart
      
    • (必要であれば) SSH サービスも再起動:
      sudo systemctl restart ssh
      # または sudo service sshd restart
      
  7. ログとブロック状況の確認:
    # Fail2Ban のログを確認
    sudo cat /var/log/fail2ban.log
    
    # 現在 BAN されている IP を確認 (sshd jail の場合)
    sudo fail2ban-client status sshd
    
    # (カスタム設定の場合) ブラックリストファイルの内容を確認
    # cat /etc/fail2ban/ip.blacklist
    

II. クライアント側の設定: 公開鍵認証の準備

パスワード認証の代わりに、より安全な公開鍵認証を利用するための設定をクライアントマシン(接続元の PC)で行います。

8. 公開鍵認証の仕組みとキーペア

公開鍵認証では、「秘密鍵」と「公開鍵」のペアを使用します。

ログイン時、サーバは公開鍵を使ってクライアントに「チャレンジ」を送り、クライアントは秘密鍵を使ってそれに正しく応答することで認証が行われます。パスワードのようにネットワーク上を流れないため、盗聴のリスクが低く、ブルートフォース攻撃も困難になります。

このセクションでは、キーペアを生成し、公開鍵をサーバへ登録する手順を説明します。

9. キーペアの生成 (クライアントマシンでの操作)

安全で高速な Ed25519 形式のキーペアを生成することを推奨します(強度が高く、処理速度も速いため)。

以下の操作は,接続元(ユーザマシン)で,各ユーザが行う.

9.1. Windows の場合 (MobaXterm を使用)

  1. MobaXterm のインストール

    【サイト内の関連ページ】

    • Windows での MobaXterm のインストール: 別ページ »で説明
    • Windows でのリモート接続,ファイル転送ソフト MobaXterm Personal 版のインストール(winget を使用しない)と利用: 別ページ »で説明

    Windows マシン の場合は,MobaXTermをインストールし,それに内蔵の ssh-keygen, ssh を使うのが便利.

  2. MobaXterm の起動とターミナル操作:

    MobaXterm を起動し、ローカルターミナルを開きます。(通常、ユーザのプロファイル内に鍵を保存するため管理者権限は不要ですが、環境によっては元の指示通り「管理者として実行」が必要な場合もあります。)

    Windowsコマンドプロンプト管理者として実行するには, 検索窓で「cmd」と入れたあと, 右クリックメニューで「管理者として実行」を選ぶのが簡単.

  3. キーペア生成コマンドの実行:

    ssh-keygen」を使います。公開鍵は,接続先(SSH サーバ側)の所定のファイルに追加して使います。

    ターミナルで次を実行します。

    ssh-keygen -t ed25519 -C "your_email@example.com"
    
    • -t ed25519: キータイプとして Ed25519 を指定します。
    • -C "コメント": 鍵の識別用コメント。通常はメールアドレスなどを入れますが、空でも構いません (-C '')。
  4. 保存場所の指定:

    Enter file in which to save the key (/home/mobaxterm/.ssh/id_ed25519):

    通常は Enter キーを押してデフォルトの場所 (%USERPROFILE%\Documents\MobaXterm\home\.ssh\id_ed25519 など) に保存します。

  5. パスフレーズの設定 (重要):

    Enter passphrase (empty for no passphrase):

    秘密鍵を保護するためのパスフレーズを入力します。パスフレーズを設定することを強く推奨します。 これにより、万が一秘密鍵ファイルが盗まれても、パスフレーズがなければ悪用できません。確認のため、同じパスフレーズを再入力します。入力中、画面には表示されません。

  6. 生成ファイルの確認:

    デフォルトの場所に id_ed25519 (秘密鍵) と id_ed25519.pub (公開鍵) の2つのファイルが生成されたことを確認します。

    cd /d c:%HOMEPATH%\Documents\MobaXterm\home\.ssh
    dir /w
    
  7. (参考) MobaXterm のデフォルト設定について:

    元の指示にある「キーペアのファイルを MobaXterm の配下にコピーする」手順は、ssh-keygen を MobaXterm 外で実行した場合や、特定の場所に鍵を置きたい場合の手順と思われます。MobaXterm 内のターミナルで生成した場合、通常は適切な場所に保存されます。

    <Documents のフォルダ>\MobaXterm\home\.ssh に id_ed25519, id_ed25519.pub をコピーする

  8. (参考) FileZilla での利用:

    FileZillaなどの PuTTY ベースのツールを使うときは、生成した秘密鍵ファイル (`id_ed25519`) を設定する必要があります。FileZilla は PuTTY 形式の鍵 (.ppk) を要求するため、初回設定時に OpenSSH 形式の秘密鍵を .ppk 形式に変換するかどうか尋ねられます。「はい」を選択すると変換が行われます。

    SFTP, 「鍵ファイル」,鍵ファイルとして先ほど生成した id_ed25519 を設定する.

    設定すると,「対応していません。ファイルを変換しますか?」のように表示される. ここで,「はい」を選ぶ. ppk ファイルへの変換が自動で行われ,次のように表示される.

9.2. Ubuntu (または他の Linux/macOS) の場合

  1. ターミナルを開く:
  2. キーペア生成コマンドの実行:

    ssh-keygen」を使います。公開鍵は,接続先(SSH サーバ側)の所定のファイルに追加して使います。

    ssh-keygen -t ed25519 -C "your_email@example.com"
    
  3. 保存場所の指定:

    Enter file in which to save the key (/home/your_username/.ssh/id_ed25519):

    通常は Enter キーを押してデフォルトの場所 ($HOME/.ssh/id_ed25519) に保存します。

  4. パスフレーズの設定 (重要):

    Windows の場合と同様に、秘密鍵を保護するためのパスフレーズを設定することを強く推奨します。確認のため、同じパスフレーズを再入力します。入力中、画面には表示されません。

  5. 生成ファイルの確認:

    $HOME/.ssh/ ディレクトリに id_ed25519 (秘密鍵) と id_ed25519.pub (公開鍵) が生成されたことを確認します。

    cd $HOME/.ssh
    ls
    

10. 公開鍵のサーバへの登録 (クライアントマシンから操作)

生成した公開鍵 (`id_ed25519.pub`) の内容を、接続先 SSH サーバの `~/.ssh/authorized_keys` ファイルに追記する必要があります。

10.1. 推奨方法: `ssh-copy-id` コマンド (利用可能な場合)

`ssh-copy-id` は公開鍵をサーバに簡単かつ安全にコピーするための専用コマンドです。Linux, macOS, MobaXterm, Git Bash などで利用可能です。

ssh-copy-id -i ~/.ssh/id_ed25519.pub ユーザー名@接続先サーバアドレス

実行すると、サーバのパスワード (まだパスワード認証が無効になっていない場合) または既存の鍵のパスフレーズを求められます。認証に成功すると、公開鍵がサーバの `~/.ssh/authorized_keys` に適切に追加されます。

10.2. 代替方法: 手動コピー

`ssh-copy-id` が使えない場合、手動で公開鍵の内容をコピーします。

Windows (MobaXterm/コマンドプロンプト):

「mkdir -p ~/.ssh」は .ssh ディレクトリを作るためのもの (存在しない場合)。パーミッション設定も同時に行います。

:: 公開鍵の内容をクリップボードにコピーするか、以下のコマンドでパイプします
type %USERPROFILE%\Documents\MobaXterm\home\.ssh\id_ed25519.pub | ssh ユーザー名@接続先サーバアドレス "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
:: 実行後、接続先サーバのパスワードを求められます

Ubuntu (または他の Linux/macOS):

「mkdir -p ~/.ssh」は .ssh ディレクトリを作るためのもの (存在しない場合)。パーミッション設定も同時に行います。

# 公開鍵の内容をサーバに追記するコマンド
cat ~/.ssh/id_ed25519.pub | ssh ユーザー名@接続先サーバアドレス "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# 実行後、接続先サーバのパスワードを求められます

11. 公開鍵認証でのログイン試行

公開鍵をサーバに登録したら、実際にログインできるか試します。

ssh ユーザー名@接続先サーバアドレス

今度はサーバのパスワードではなく、キーペア生成時に設定したパスフレーズを求められるはずです (Enter passphrase for key ...)。正しくパスフレーズを入力してログインできれば、公開鍵認証の設定は成功です。

(MobaXterm や他の GUI クライアントを使用している場合は、接続設定で秘密鍵ファイル (例: id_ed25519) を指定する必要があるかもしれません。)

(FileZilla など PuTTY ベースのツールで SFTP 接続する場合、Ed25519 秘密鍵を PuTTY 形式 (.ppk) に変換する必要がある場合があります。ツールの指示に従ってください。)

III. 最終的なセキュリティ強化

12. パスワード認証の無効化 (重要)

公開鍵認証でのログインが確実に機能することを確認したら、セキュリティを最大限に高めるために、従来のパスワード認証を無効にします。これにより、パスワードを知っていても SSH ログインはできなくなり、ブルートフォース攻撃のリスクが大幅に減少します。

警告: この設定を行う前に、必ず公開鍵認証でログインできることをテストしてください。 もし公開鍵認証に失敗していてパスワード認証を無効にすると、SSH でサーバにログインできなくなる可能性があります。

以下の操作は,接続先(SSH サーバ側)のマシンで,システム管理者が実施する.

  1. /etc/ssh/sshd_config を編集します。
    PasswordAuthentication no
    
    • この行がコメントアウトされているか yes になっている場合は、no に変更します。
  2. SSH サーバを再起動して設定を反映させます。
    # systemd を使用する最近の Ubuntu の場合 (推奨)
    sudo systemctl restart ssh
    
    # 古いバージョンの Ubuntu や systemd を使用しないシステムの場合
    # sudo service ssh restart
    

これ以降、パスワードによる SSH ログインは拒否され、有効な秘密鍵を持つクライアントのみが (パスフレーズ入力後に) ログインできるようになります。

IV. トラブルシューティング

SSH 接続で問題が発生した場合の基本的な切り分け手順です。

13. サーバ側でのデバッグ

SSH サーバの動作状況を詳細に確認するには、現在動作中の SSH サービスを停止し、デバッグモードで手動起動します。

  1. 既存の SSH サービスを停止:
    sudo systemctl stop ssh
    # または sudo service ssh stop
    
  2. デバッグモードで SSH サーバを起動:
    sudo /usr/sbin/sshd -d -p <ポート番号>
    
    • -d: デバッグモードを有効にします。接続試行の詳細なログがコンソールに出力されます。
    • -p <ポート番号>: SSH サーバが待ち受けるポート番号を指定します。デフォルト (22) 以外を使用している場合は指定が必要です。

    (このプロセスはフォアグラウンドで実行されるため、Ctrl+C で停止できます。確認が終わったら、sudo systemctl start ssh などでサービスを再開してください)

14. クライアント側でのデバッグ

接続元クライアントから接続を試みる際に、詳細な情報を表示させることで問題の原因特定に役立ちます。

ssh -v ユーザー名@接続先サーバアドレス

サーバ側とクライアント側のデバッグ情報を組み合わせることで、設定ミス、鍵の不一致、パーミッションの問題、ファイアウォールによるブロックなど、多くの問題の原因を特定できます。


【サイト内の関連ページ】