SSH Configuration and Hardening

SSH 設定とハードニング 完全ガイド

目次

  1. はじめに
  2. SSH アーキテクチャとプロトコル
  3. sshd_config(サーバー設定)詳細
  4. ssh_config(クライアント設定)詳細
  5. 鍵ベースの認証
  6. SSH トンネリング
  7. ProxyJump と ProxyCommand
  8. SSH 証明書
  9. fail2ban 連携
  10. ポートノッキング
  11. SSH ハードニングベストプラクティス
  12. 多重化(Multiplexing)
  13. SCP / SFTP / rsync over SSH
  14. トラブルシューティング
  15. 比較表
  16. 参考文献

1. はじめに

SSH(Secure Shell)は、暗号化された通信路を通じてリモートシステムに安全にアクセスするためのプロトコルおよびツールセットである。本ガイドでは、SSH の設定、ハードニング、高度な機能について包括的に解説する。


2. SSH アーキテクチャとプロトコル

2.1 SSH プロトコルの概要

SSH プロトコルバージョン2(SSH-2)は、3つのレイヤーで構成される。

レイヤー説明機能
トランスポート層暗号化、完全性、圧縮鍵交換、暗号化アルゴリズムのネゴシエーション
ユーザー認証層クライアント認証パスワード、公開鍵、キーボードインタラクティブ
コネクション層チャネル多重化セッション、ポートフォワーディング

SSH 接続の流れ

1. TCP 接続の確立(デフォルトポート 22)
2. プロトコルバージョンの交換
3. 鍵交換(Key Exchange)
   - アルゴリズムのネゴシエーション
   - Diffie-Hellman 鍵交換
   - サーバーホストキーの検証
4. ユーザー認証
   - 公開鍵認証
   - パスワード認証
   - 多要素認証
5. セッションの確立
   - チャネルの開設
   - シェル / コマンド実行

2.2 認証メカニズム

方式説明セキュリティ
公開鍵認証秘密鍵/公開鍵ペアによる認証非常に高い
パスワード認証パスワードによる認証中程度
キーボードインタラクティブチャレンジ・レスポンス(PAM 等)中~高
GSSAPIKerberos 等の認証高い
証明書認証SSH CA 署名の証明書非常に高い

2.3 暗号化とキー交換

鍵交換アルゴリズム

# サポートされる鍵交換アルゴリズムの確認
$ ssh -Q kex
curve25519-sha256
curve25519-sha256@libssh.org
diffie-hellman-group-exchange-sha256
diffie-hellman-group16-sha512
diffie-hellman-group18-sha512
ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521
sntrup761x25519-sha512@openssh.com

暗号アルゴリズム

# サポートされる暗号アルゴリズムの確認
$ ssh -Q cipher
chacha20-poly1305@openssh.com
aes128-ctr
aes192-ctr
aes256-ctr
aes128-gcm@openssh.com
aes256-gcm@openssh.com

# サポートされる MAC アルゴリズム
$ ssh -Q mac
hmac-sha2-256
hmac-sha2-512
hmac-sha2-256-etm@openssh.com
hmac-sha2-512-etm@openssh.com

# サポートされる鍵タイプ
$ ssh -Q key
ssh-ed25519
ssh-ed25519-cert-v01@openssh.com
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
ssh-rsa
rsa-sha2-256
rsa-sha2-512

3. sshd_config(サーバー設定)詳細

設定ファイル: /etc/ssh/sshd_config

3.1 基本設定

# リスニング設定
Port 22                          # SSHポート(変更推奨)
# Port 2222                      # 非標準ポート
AddressFamily any                # inet (IPv4), inet6 (IPv6), any (両方)
ListenAddress 0.0.0.0            # リスニングアドレス (IPv4)
ListenAddress ::                 # リスニングアドレス (IPv6)

# プロトコル
Protocol 2                       # SSH-2 のみ(デフォルト)

# ホストキー
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

# ロギング
SyslogFacility AUTH
LogLevel INFO                    # VERBOSE にするとより詳細なログ
# LogLevel VERBOSE               # 鍵のフィンガープリント等を記録

3.2 認証設定

