はじめに:SSH、リモートサーバー管理の核心

SSH(Secure Shell)は、ネットワークを通じて安全にリモートサーバーに接続・管理するためのプロトコルです。暗号化通信でデータを保護し、現代のサーバー運用において最も重要なツールの一つです。今回はSSHの基礎から高度な活用法まで解説します。

1. SSHの基礎

1.1 SSH接続の基本

# 基本接続
ssh username@hostname

# 特定ポートで接続
ssh -p 2222 username@hostname

# IPアドレスで接続
ssh user@192.168.1.100

# 詳細デバッグモード
ssh -v username@hostname
ssh -vvv username@hostname  # より詳細な情報

1.2 SSHサーバーのインストールと状態確認

# Ubuntu/Debian
sudo apt update
sudo apt install openssh-server

# RHEL/CentOS
sudo dnf install openssh-server

# SSHサーバーの状態確認
sudo systemctl status sshd

# サービスの開始/停止/再起動
sudo systemctl start sshd
sudo systemctl stop sshd
sudo systemctl restart sshd

# 起動時の自動開始
sudo systemctl enable sshd

1.3 SSH接続の切断

# 通常の終了
exit
logout
Ctrl + D

# セッションがフリーズした場合の強制切断
~.    # Enterを押してから~.を入力

2. SSH鍵認証

2.1 鍵ペアの生成

# RSA鍵の生成(デフォルト)
ssh-keygen -t rsa -b 4096

# Ed25519鍵の生成(推奨、より安全で高速)
ssh-keygen -t ed25519

# 特定のファイル名で生成
ssh-keygen -t ed25519 -f ~/.ssh/myserver_key

# コメントを追加
ssh-keygen -t ed25519 -C "admin@company.com"

# 生成されたファイルを確認
ls -la ~/.ssh/
# id_ed25519      - 秘密鍵(絶対に共有しない)
# id_ed25519.pub  - 公開鍵(サーバーに登録)

2.2 公開鍵をサーバーに登録

# ssh-copy-idを使用(最も簡単な方法)
ssh-copy-id username@hostname
ssh-copy-id -i ~/.ssh/myserver_key.pub username@hostname

# 手動登録
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# またはサーバーで直接
# ~/.ssh/authorized_keysファイルに公開鍵の内容を追加

# 権限設定(重要!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

2.3 鍵認証での接続

# デフォルト鍵で接続
ssh username@hostname

# 特定の鍵を指定
ssh -i ~/.ssh/myserver_key username@hostname

# パスフレーズ入力を省略(ssh-agent)
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
ssh-add -l  # 登録された鍵を確認

3. SSH設定ファイル

3.1 クライアント設定(~/.ssh/config)

# ~/.ssh/config の例
# Webサーバー
Host webserver
    HostName 192.168.1.10
    User admin
    Port 22
    IdentityFile ~/.ssh/webserver_key

# 開発サーバー(エイリアス使用)
Host dev
    HostName dev.company.com
    User developer
    Port 2222

# DBサーバー(踏み台サーバー経由)
Host dbserver
    HostName 10.0.0.50
    User dbadmin
    ProxyJump webserver

# 全ホスト共通設定
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes

# これで簡単に接続可能
# ssh webserver
# ssh dev

3.2 サーバー設定(/etc/ssh/sshd_config)

# 主要なセキュリティ設定
# ポート変更
Port 2222

# rootログイン無効化
PermitRootLogin no

# パスワード認証無効化(鍵認証のみ許可)
PasswordAuthentication no

# 空パスワード禁止
PermitEmptyPasswords no

# 特定ユーザーのみ許可
AllowUsers admin deploy

# 特定グループのみ許可
AllowGroups sshusers

# ログイン試行制限
MaxAuthTries 3

# 最大セッション数
MaxSessions 5

# X11フォワーディング無効化
X11Forwarding no

# 設定適用
sudo sshd -t  # 構文チェック
sudo systemctl restart sshd

4. ファイル転送:SCPとSFTP

4.1 SCP(Secure Copy)

# ローカル → リモート(ファイル)
scp file.txt user@host:/path/to/destination/

# ローカル → リモート(ディレクトリ)
scp -r mydir/ user@host:/path/to/destination/

# リモート → ローカル
scp user@host:/path/to/file.txt ./local/

# 別のポートを使用
scp -P 2222 file.txt user@host:/path/

# 特定の鍵を使用
scp -i ~/.ssh/mykey file.txt user@host:/path/

# 圧縮転送(大容量ファイルに有用)
scp -C largefile.zip user@host:/path/

