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

【概要】Ubuntu上でのセキュアなSSHサーバ構築はsshd_configの設定と公開鍵認証で行う。ufwFail2Banで防御し、パスワード認証は無効にする。Ubuntu 24.04 LTS ではソケットアクティベーションを使うため、待ち受けポートの変更はssh.socketで行う。ログ確認、デバッグ、緊急復旧の方法も示す。

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

1. OpenSSHのインストール

SSH接続を行うクライアント機能と、接続を受け付けるサーバ機能の両方をインストールする。サーバ機自身が他のSSHサーバへ接続することもあるため、クライアントも入れておく。

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

# パッケージリストの情報を更新
sudo apt update

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

sudo apt -y install openssh-client

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

sudo apt -y install openssh-server

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

SSHサーバの挙動を決める設定ファイル /etc/ssh/sshd_config を編集する。Ubuntu では /etc/ssh/sshd_config.d/ 内の .conf ファイルも読み込まれ、こちらの設定が優先される場合があるため、設定が反映されないときはこのディレクトリも確認する。編集後は設定の反映が必要である。この操作は、接続先(SSH サーバ側)のマシンで、システム管理者が実施する。

編集後は、次のコマンドで文法エラーの有無を確認する。

sudo sshd -t

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

ログ設定

(オプション)待ち受けポート番号の変更

アクセス制御

3. 公開鍵認証の有効化

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

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

/etc/ssh/sshd_config を編集する。

設定変更後、設定を反映させる。Ubuntu 24.04 LTS ではソケットアクティベーションにより接続ごとに sshd が起動するため、sshd_config の変更は次の新規接続から有効になる。待ち受けポートやアドレスを変えた場合は ssh.socket の再起動が必要である。

# Ubuntu 24.04 LTS の場合
sudo systemctl restart ssh.socket

4. 接続ログの確認

SSHサーバへの接続試行や認証の成功・失敗の記録は、rsyslog が動作している環境では /var/log/auth.log に出力される。ログには、ログイン試行の成否、使われた認証方法、接続元IPアドレスなどが含まれる。設定が反映されているかの確認や、不審なアクセスの点検に使う。

Ubuntu 24.04 LTS の最小構成イメージやコンテナでは rsyslog が入っておらず、/var/log/auth.log が存在しないことがある。その場合は systemd ジャーナルを参照する。

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

# sshd の行だけを抽出して表示
grep sshd /var/log/auth.log

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

# systemd ジャーナルから参照する場合
journalctl -u ssh -n 100
journalctl -t sshd -f

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

Ubuntu では、次のコマンドで SSH サーバを再起動する。設定ファイルを書き換えた場合は、再起動の後に動作確認を行う。Ubuntu 24.04 LTS の OpenSSH は systemd のソケットアクティベーションを使う設定になっており、接続要求があるまで sshd は起動しない。

# Ubuntu 24.04 LTS の場合
sudo systemctl restart ssh.socket

設定変更を反映するときは、現在のSSH接続を切断せずに残したまま、別のターミナルから新規接続してログインできることを確認する。ログインできなくなった場合、残した接続から設定を戻せる。

5. TCP Wrapper による IP アドレス制限(現在は使用できない)

OpenSSH は 6.7(2014年)で TCP Wrapper(libwrap)のサポートを削除した。Ubuntu 24.04 LTS の OpenSSH も libwrap を使わないため、/etc/hosts.allow/etc/hosts.denysshd のルールを書いてもSSHのアクセス制御には効かない。接続元IPアドレスによる制限は、次に説明する ufw、または sshd_configAllowUsersユーザー名@IPアドレス/CIDR の形式)で行う。

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