# ログイン制限
LoginGraceTime 60                # ログイン猶予時間(秒)
MaxAuthTries 3                   # 最大認証試行回数
MaxSessions 10                   # 接続あたりの最大セッション数

# root ログインの制限
PermitRootLogin no               # root ログインを禁止
# PermitRootLogin prohibit-password  # 鍵認証のみ許可
# PermitRootLogin forced-commands-only  # 特定コマンドのみ許可

# パスワード認証
PasswordAuthentication no        # パスワード認証を無効化
PermitEmptyPasswords no          # 空パスワードを禁止

# 公開鍵認証
PubkeyAuthentication yes         # 公開鍵認証を有効化
AuthorizedKeysFile .ssh/authorized_keys

# キーボードインタラクティブ認証
KbdInteractiveAuthentication no  # チャレンジ・レスポンス認証を無効化
# ChallengeResponseAuthentication no  # 旧名称

# GSSAPI 認証
GSSAPIAuthentication no
GSSAPICleanupCredentials yes

# PAM
UsePAM yes                       # PAM を使用(多くの場合必要)

3.3 アクセス制御

# ユーザーベースのアクセス制御
AllowUsers admin deployer webmaster
# DenyUsers testuser guest

# グループベースのアクセス制御
AllowGroups sshusers wheel
# DenyGroups noremote

# ネットワークベースの制限(Match ブロック内)
Match Address 192.168.1.0/24
    PasswordAuthentication yes

Match Address 10.0.0.0/8
    AllowUsers admin

# ユーザーごとのカスタム設定
Match User deployer
    ForceCommand /usr/local/bin/deploy.sh
    AllowTcpForwarding no
    X11Forwarding no

Match User sftponly
    ChrootDirectory /var/sftp/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no

3.4 セッション管理

# キープアライブ
ClientAliveInterval 300          # 5分ごとにキープアライブを送信
ClientAliveCountMax 3            # 3回応答がなければ切断

# 接続タイムアウト
TCPKeepAlive yes                 # TCP キープアライブ

# X11 フォワーディング
X11Forwarding no                 # X11 転送を無効化(推奨)
# X11Forwarding yes
# X11DisplayOffset 10
# X11UseLocalhost yes

# TCP フォワーディング
AllowTcpForwarding no            # ポートフォワーディングを無効化(必要に応じて有効化)
# AllowTcpForwarding yes
# AllowTcpForwarding local       # ローカルのみ許可
# GatewayPorts no                # 他のホストからのフォワーディング接続を禁止

# エージェント転送
AllowAgentForwarding no          # エージェント転送を無効化

# StreamLocal フォワーディング
AllowStreamLocalForwarding no

# バナー
Banner /etc/ssh/banner.txt       # ログイン前のバナー表示
PrintMotd yes                    # /etc/motd の表示
PrintLastLog yes                 # 最終ログイン情報の表示

# 環境変数
AcceptEnv LANG LC_*              # 受け入れる環境変数

3.5 暗号化設定

# 推奨される暗号化設定(2026年時点)

# 鍵交換アルゴリズム
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

# 暗号アルゴリズム
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

# MAC アルゴリズム
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256

# ホストキーアルゴリズム
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

# 公開鍵認証の受け入れアルゴリズム
PubkeyAcceptedAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

設定の適用と検証

# 設定ファイルの構文チェック
$ sudo sshd -t
# エラーがなければ出力なし

# 設定ファイルの拡張表示(全設定を表示)
$ sudo sshd -T

# 特定のユーザー/ホストの設定確認
$ sudo sshd -T -C user=admin,host=192.168.1.10,addr=192.168.1.10

# サービスの再起動
$ sudo systemctl reload sshd
$ sudo systemctl restart sshd

4. ssh_config(クライアント設定)詳細

4.1 グローバルとユーザー設定

# グローバル設定
/etc/ssh/ssh_config

# ユーザー設定(優先度が高い)
~/.ssh/config

4.2 Host ブロック

# ~/.ssh/config

# デフォルト設定(全ホストに適用)
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes
    IdentitiesOnly yes
    HashKnownHosts yes

# 特定のサーバー
Host webserver
    HostName 192.168.1.10
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_web

Host dbserver
    HostName 192.168.1.20
    User dbadmin
    Port 22
    IdentityFile ~/.ssh/id_ed25519_db
    LocalForward 3306 localhost:3306