# 帯域幅制限(KB/s)
scp -l 1000 file.txt user@host:/path/

# サーバー間転送
scp user1@host1:/file.txt user2@host2:/path/

4.2 SFTP(SSHファイル転送プロトコル)

# SFTP接続
sftp user@host
sftp -P 2222 user@host

# SFTPコマンド
sftp> pwd           # リモートの現在ディレクトリ
sftp> lpwd          # ローカルの現在ディレクトリ
sftp> ls            # リモートファイル一覧
sftp> lls           # ローカルファイル一覧
sftp> cd /path      # リモートディレクトリ移動
sftp> lcd /path     # ローカルディレクトリ移動
sftp> get file.txt  # ダウンロード
sftp> get -r dir/   # ディレクトリをダウンロード
sftp> put file.txt  # アップロード
sftp> put -r dir/   # ディレクトリをアップロード
sftp> rm file.txt   # 削除
sftp> mkdir newdir  # ディレクトリ作成
sftp> exit          # 終了

4.3 rsync over SSH

# 基本同期
rsync -avz source/ user@host:/destination/

# 削除されたファイルも同期
rsync -avz --delete source/ user@host:/destination/

# 別のポートを使用
rsync -avz -e "ssh -p 2222" source/ user@host:/dest/

# 進捗表示
rsync -avz --progress source/ user@host:/dest/

# テスト実行(dry-run)
rsync -avzn source/ user@host:/dest/

5. SSHトンネリング(ポートフォワーディング)

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

ローカルマシンのポートをリモートサーバー経由で他のサーバーに接続します。

# 構文:ssh -L [ローカルポート]:[対象ホスト]:[対象ポート] [SSHサーバー]

# 例:ローカル3306でリモートDBサーバーに接続
ssh -L 3306:localhost:3306 user@sshserver

# 例:リモートサーバー背後の別サーバーにアクセス
ssh -L 8080:internal-web.lan:80 user@sshserver

# バックグラウンド実行
ssh -fNL 3306:localhost:3306 user@sshserver

# localhost:3306でDB接続可能
mysql -h localhost -P 3306 -u dbuser -p

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

リモートサーバーのポートをローカルマシンに接続します。

# 構文:ssh -R [リモートポート]:[ローカルホスト]:[ローカルポート] [SSHサーバー]

# 例:リモートサーバーの8080をローカルの80に接続
ssh -R 8080:localhost:80 user@sshserver

# 外部からリモートサーバーの8080にアクセスするとローカル80に転送

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

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

# SOCKSプロキシ作成
ssh -D 1080 user@sshserver

# バックグラウンド実行
ssh -fND 1080 user@sshserver

# ブラウザやアプリでSOCKS5プロキシ設定
# プロキシ:localhost:1080

5.4 踏み台ホスト(プロキシジャンプ)

# -Jオプション使用(OpenSSH 7.3以降)
ssh -J jumphost user@targetserver

# 複数の踏み台ホスト
ssh -J jump1,jump2 user@target

# 旧方式(-o ProxyCommand)
ssh -o ProxyCommand="ssh -W %h:%p jumphost" user@target

# ~/.ssh/configで設定
Host internal
    HostName 10.0.0.50
    User admin
    ProxyJump jumphost

6. SSHセキュリティ強化

6.1 sshd_configセキュリティ設定

# /etc/ssh/sshd_config

# パスワード認証無効化(鍵のみ許可)
PasswordAuthentication no
ChallengeResponseAuthentication no

# rootログイン禁止
PermitRootLogin no

# 空パスワード禁止
PermitEmptyPasswords no

# キーボードインタラクティブ認証無効化
KbdInteractiveAuthentication no

# プロトコルバージョン2のみ許可(デフォルト)
Protocol 2

# ログイン試行制限
MaxAuthTries 3
LoginGraceTime 30

# 特定IPからのみ接続許可(sshd_configまたはファイアウォール)
# AllowUsers admin@192.168.1.0/24

# TCPフォワーディング制限
AllowTcpForwarding no
AllowAgentForwarding no

# 強力な暗号化アルゴリズムのみ許可
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# 設定適用前に構文チェック
sudo sshd -t
sudo systemctl restart sshd

6.2 Fail2Banのインストール

# Ubuntu/Debian
sudo apt install fail2ban

# RHEL/CentOS
sudo dnf install fail2ban

# 設定ファイル作成
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# /etc/fail2ban/jail.local を編集
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log   # Debian/Ubuntu
# logpath = /var/log/secure   # RHEL/CentOS
maxretry = 3
bantime = 3600
findtime = 600