ufw(Uncomplicated Firewall)は、Ubuntu で標準的に使えるファイアウォール管理ツールである。不要なポートを閉じ、SSH で使うポートだけを開けることでアクセスを制御する。

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

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

    (受信を既定で拒否すると、明示的に許可した通信以外は遮断される)

  2. SSH ポートの許可
    • 既定の SSH ポート(22)を許可
      sudo ufw allow ssh
      

      sudo ufw allow 22/tcp と同じ意味である)

    • ポート番号を変更した場合(例:2222)
      sudo ufw allow 2222/tcp
      
  3. (オプション)他に必要なポートの許可
    • Web サーバを運用している場合など
      sudo ufw allow http  # ポート 80
      sudo ufw allow https # ポート 443
      
  4. SSH 総当たり攻撃の緩和
    sudo ufw limit ssh
    
    • 説明 同一の送信元から30秒間に6回以上の接続があった場合、その送信元からの新規接続を拒否する。sudo ufw allow ssh の代わりに設定する。ポート番号を変更した場合は sudo ufw limit 2222/tcp のように指定する。
  5. ufw の有効化
    sudo ufw enable
    

    (SSH の許可ルールを入れてから有効化する。リモート作業中に許可なしで有効化すると接続が切れる)

  6. 設定状態の確認
    sudo ufw status verbose
    

これらの設定により、許可したポート以外へのアクセスは拒否される。

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

Fail2Ban は、認証ログを監視し、パスワード総当たり攻撃などの試行を検知すると、その送信元 IP アドレスからのアクセスを一定期間ファイアウォールでブロックするツールである。

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

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

  1. Fail2Ban のインストールと起動
    # パッケージリストの情報を更新
    sudo apt update
    sudo apt -y install fail2ban
    sudo systemctl enable --now fail2ban
    

    Ubuntu 24.04 LTS では /etc/fail2ban/jail.d/defaults-debian.conf により sshd の監視(jail)が有効になる。

  2. sshd 監視状況の確認
    sudo fail2ban-client status sshd
    
  3. 設定の追加(jail.local)
    • jail.conf はパッケージ更新で上書きされるため直接編集せず、設定の上書きや追加は /etc/fail2ban/jail.local に書く。ファイルがなければ新規作成する。
    • 設定例
      [DEFAULT]
      # 全 jail に適用される既定値
      bantime  = 1h
      findtime = 10m
      maxretry = 5
      # 自分の管理ネットワークをブロック対象から除外する
      ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16
      
      [sshd]
      enabled  = true
      port     = ssh
      backend  = systemd
      maxretry = 3
      bantime  = 24h
      findtime = 10m
      
    • 設定の説明
      • bantime:ブロック期間(1h=1時間、24h=24時間、-1=無期限)
      • findtime:失敗回数を数える期間(10m=10分)
      • maxretryfindtime 内に許容する最大失敗回数
      • backend:ログの取得元。systemd はジャーナルを読む。rsyslog を使い /var/log/auth.log を読ませる場合は backend = autologpath = /var/log/auth.log を指定する。/var/log/auth.log が存在しない環境で logpath を指定すると、Fail2Ban の起動に失敗する。
      • port:待ち受けポートを変更した場合は、その番号(例:port = 2222)を指定する。
    • ignoreip を設定していない状態で自分の操作ミス(パスワード連続失敗など)が続くと、自分の接続元がブロックされる。ブロックの解除は次のコマンドで行う。
      sudo fail2ban-client set sshd unbanip 192.168.0.10
      
  4. Fail2Ban サービスのリロード/再起動
    • 設定ファイルを再読み込み
      sudo fail2ban-client reload
      
    • サービスを再起動
      sudo systemctl restart fail2ban
      
  5. ログとブロック状況の確認
    # Fail2Ban のログを確認
    sudo cat /var/log/fail2ban.log
    
    # 現在ブロックされている IP を確認(sshd jail の場合)
    sudo fail2ban-client status sshd
    
    # すべての jail の一覧を確認
    sudo fail2ban-client status
    

古い解説にある [sshd-ddos] jail は、Fail2Ban 0.10 以降では削除されている。jail.local に書くと filter が見つからず起動に失敗するため、記述しない。短時間の大量接続は [sshd]mode = aggressiveufw limit で対処する。

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

パスワード認証の代わりに公開鍵認証を使うための設定を、クライアントマシン(接続元の PC)で行う。

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

公開鍵認証では、「秘密鍵」と「公開鍵」のペアを使う。