# ワイルドカード
Host *.internal.example.com
    User admin
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519_internal

# 踏み台(bastion)サーバー
Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_bastion
    ForwardAgent no

# 開発環境
Host dev-*
    User developer
    IdentityFile ~/.ssh/id_ed25519_dev
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel ERROR

4.3 接続の最適化

# ~/.ssh/config

Host *
    # 接続多重化
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

    # 圧縮
    Compression yes

    # 接続維持
    ServerAliveInterval 60
    ServerAliveCountMax 3
    TCPKeepAlive yes

    # 認証の最適化
    IdentitiesOnly yes          # 明示的に指定した鍵のみ使用
    AddKeysToAgent yes          # 使用した鍵を自動でエージェントに追加

    # 接続速度の改善
    # Ciphers chacha20-poly1305@openssh.com,aes128-gcm@openssh.com

5. 鍵ベースの認証

5.1 ssh-keygen

# Ed25519 鍵の生成(推奨)
$ ssh-keygen -t ed25519 -C "user@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX user@example.com
The key's randomart image is:
+--[ED25519 256]--+
|        ..o.     |
|       . +o.     |
|        oo=.     |
|       .o+.+     |
|      ..S.o .    |
|     . .o=       |
|    o  .+.       |
|   . ...o+       |
|    ..oooo+      |
+----[SHA256]-----+

# RSA 鍵の生成(4096ビット以上推奨)
$ ssh-keygen -t rsa -b 4096 -C "user@example.com"

# ECDSA 鍵の生成
$ ssh-keygen -t ecdsa -b 521 -C "user@example.com"

# 特定のファイル名で生成
$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "work-key"

# パスフレーズの変更
$ ssh-keygen -p -f ~/.ssh/id_ed25519

# 公開鍵のフィンガープリント確認
$ ssh-keygen -l -f ~/.ssh/id_ed25519.pub
256 SHA256:XXXXXXXXXX user@example.com (ED25519)

# 公開鍵の表示
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIxxxx user@example.com

# known_hosts からエントリを削除
$ ssh-keygen -R hostname
$ ssh-keygen -R 192.168.1.10

# 鍵の変換(OpenSSH → PEM)
$ ssh-keygen -p -m PEM -f ~/.ssh/id_rsa

5.2 ssh-copy-id

# 公開鍵をリモートサーバーにコピー
$ ssh-copy-id user@remote-server
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed
user@remote-server's password:
Number of key(s) added: 1

# 特定の鍵を指定してコピー
$ ssh-copy-id -i ~/.ssh/id_ed25519_work.pub user@remote-server

# 非標準ポートのサーバーにコピー
$ ssh-copy-id -p 2222 user@remote-server

# 手動でのコピー(ssh-copy-id が使えない場合)
$ cat ~/.ssh/id_ed25519.pub | ssh user@remote-server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

5.3 SSH エージェント

# SSH エージェントの起動
$ eval $(ssh-agent -s)
Agent pid 12345

# 鍵の追加
$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/user/.ssh/id_ed25519:
Identity added: /home/user/.ssh/id_ed25519 (user@example.com)

# 登録済み鍵の一覧
$ ssh-add -l
256 SHA256:XXXXXXXXXX user@example.com (ED25519)

# 全ての鍵を削除
$ ssh-add -D

# 鍵のロック/アンロック
$ ssh-add -x    # ロック(パスワード設定)
$ ssh-add -X    # アンロック

# 有効期限付きで鍵を追加
$ ssh-add -t 3600 ~/.ssh/id_ed25519  # 1時間

systemd での SSH エージェント自動起動

# ~/.config/systemd/user/ssh-agent.service
[Unit]
Description=SSH Key Agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

# 有効化
$ systemctl --user enable ssh-agent
$ systemctl --user start ssh-agent

# ~/.bashrc に追加
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

5.4 エージェント転送

# エージェント転送を有効にして接続
$ ssh -A user@bastion-server

# ~/.ssh/config での設定
Host bastion
    ForwardAgent yes

# 注意: エージェント転送はセキュリティリスクがある
# 信頼できないサーバーでは使用しない
# ProxyJump の使用を推奨