# サービス開始
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 状態確認
sudo fail2ban-client status sshd

6.3 二段階認証(2FA)

# Google Authenticatorインストール
sudo apt install libpam-google-authenticator

# 設定初期化
google-authenticator

# PAM設定(/etc/pam.d/sshd)
auth required pam_google_authenticator.so

# sshd_config設定
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

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

7. SSHエージェントと鍵管理

7.1 SSHエージェントの使用

# エージェント開始
eval $(ssh-agent)

# 鍵追加
ssh-add                      # デフォルト鍵
ssh-add ~/.ssh/mykey        # 特定の鍵
ssh-add -t 3600 ~/.ssh/key  # 1時間後に自動削除

# 登録された鍵を確認
ssh-add -l

# 鍵削除
ssh-add -d ~/.ssh/mykey     # 特定の鍵
ssh-add -D                  # すべての鍵

# エージェント終了
ssh-agent -k

7.2 SSHエージェントフォワーディング

# -Aオプションでエージェントフォワーディング
ssh -A user@server1

# server1からローカル鍵で他のサーバーに接続可能
ssh user@server2

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

# 注意:信頼できるサーバーでのみ使用

7.3 鍵管理のベストプラクティス

# 用途別に鍵を分離
ssh-keygen -t ed25519 -f ~/.ssh/work_key -C "work"
ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "personal"

# 強力なパスフレーズを設定
ssh-keygen -t ed25519 -f ~/.ssh/mykey
# (対話形式でパスフレーズを入力)

# 鍵の権限を確認
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 700 ~/.ssh

# 古い鍵の交換
# 1. 新しい鍵を生成
# 2. サーバーに新しい鍵を登録
# 3. テスト
# 4. 古い鍵を削除

8. リモートサーバー管理のヒント

8.1 セッション維持(keepalive)

# クライアント設定(~/.ssh/config)
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

# サーバー設定(/etc/ssh/sshd_config)
ClientAliveInterval 60
ClientAliveCountMax 3

8.2 tmux/screenとの併用

# tmuxセッション作成
tmux new -s mysession

# セッション分離(Ctrl+B, D)
# SSH接続が切れても作業継続

# 再接続後にセッション復帰
tmux attach -t mysession

# セッション一覧
tmux ls

8.3 複数サーバーの同時管理

# 複数サーバーに同じコマンドを実行
for server in server1 server2 server3; do
    ssh $server "uptime"
done

# parallel-sshを使用
pssh -h hosts.txt -l user "uptime"

# Ansibleを使用(推奨)
ansible all -m ping
ansible all -a "uptime"

8.4 SSH接続の再利用

# ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

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

# 最初の接続後、追加接続が高速化

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

9.1 一般的なエラー

# Permission denied (publickey)
# → 鍵の権限を確認
chmod 600 ~/.ssh/id_*
chmod 700 ~/.ssh

# Host key verification failed
# → known_hostsから該当ホストを削除
ssh-keygen -R hostname

# Connection refused
# → SSHサーバーの実行を確認
sudo systemctl status sshd

# Connection timed out
# → ファイアウォールを確認
sudo ufw status
sudo firewall-cmd --list-all

9.2 デバッグモード

# クライアントデバッグ
ssh -v user@host    # 基本
ssh -vv user@host   # 詳細
ssh -vvv user@host  # 非常に詳細

# サーバーデバッグ(フォアグラウンド実行)
sudo /usr/sbin/sshd -d -p 2222

10. 実践:SSHセキュリティチェックリスト

# 1. 鍵認証を設定
ssh-keygen -t ed25519
ssh-copy-id user@server

# 2. パスワード認証を無効化
# /etc/ssh/sshd_config
PasswordAuthentication no

# 3. rootログインを禁止
PermitRootLogin no

# 4. ポート変更(オプション)
Port 2222

# 5. ファイアウォール設定
sudo ufw allow 2222/tcp
sudo ufw enable

# 6. Fail2Banインストール
sudo apt install fail2ban

# 7. 設定適用
sudo sshd -t && sudo systemctl restart sshd

# 8. テスト
ssh -p 2222 user@server

まとめ

SSHはリモートサーバー管理の核心ツールです。鍵認証を使用し、適切なセキュリティ設定を適用し、トンネリング機能を活用することで、安全で効率的なサーバー管理が可能です。次回は、シェルスクリプトの基礎でサーバー管理自動化の第一歩を踏み出します。