ログイン時、サーバは登録済みの公開鍵に対応する署名をクライアントに要求し、クライアントは秘密鍵で署名して応答する。秘密鍵そのものはネットワーク上を流れないため、盗聴されず、総当たり攻撃も現実的でない。

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

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

Ed25519 形式のキーペアを生成する(鍵長が短く、署名と検証が高速である)。コマンドは次の通りである。

ssh-keygen -t ed25519 -C "your_email@example.com"

以下の操作は、接続元(ユーザマシン)で、各ユーザが行う。SSHキーは利用者ごとに作り、複数人で共有しない。

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

  1. MobaXterm のインストール

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

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

    Windows マシン の場合は、MobaXTermをインストールし、内蔵の ssh-keygenssh を使う。Windows 10/11 に標準搭載の OpenSSH クライアント(コマンドプロンプトや PowerShell の sshssh-keygen)でも同じ操作ができるが、ssh-copy-id は含まれない。

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

    MobaXterm を起動し、ローカルターミナルを開く。鍵はユーザのプロファイル内に保存されるため、通常は管理者権限は不要である。

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

    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):

    秘密鍵を保護するためのパスフレーズを入力する。パスフレーズを設定しておくと、秘密鍵ファイルが流出しても、パスフレーズを知らない者は鍵を使えない。確認のため、同じパスフレーズを再入力する。入力中、画面には表示されない。

    MobaXtermターミナルでssh-keygen実行中にパスフレーズ入力を求められている画面
  6. 生成ファイルの確認

    既定の場所に id_ed25519秘密鍵)と id_ed25519.pub公開鍵)の2つのファイルが生成されたことを確認する。

    cd /d c:%HOMEPATH%\Documents\MobaXterm\home\.ssh
    dir /w
    
    Windowsエクスプローラーで.sshフォルダ内にid_ed25519とid_ed25519.pubファイルが表示されている画面
  7. (参考)MobaXterm 外で鍵を生成した場合

    MobaXterm 内のローカルターミナルで生成した場合、鍵は上記の既定の場所に保存されるため、コピー作業は不要である。ssh-keygen を MobaXterm 外で実行した場合は、<Documents のフォルダ>\MobaXterm\home\.sshid_ed25519id_ed25519.pub をコピーする。

    WindowsエクスプローラーでMobaXtermフォルダ構造を表示している画面
  8. (参考)FileZilla での利用

    FileZillaなどの PuTTY ベースのツールを使うときは、生成した秘密鍵ファイル(id_ed25519)を設定する。FileZilla は PuTTY 形式の鍵(.ppk)を使うため、OpenSSH 形式の秘密鍵を指定すると変換するかどうかを尋ねられる。「はい」を選ぶと変換される。

    SFTP を選び、「鍵ファイル」に、生成した id_ed25519 を設定する。

    FileZillaでOpenSSH形式の鍵をPuTTY形式に変換するか確認するダイアログ画面

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

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

    ssh-keygen を使う。生成した公開鍵は、接続先(SSH サーバ側)の所定のファイルに追加して使う。

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

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

    Enter キーを押して既定の場所($HOME/.ssh/id_ed25519)に保存する。

  4. パスフレーズの設定

    秘密鍵を保護するためのパスフレーズを入力する。パスフレーズを設定しておくと、秘密鍵ファイルが流出しても、パスフレーズを知らない者は鍵を使えない。確認のため、同じパスフレーズを再入力する。入力中、画面には表示されない。

    Linuxターミナルでssh-keygen実行中にパスフレーズ入力を求められている画面
  5. 生成ファイルの確認

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

    cd $HOME/.ssh
    ls
    
    Linuxターミナルで.sshディレクトリ内のファイル一覧を表示し、id_ed25519とid_ed25519.pubが確認できる画面

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 ディレクトリがない場合に作成するためのものである。パーミッション設定も同時に行う。

:: 公開鍵の内容をパイプでサーバに送り、authorized_keys に追記する
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"
:: 実行後、接続先サーバのパスワードを求められる
Windowsコマンドプロンプトで公開鍵をSSHサーバにコピーするコマンドを実行している画面

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"
# 実行後、接続先サーバのパスワードを求められる
Linuxターミナルで公開鍵をSSHサーバにコピーするコマンドを実行している画面

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

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

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

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