6. SSH トンネリング

6.1 ローカルポートフォワーディング

ローカルポートへの接続をリモートサーバー経由で別のホストに転送する。

# 構文: ssh -L [bind_address:]local_port:remote_host:remote_port user@ssh_server

# 例: ローカルの 3306 をリモートの MySQL に転送
$ ssh -L 3306:localhost:3306 user@db-server
# ローカルで mysql -h 127.0.0.1 -P 3306 で接続可能

# 例: ローカルの 8080 をリモートの内部 Web サーバーに転送
$ ssh -L 8080:internal-web:80 user@bastion
# ブラウザで http://localhost:8080 でアクセス可能

# 全インターフェースでリスン
$ ssh -L 0.0.0.0:8080:internal-web:80 user@bastion

# バックグラウンドで実行(-f: バックグラウンド、-N: コマンド実行なし)
$ ssh -fNL 8080:internal-web:80 user@bastion

# 複数のポートフォワーディング
$ ssh -L 3306:db-server:3306 -L 6379:redis-server:6379 user@bastion

6.2 リモートポートフォワーディング

リモートサーバーのポートへの接続をローカルまたは別のホストに転送する。

# 構文: ssh -R [bind_address:]remote_port:local_host:local_port user@ssh_server

# 例: リモートサーバーの 8080 をローカルの Web サーバーに転送
$ ssh -R 8080:localhost:80 user@remote-server
# リモートサーバーで curl http://localhost:8080 でローカルにアクセス可能

# 外部からアクセス可能にする(サーバー側で GatewayPorts yes が必要)
$ ssh -R 0.0.0.0:8080:localhost:80 user@remote-server

# バックグラウンドで実行
$ ssh -fNR 8080:localhost:80 user@remote-server

6.3 ダイナミックフォワーディング(SOCKS プロキシ)

# 構文: ssh -D [bind_address:]port user@ssh_server

# SOCKS5 プロキシの作成
$ ssh -D 1080 user@proxy-server
# ブラウザのプロキシ設定で SOCKS5 localhost:1080 を指定

# バックグラウンドで実行
$ ssh -fND 1080 user@proxy-server

# curl での使用
$ curl --socks5 localhost:1080 http://internal-site.example.com

# proxychains での使用
$ proxychains nmap -sT internal-host

7. ProxyJump と ProxyCommand

7.1 ProxyJump(推奨)

# コマンドラインで使用
$ ssh -J bastion user@internal-server

# 複数の踏み台を経由
$ ssh -J bastion1,bastion2 user@internal-server

# ~/.ssh/config での設定
Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_bastion

Host internal-*
    ProxyJump bastion
    User admin
    IdentityFile ~/.ssh/id_ed25519_internal

Host internal-web
    HostName 192.168.1.10

Host internal-db
    HostName 192.168.1.20

7.2 ProxyCommand

# ~/.ssh/config
Host internal-server
    HostName 192.168.1.10
    User admin
    ProxyCommand ssh -W %h:%p bastion

# nc(netcat)を使用する場合
Host internal-server
    ProxyCommand ssh bastion nc %h %p

# AWS SSM を経由する場合
Host i-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

8. SSH 証明書

8.1 SSH CA の概要

SSH 証明書は、認証局(CA)による署名済み鍵を使用して、known_hosts や authorized_keys の管理を簡素化する仕組みである。

8.2 CA の構築と運用

# CA 鍵の生成
$ ssh-keygen -t ed25519 -f /etc/ssh/ca_key -C "SSH CA Key"

# ホスト証明書の署名
$ ssh-keygen -s /etc/ssh/ca_key -I "webserver01" -h -n webserver01.example.com -V +52w /etc/ssh/ssh_host_ed25519_key.pub
# -s: CA秘密鍵
# -I: 証明書ID
# -h: ホスト証明書
# -n: プリンシパル(ホスト名)
# -V: 有効期間(52週間)

# ユーザー証明書の署名
$ ssh-keygen -s /etc/ssh/ca_key -I "user@example.com" -n admin,deployer -V +30d ~/.ssh/id_ed25519.pub
# -n: プリンシパル(許可されるユーザー名)
# -V: 有効期間(30日)

