SSH Configuration and Hardening
SSH 設定とハードニング 完全ガイド
目次
- はじめに
- SSH アーキテクチャとプロトコル
- 2.1 SSH プロトコルの概要
- 2.2 認証メカニズム
- 2.3 暗号化とキー交換
- sshd_config(サーバー設定)詳細
- ssh_config(クライアント設定)詳細
- 4.1 グローバルとユーザー設定
- 4.2 Host ブロック
- 4.3 接続の最適化
- 鍵ベースの認証
- 5.1 ssh-keygen
- 5.2 ssh-copy-id
- 5.3 SSH エージェント
- 5.4 エージェント転送
- SSH トンネリング
- 6.1 ローカルポートフォワーディング
- 6.2 リモートポートフォワーディング
- 6.3 ダイナミックフォワーディング(SOCKS プロキシ)
- ProxyJump と ProxyCommand
- SSH 証明書
- fail2ban 連携
- ポートノッキング
- SSH ハードニングベストプラクティス
- 多重化(Multiplexing)
- SCP / SFTP / rsync over SSH
- トラブルシューティング
- 比較表
- 参考文献
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 等) | 中~高 |
| GSSAPI | Kerberos 等の認証 | 高い |
| 証明書認証 | 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 refused | sshd が起動していない、ポートが違う | systemctl status sshd、ファイアウォール確認 |
| Connection timed out | ネットワーク接続の問題 | ping、traceroute、ファイアウォール確認 |
| Too many authentication failures | 認証試行回数超過 | IdentitiesOnly yes を設定 |
| No matching key exchange method | アルゴリズムの不一致 | KexAlgorithms の設定を確認 |
15. 比較表
15.1 SSH 鍵タイプ比較
| 鍵タイプ | ビット長 | セキュリティ | パフォーマンス | 推奨度 |
|---|---|---|---|---|
| Ed25519 | 256 | 非常に高い | 非常に高速 | 最推奨 |
| ECDSA | 256/384/521 | 高い | 高速 | 推奨 |
| RSA | 2048/4096 | 高い(4096bit) | 中程度 | 互換性が必要な場合 |
| DSA | 1024 | 低い | 低い | 使用禁止 |
15.2 ファイル転送方式比較
| 方式 | 暗号化 | 再開 | 差分転送 | 帯域制限 | 推奨用途 |
|---|---|---|---|---|---|
| scp | SSH | 不可 | 不可 | 可 | 非推奨 |
| sftp | SSH | 可 | 不可 | 可 | ファイル操作全般 |
| rsync | SSH | 可 | 可 | 可 | 大量/定期同期 |
16. 参考文献
- OpenSSH 公式: https://www.openssh.com/
- OpenSSH man pages:
man ssh,man sshd_config,man ssh_config - Mozilla SSH Guidelines: https://infosec.mozilla.org/guidelines/openssh
- CIS Benchmark - SSH: https://www.cisecurity.org/cis-benchmarks
- NIST SP 800-123: Guide to General Server Security
- fail2ban 公式: https://www.fail2ban.org/
- SSH Mastery (Michael W Lucas): 書籍
- Arch Linux Wiki - SSH: https://wiki.archlinux.org/title/OpenSSH
- ssh-audit ツール: https://github.com/jtesta/ssh-audit
- DISA STIG for SSH: https://public.cyber.mil/stigs/
本ドキュメントは 2026年4月時点の情報に基づいて作成されています。