WindowsのMobaXtermで公開鍵認証によるSSH接続時にパスフレーズ入力を求められている画面
Linuxターミナルで公開鍵認証によるSSH接続時にパスフレーズ入力を求められている画面

MobaXterm や他の GUI クライアントでは、接続設定で秘密鍵ファイル(例:id_ed25519)を指定する。FileZilla など PuTTY ベースのツールで SFTP 接続する場合は、秘密鍵を PuTTY 形式(.ppk)に変換する。

(補足)SSHエージェントの利用

秘密鍵にパスフレーズを設定すると、接続ごとにパスフレーズの入力が必要になる。この入力を省くにはSSHエージェントを使う。

SSHエージェントは復号した秘密鍵をメモリ上に保持し、認証時の署名処理を代行する。一度鍵を登録すれば、そのエージェントのプロセスが動作している間はパスフレーズの入力が不要になる。MobaXterm、Linux、macOS のいずれでも利用できる。Linux での登録手順は次の通りである。

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# 登録されている鍵を確認
ssh-add -l

秘密鍵のパスフレーズを変更するには次のコマンドを使う。

ssh-keygen -p -f ~/.ssh/id_ed25519

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

12. パスワード認証の無効化

公開鍵認証でのログインを確認したら、パスワード認証を無効にする。これにより、パスワードを知っていても SSH ログインはできなくなり、パスワード総当たり攻撃を受けなくなる。

この設定を行う前に、公開鍵認証でログインできることを確認する。 公開鍵認証が動いていない状態でパスワード認証を無効にすると、SSH でログインできなくなる。作業中は、現在のSSH接続を切断せずに残しておく。

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

  1. /etc/ssh/sshd_config を編集する。
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    
    • PasswordAuthentication の行がコメントアウトされているか yes になっている場合は、no に変更する。
    • KbdInteractiveAuthentication(旧 ChallengeResponseAuthentication)も no にする。これが yes のままだと、PAM 経由でパスワード入力を求められる場合がある。
    • Ubuntu では /etc/ssh/sshd_config.d/ 内のファイルで PasswordAuthentication yes が指定されていることがある。その場合はそのファイルも修正する。
    sshd_configファイルでPasswordAuthentication noを設定している画面
  2. 設定を確認し、反映させる。
    sudo sshd -t
    # Ubuntu 24.04 LTS の場合
    sudo systemctl restart ssh.socket
    

    反映後、別のターミナルから新規接続してログインできることを確認する。

これ以降、パスワードによる SSH ログインは拒否され、登録済みの公開鍵に対応する秘密鍵を持つクライアントだけがログインできる。

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

SSH 接続で問題が起きた場合の切り分け手順である。

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

SSH サーバの動作を詳しく確認するには、動作中の SSH サービスを停止し、デバッグモードで手動起動する。詳細なログを常時記録したい場合は、/etc/ssh/sshd_configLogLevel VERBOSE または LogLevel DEBUG を指定する方法もある。

  1. 既存の SSH サービスを停止
    # Ubuntu 24.04 LTS の場合(ソケットとサービスの両方を停止する)
    sudo systemctl stop ssh.socket ssh.service
    
  2. デバッグモードで SSH サーバを起動
    sudo /usr/sbin/sshd -d -p <ポート番号>
    
    • -d:デバッグモード。接続試行の詳細なログがコンソールに出力される。1接続を処理すると終了する。
    • -p <ポート番号>:待ち受けるポート番号を指定する。

    このプロセスはフォアグラウンドで動作するため、Ctrl+C で停止できる。確認が終わったら、sudo systemctl start ssh.socket でサービスを再開する。

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

接続元クライアントから接続する際に詳細な情報を表示させると、原因の特定に役立つ。

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

サーバ側とクライアント側のデバッグ情報を合わせて見ることで、設定の誤り、鍵の不一致、パーミッションの問題、ファイアウォールによる遮断などを特定できる。

(補足)緊急時のSSH接続復旧

ファイアウォールの設定ミスや sshd_config の誤りにより、SSH 接続ができなくなった場合は、次の方法で復旧する。


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