# 証明書の内容確認
$ ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub
/home/user/.ssh/id_ed25519-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:XXXXXXXXXX
        Signing CA: ED25519 SHA256:YYYYYYYYYY (using ssh-ed25519)
        Key ID: "user@example.com"
        Serial: 0
        Valid: from 2026-04-10T10:00:00 to 2026-05-10T10:00:00
        Principals:
                admin
                deployer
        Critical Options: (none)
        Extensions:
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

サーバー側の設定

# sshd_config
# ユーザー証明書の CA 公開鍵を信頼
TrustedUserCAKeys /etc/ssh/ca_key.pub

# ホスト証明書の使用
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

# プリンシパルの制限
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u

クライアント側の設定

# known_hosts に CA 公開鍵を追加
# ~/.ssh/known_hosts
@cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... SSH CA Key

9. fail2ban 連携

9.1 fail2ban のインストールと設定

# インストール
$ sudo apt install fail2ban    # Debian/Ubuntu
$ sudo yum install fail2ban    # RHEL/CentOS

# サービスの有効化
$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban

9.2 SSH 用の設定

# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600              # 1時間のBAN
findtime = 600              # 10分間の監視期間
maxretry = 3                # 最大試行回数
banaction = iptables-multiport
backend = systemd

[sshd]
enabled = true
port = ssh                  # またはカスタムポート: 2222
filter = sshd
logpath = /var/log/auth.log  # Debian/Ubuntu
# logpath = /var/log/secure  # RHEL/CentOS
maxretry = 3
bantime = 3600
findtime = 600

# 繰り返しのBAN
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800            # 1週間
findtime = 86400            # 1日間
maxretry = 3                # 3回BANされたら

9.3 fail2ban の管理

# ステータス確認
$ sudo fail2ban-client status
Status
|- Number of jail:      2
`- Jail list:   recidive, sshd

# SSH jail のステータス
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     45
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     12
   `- Banned IP list:   10.0.0.100 10.0.0.101 10.0.0.102

# IP のBAN解除
$ sudo fail2ban-client set sshd unbanip 10.0.0.100

# 手動でBAN
$ sudo fail2ban-client set sshd banip 10.0.0.200

# jail のリロード
$ sudo fail2ban-client reload sshd

10. ポートノッキング

10.1 概要

ポートノッキングは、特定のポートシーケンスへのアクセスをトリガーとして、ファイアウォールルールを動的に変更する仕組みである。

10.2 knockd の設定

# インストール
$ sudo apt install knockd

# /etc/knockd.conf
[options]
    UseSyslog
    Interface = eth0

[openSSH]
    sequence    = 7000,8000,9000
    seq_timeout = 5
    command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn

[closeSSH]
    sequence    = 9000,8000,7000
    seq_timeout = 5
    command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn

# knockd の有効化
# /etc/default/knockd
START_KNOCKD=1

$ sudo systemctl enable knockd
$ sudo systemctl start knockd

10.3 ノッキングの実行

# knock コマンドで接続前にノック
$ knock server.example.com 7000 8000 9000

# SSH 接続
$ ssh user@server.example.com

# 切断後にポートを閉じる
$ knock server.example.com 9000 8000 7000

# nmap でのノック
$ nmap -Pn --host-timeout 100 --max-retries 0 -p 7000 server.example.com
$ nmap -Pn --host-timeout 100 --max-retries 0 -p 8000 server.example.com
$ nmap -Pn --host-timeout 100 --max-retries 0 -p 9000 server.example.com

11. SSH ハードニングベストプラクティス

11.1 推奨される sshd_config(完全版)

# /etc/ssh/sshd_config - ハードニング設定

# === 基本設定 ===
Port 2222
AddressFamily inet
ListenAddress 0.0.0.0
Protocol 2

# === ホストキー ===
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

# === 暗号化 ===
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

# === 認証 ===
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 5

PermitRootLogin no
StrictModes yes

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no

GSSAPIAuthentication no
UsePAM yes

# === アクセス制御 ===
AllowGroups sshusers
# AllowUsers admin deployer

# === セッション ===
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive no

X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
AllowStreamLocalForwarding no
PermitTunnel no
GatewayPorts no

# === その他 ===
Banner /etc/ssh/banner.txt
PrintMotd no
PrintLastLog yes
PermitUserEnvironment no
Compression delayed
UseDNS no

# === ロギング ===
SyslogFacility AUTH
LogLevel VERBOSE

# === SFTP 専用ユーザー ===
Match Group sftponly
    ChrootDirectory /var/sftp/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    AllowAgentForwarding no
    X11Forwarding no
    PermitTunnel no

11.2 ファイルパーミッション

# サーバー側
$ sudo chmod 600 /etc/ssh/sshd_config
$ sudo chmod 600 /etc/ssh/ssh_host_*_key
$ sudo chmod 644 /etc/ssh/ssh_host_*_key.pub

# クライアント側
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/config
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 644 ~/.ssh/known_hosts

11.3 追加のハードニング手順

# 1. 弱いモジュラスの削除(Diffie-Hellman)
$ sudo awk '$5 >= 3071' /etc/ssh/moduli > /tmp/moduli.safe
$ sudo mv /tmp/moduli.safe /etc/ssh/moduli

# 2. SSH ポートの変更
# sshd_config: Port 2222
# ファイアウォールの更新
$ sudo firewall-cmd --add-port=2222/tcp --permanent
$ sudo firewall-cmd --remove-service=ssh --permanent
$ sudo firewall-cmd --reload

# 3. SELinux でのポート変更
$ sudo semanage port -a -t ssh_port_t -p tcp 2222

# 4. 2FA(二要素認証)の導入
$ sudo apt install libpam-google-authenticator
# /etc/pam.d/sshd に追加:
# auth required pam_google_authenticator.so
# sshd_config:
# KbdInteractiveAuthentication yes
# AuthenticationMethods publickey,keyboard-interactive

# 5. 不要なホストキーの削除
$ sudo rm /etc/ssh/ssh_host_dsa_key*
$ sudo rm /etc/ssh/ssh_host_ecdsa_key*  # 必要に応じて

# 6. バナーの設定
$ sudo tee /etc/ssh/banner.txt << 'EOF'
*******************************************************************
*  WARNING: Unauthorized access to this system is prohibited.     *
*  All activities on this system are logged and monitored.        *
*  By accessing this system, you consent to these terms.          *
*******************************************************************
EOF

12. 多重化(Multiplexing)

12.1 ControlMaster の設定

# ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600        # 10分間マスター接続を維持

# ソケットディレクトリの作成
$ mkdir -p ~/.ssh/sockets
$ chmod 700 ~/.ssh/sockets

12.2 多重化の使用

# 最初の接続(マスター接続が確立される)
$ ssh user@server
# 認証が行われる

# 2番目の接続(マスター接続を再利用、認証不要)
$ ssh user@server
# 即座に接続

# マスター接続の状態確認
$ ssh -O check user@server
Master running (pid=12345)

# マスター接続の終了
$ ssh -O exit user@server

# マスター接続のフォワーディング追加
$ ssh -O forward -L 8080:localhost:80 user@server

# マスター接続のフォワーディング削除
$ ssh -O cancel -L 8080:localhost:80 user@server

13. SCP / SFTP / rsync over SSH

13.1 SCP(Secure Copy)

# ローカルからリモートにコピー
$ scp file.txt user@server:/remote/path/

# リモートからローカルにコピー
$ scp user@server:/remote/file.txt /local/path/

# ディレクトリの再帰的コピー
$ scp -r /local/dir/ user@server:/remote/dir/

# 非標準ポート
$ scp -P 2222 file.txt user@server:/remote/path/

# 帯域制限
$ scp -l 1000 largefile.tar.gz user@server:/remote/path/  # 1000 Kbit/s

# 踏み台経由
$ scp -o ProxyJump=bastion file.txt user@internal:/path/

# 注意: scp は非推奨(sftp または rsync を推奨)

13.2 SFTP

# SFTP 接続
$ sftp user@server

# SFTP コマンド
sftp> ls
sftp> cd /remote/path
sftp> lcd /local/path
sftp> get remote_file.txt
sftp> put local_file.txt
sftp> get -r remote_dir/
sftp> put -r local_dir/
sftp> mkdir new_dir
sftp> rm file.txt
sftp> bye

# バッチモード
$ sftp -b batch_commands.txt user@server

# batch_commands.txt の内容
cd /remote/path
get file1.txt
get file2.txt
bye

# 非標準ポート
$ sftp -P 2222 user@server

# 踏み台経由
$ sftp -J bastion user@internal

13.3 rsync over SSH

# 基本的なrsync over SSH
$ rsync -avz /local/dir/ user@server:/remote/dir/

# 削除の同期
$ rsync -avz --delete /local/dir/ user@server:/remote/dir/

# 非標準ポート
$ rsync -avz -e "ssh -p 2222" /local/dir/ user@server:/remote/dir/

# 帯域制限
$ rsync -avz --bwlimit=1000 /local/dir/ user@server:/remote/dir/

# ドライラン(実際にはコピーしない)
$ rsync -avzn /local/dir/ user@server:/remote/dir/

# 特定のファイルを除外
$ rsync -avz --exclude='*.log' --exclude='.git/' /local/dir/ user@server:/remote/dir/

# 踏み台経由
$ rsync -avz -e "ssh -J bastion" /local/dir/ user@internal:/remote/dir/

# 進捗表示
$ rsync -avz --progress /local/dir/ user@server:/remote/dir/

# 圧縮レベルの指定
$ rsync -avz --compress-level=9 /local/dir/ user@server:/remote/dir/

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

14.1 一般的な問題

# 詳細なデバッグ出力
$ ssh -vvv user@server

# サーバー側のデバッグ
$ sudo /usr/sbin/sshd -d -p 2222

# パーミッションの問題
$ ls -la ~/.ssh/
$ ls -la ~/.ssh/authorized_keys
# authorized_keys は 600、.ssh は 700 であること

# known_hosts の問題
$ ssh-keygen -R server-hostname

# 接続のテスト
$ ssh -o ConnectTimeout=5 user@server

# SELinux の問題(RHEL/CentOS)
$ sudo ausearch -m AVC -c sshd | audit2why
$ sudo restorecon -Rv ~/.ssh/

# ファイアウォールの確認
$ sudo ss -tlnp | grep sshd
$ sudo iptables -L -n | grep 22

14.2 よくあるエラーと対処

エラー原因対処
Permission denied (publickey)鍵認証の失敗鍵のパーミッション確認、authorized_keys の確認
Host key verification failedホストキーの変更ssh-keygen -R で古いエントリを削除
Connection refusedsshd が起動していない、ポートが違うsystemctl status sshd、ファイアウォール確認
Connection timed outネットワーク接続の問題ping、traceroute、ファイアウォール確認
Too many authentication failures認証試行回数超過IdentitiesOnly yes を設定
No matching key exchange methodアルゴリズムの不一致KexAlgorithms の設定を確認

15. 比較表

15.1 SSH 鍵タイプ比較

鍵タイプビット長セキュリティパフォーマンス推奨度
Ed25519256非常に高い非常に高速最推奨
ECDSA256/384/521高い高速推奨
RSA2048/4096高い(4096bit)中程度互換性が必要な場合
DSA1024低い低い使用禁止

15.2 ファイル転送方式比較

方式暗号化再開差分転送帯域制限推奨用途
scpSSH不可不可非推奨
sftpSSH不可ファイル操作全般
rsyncSSH大量/定期同期

16. 参考文献

  1. OpenSSH 公式: https://www.openssh.com/
  2. OpenSSH man pages: man ssh, man sshd_config, man ssh_config
  3. Mozilla SSH Guidelines: https://infosec.mozilla.org/guidelines/openssh
  4. CIS Benchmark - SSH: https://www.cisecurity.org/cis-benchmarks
  5. NIST SP 800-123: Guide to General Server Security
  6. fail2ban 公式: https://www.fail2ban.org/
  7. SSH Mastery (Michael W Lucas): 書籍
  8. Arch Linux Wiki - SSH: https://wiki.archlinux.org/title/OpenSSH
  9. ssh-audit ツール: https://github.com/jtesta/ssh-audit
  10. DISA STIG for SSH: https://public.cyber.mil/stigs/

本ドキュメントは 2026年4月時点の情報に基づいて作成されています。