リモートサーバーへの安全な接続は、サーバー管理やクラウド開発において必須のスキルです。SSH(Secure Shell)は、暗号化された通信経路を確立し、パスワードやデータを保護しながらリモート操作を可能にするプロトコルです。

本記事では、SSH接続の基礎から実践的な活用方法まで、以下の内容を体系的に解説します。

  • SSHの仕組みと基本的な接続方法
  • ssh-keygenssh-copy-idを使った公開鍵認証の設定
  • ~/.ssh/configによる効率的なSSH接続管理
  • ポートフォワーディングとSSHトンネリングの活用
  • scpsftpによるセキュアなファイル転送

この記事を読むことで、安全なリモート接続を設定し、効率的にサーバーを操作できるようになります。

前提条件

本記事を理解するために、以下の知識があることを前提としています。

実行環境

本記事で使用するコマンドは以下の環境で動作確認を行っています。

項目 環境
クライアントOS Ubuntu 22.04/24.04、macOS Ventura以降、Windows 10/11(OpenSSH搭載)
サーバーOS Ubuntu 22.04/24.04、Rocky Linux 9、Debian 12
OpenSSHバージョン OpenSSH 8.9以降
権限 一般ユーザー(サーバー側設定の一部でsudoが必要)

Windows環境では、Windows 10以降に標準搭載されているOpenSSHクライアントを使用します。PowerShellまたはコマンドプロンプトからsshコマンドを実行できます。

期待される学習成果

本記事を読み終えると、以下のことができるようになります。

  1. SSHの基本的な仕組みを理解し、パスワード認証でリモートサーバーに接続できる
  2. 公開鍵認証を設定し、より安全なSSH接続を実現できる
  3. SSH設定ファイルで複数サーバーへの接続を効率的に管理できる
  4. ポートフォワーディングを使ってセキュアなトンネルを構築できる
  5. SCPとSFTPでファイルを安全に転送できる

SSHの仕組みと基本概念

SSHは、ネットワーク越しに別のコンピュータに安全にログインし、コマンドを実行するためのプロトコルです。すべての通信は暗号化されるため、パスワードやデータが第三者に盗聴されるリスクを大幅に低減できます。

SSHの認証方式

SSHには主に2つの認証方式があります。

flowchart LR
    subgraph AUTH["SSH認証方式"]
        direction TB
        PWD["パスワード認証<br/>ユーザー名とパスワードで認証"]
        KEY["公開鍵認証<br/>鍵ペア(公開鍵・秘密鍵)で認証"]
    end
    
    PWD -->|セキュリティ| LOW["低<br/>総当たり攻撃のリスク"]
    KEY -->|セキュリティ| HIGH["高<br/>推奨される認証方式"]
認証方式 概要 セキュリティ
パスワード認証 ユーザー名とパスワードで認証する 総当たり攻撃のリスクがある
公開鍵認証 公開鍵と秘密鍵のペアで認証する より安全で推奨される

本記事では両方の認証方式を解説しますが、実運用では公開鍵認証の使用を強く推奨します。

SSH接続の流れ

SSH接続では、クライアントとサーバー間で以下のような手順で通信が確立されます。

sequenceDiagram
    participant Client as SSHクライアント
    participant Server as SSHサーバー
    
    Client->>Server: 1. 接続要求(ポート22)
    Server->>Client: 2. サーバーの公開鍵を送信
    Client->>Client: 3. known_hostsでホスト鍵を検証
    Client->>Server: 4. 暗号化方式の合意
    Note over Client,Server: セキュアチャネル確立
    Client->>Server: 5. ユーザー認証(パスワードまたは公開鍵)
    Server->>Client: 6. 認証成功・シェル起動

基本的なSSH接続

まず、最もシンプルなSSH接続方法から始めましょう。

sshコマンドの基本構文

SSH接続の基本構文は以下のとおりです。

1
ssh [オプション] [ユーザー名@]ホスト名

リモートサーバーに接続する最も基本的なコマンドは以下のようになります。

1
2
3
4
5
6
7
8
# ユーザー名を指定して接続
ssh user@example.com

# ポート番号を指定して接続(デフォルトは22)
ssh -p 2222 user@example.com

# 同じユーザー名の場合(ローカルのユーザー名が使用される)
ssh example.com

初回接続時のホスト鍵確認

初めてサーバーに接続する際、以下のような確認メッセージが表示されます。

1
2
3
4
The authenticity of host 'example.com (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

これはサーバーの身元を確認するためのホスト鍵検証です。yesと入力すると、サーバーの公開鍵が~/.ssh/known_hostsファイルに保存され、次回以降は自動的に検証されます。

よく使うSSHオプション

オプション 説明 使用例
-p 接続ポートを指定 ssh -p 2222 user@host
-i 秘密鍵ファイルを指定 ssh -i ~/.ssh/mykey user@host
-v 詳細なデバッグ出力 ssh -v user@host
-N リモートコマンドを実行しない(トンネル用) ssh -N -L 8080:localhost:80 user@host
-f バックグラウンドで実行 ssh -f -N -L 8080:localhost:80 user@host
-J 踏み台サーバーを経由 ssh -J bastion@jump user@target

接続がうまくいかない場合は、-vオプション(さらに詳細な情報が必要な場合は-vv-vvv)を使用してデバッグ情報を確認しましょう。

1
2
# 詳細なデバッグ出力を表示
ssh -v user@example.com

公開鍵認証の設定

公開鍵認証は、パスワード認証よりも安全で、適切に設定すればパスワード入力なしでSSH接続できます。

公開鍵認証の仕組み

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

flowchart TB
    subgraph Client["クライアント側"]
        PRIV["秘密鍵<br/>~/.ssh/id_ed25519<br/>絶対に外部に漏らさない"]
    end
    
    subgraph Server["サーバー側"]
        PUB["公開鍵<br/>~/.ssh/authorized_keys<br/>サーバーに登録"]
    end
    
    PRIV <-->|ペア| PUB
    
    subgraph Auth["認証プロセス"]
        A1["1. クライアントが接続要求"]
        A2["2. サーバーがチャレンジを送信"]
        A3["3. クライアントが秘密鍵で署名"]
        A4["4. サーバーが公開鍵で検証"]
        A5["5. 認証成功"]
    end
    
    A1 --> A2 --> A3 --> A4 --> A5
  • 秘密鍵(Private Key):クライアント側に保管し、絶対に外部に漏らしてはいけません
  • 公開鍵(Public Key):サーバー側に登録します。公開しても問題ありません

ssh-keygenで鍵ペアを生成する

ssh-keygenコマンドを使って鍵ペアを生成します。現在推奨されるアルゴリズムはEd25519です。

1
2
# Ed25519アルゴリズムで鍵ペアを生成(推奨)
ssh-keygen -t ed25519 -C "your_email@example.com"

コマンドを実行すると、以下のような対話形式で設定を行います。

1
2
3
4
5
6
7
8
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:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx your_email@example.com

各プロンプトの意味は以下のとおりです。

プロンプト 説明 推奨設定
Enter file in which to save the key 鍵ファイルの保存先 デフォルト(Enter)でOK
Enter passphrase 秘密鍵を保護するパスフレーズ 設定を強く推奨

パスフレーズを設定すると、秘密鍵が暗号化されます。万が一秘密鍵が流出しても、パスフレーズなしでは使用できません。

鍵アルゴリズムの選択

現在サポートされている主な鍵アルゴリズムと、その特徴を以下に示します。

アルゴリズム 鍵長 セキュリティ 推奨度
Ed25519 固定(256ビット相当) 非常に高い 最も推奨
ECDSA 256/384/521ビット 高い 推奨
RSA 2048/4096ビット 4096ビットなら十分 互換性が必要な場合

古いシステムとの互換性が必要な場合は、RSA 4096ビットを使用します。

1
2
# RSA 4096ビットで鍵ペアを生成
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

ssh-copy-idで公開鍵をサーバーに登録する

生成した公開鍵をサーバーに登録するには、ssh-copy-idコマンドを使用します。

1
2
3
4
5
# 公開鍵をサーバーに登録
ssh-copy-id user@example.com

# 特定の鍵ファイルを指定する場合
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@example.com

実行結果の例を以下に示します。

1
2
3
4
5
6
7
8
9
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user@example.com's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user@example.com'"
and check to make sure that only the key(s) you wanted were added.

ssh-copy-idが使用できない環境(Windowsなど)では、手動で公開鍵を登録します。

1
2
# 手動で公開鍵を登録する方法
cat ~/.ssh/id_ed25519.pub | ssh user@example.com "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

公開鍵認証の動作確認

公開鍵認証が正しく設定されたか確認します。

1
2
# 公開鍵認証でSSH接続
ssh user@example.com

パスフレーズを設定した場合は、秘密鍵のパスフレーズの入力が求められます。パスワードではなくパスフレーズが求められていれば、公開鍵認証が正しく動作しています。

ssh-agentでパスフレーズ入力を省略する

ssh-agentを使用すると、一度入力したパスフレーズをメモリに保持し、以降のSSH接続でパスフレーズ入力を省略できます。

1
2
3
4
5
# ssh-agentを起動
eval "$(ssh-agent -s)"

# 秘密鍵を登録(パスフレーズを入力)
ssh-add ~/.ssh/id_ed25519

登録済みの鍵を確認するには、以下のコマンドを使用します。

1
2
# 登録済みの鍵を表示
ssh-add -l

SSH設定ファイル(~/.ssh/config)

複数のサーバーに接続する場合、毎回ユーザー名やポート番号を指定するのは手間がかかります。~/.ssh/configファイルを使用すると、接続設定をまとめて管理できます。

SSH設定ファイルの基本構造

~/.ssh/configファイルを作成し、各ホストの設定を記述します。

1
2
3
# 設定ファイルを作成(存在しない場合)
touch ~/.ssh/config
chmod 600 ~/.ssh/config

設定ファイルの基本的な構造は以下のとおりです。

1
2
3
4
5
Host エイリアス名
    HostName 実際のホスト名またはIPアドレス
    User ユーザー名
    Port ポート番号
    IdentityFile 秘密鍵のパス

設定ファイルの具体例

複数のサーバーを管理する設定例を示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 本番サーバー
Host production
    HostName prod.example.com
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519_prod

# ステージングサーバー
Host staging
    HostName staging.example.com
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519

# 開発サーバー(非標準ポート)
Host dev
    HostName 192.168.1.100
    User developer
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

# GitHub
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github

# すべてのホストに適用するデフォルト設定
Host *
    AddKeysToAgent yes
    ServerAliveInterval 60
    ServerAliveCountMax 3

この設定を行うと、以下のように短いコマンドでSSH接続できます。

1
2
3
4
5
6
7
8
# 本番サーバーに接続
ssh production

# ステージングサーバーに接続
ssh staging

# 開発サーバーに接続
ssh dev

よく使う設定オプション

オプション 説明 設定例
HostName 実際のホスト名またはIPアドレス prod.example.com
User ログインユーザー名 deploy
Port 接続ポート番号 22
IdentityFile 使用する秘密鍵のパス ~/.ssh/id_ed25519
ServerAliveInterval キープアライブの送信間隔(秒) 60
ServerAliveCountMax キープアライブの最大送信回数 3
AddKeysToAgent ssh-agentに自動で鍵を追加 yes
ForwardAgent エージェント転送を有効化 yes
ProxyJump 踏み台サーバーを指定 bastion

踏み台サーバー(ジャンプホスト)の設定

踏み台サーバーを経由してプライベートネットワーク内のサーバーに接続する設定例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 踏み台サーバー
Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519

# プライベートサーバー(踏み台経由)
Host private-server
    HostName 10.0.1.100
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump bastion

この設定により、以下のコマンドで踏み台を経由した接続が可能になります。

1
2
# 踏み台経由でプライベートサーバーに接続
ssh private-server

ポートフォワーディングとSSHトンネリング

SSHポートフォワーディングを使用すると、暗号化されたSSH接続を通じて、別のポートへの通信をトンネリングできます。ファイアウォールで直接アクセスできないサービスに安全に接続する場合に有効です。

ポートフォワーディングの種類

SSHポートフォワーディングには3つの種類があります。

flowchart TB
    subgraph Local["ローカルポートフォワーディング(-L)"]
        L1["クライアント:8080"] -->|SSHトンネル| L2["サーバー"] --> L3["内部サービス:80"]
    end
    
    subgraph Remote["リモートポートフォワーディング(-R)"]
        R1["外部クライアント"] --> R2["サーバー:8080"] -->|SSHトンネル| R3["クライアント:80"]
    end
    
    subgraph Dynamic["ダイナミックポートフォワーディング(-D)"]
        D1["クライアント:1080<br/>SOCKSプロキシ"] -->|SSHトンネル| D2["サーバー"] --> D3["任意の宛先"]
    end

ローカルポートフォワーディング(-L)

ローカルポートフォワーディングは、クライアント側のポートをリモートサーバー経由で別のホストに転送します。

1
2
3
4
5
6
7
8
# 基本構文
ssh -L [ローカルポート]:[転送先ホスト]:[転送先ポート] user@SSHサーバー

# 例:リモートサーバー上のMySQLに接続
ssh -L 3306:localhost:3306 user@example.com

# 例:リモートネットワーク内の別サーバーのWebサービスに接続
ssh -L 8080:internal-server:80 user@example.com

上記の設定後、クライアント側でlocalhost:3306に接続すると、リモートサーバーのlocalhost:3306(MySQL)に接続できます。

1
2
# ローカルからリモートのMySQLに接続
mysql -h 127.0.0.1 -P 3306 -u dbuser -p

リモートポートフォワーディング(-R)

リモートポートフォワーディングは、リモートサーバー側のポートをクライアント側に転送します。外部からアクセスできないローカルサービスを公開する場合に使用します。

1
2
3
4
5
# 基本構文
ssh -R [リモートポート]:[転送先ホスト]:[転送先ポート] user@SSHサーバー

# 例:ローカルの開発サーバーをリモートサーバー経由で公開
ssh -R 8080:localhost:3000 user@example.com

この設定により、リモートサーバーの:8080にアクセスすると、ローカルの:3000に接続されます。

ダイナミックポートフォワーディング(-D)

ダイナミックポートフォワーディングは、SOCKSプロキシとして動作し、任意の宛先への接続をSSHトンネル経由で行います。

1
2
3
4
5
# 基本構文
ssh -D [ローカルポート] user@SSHサーバー

# 例:SOCKSプロキシを起動
ssh -D 1080 user@example.com

ブラウザやアプリケーションのプロキシ設定でlocalhost:1080をSOCKSプロキシとして指定すると、すべての通信がSSHトンネル経由になります。

バックグラウンドでトンネルを維持する

ポートフォワーディングをバックグラウンドで実行し、トンネルを維持する場合は、-f-Nオプションを組み合わせます。

1
2
3
4
5
6
7
8
# バックグラウンドでトンネルを維持
ssh -f -N -L 3306:localhost:3306 user@example.com

# プロセスを確認
ps aux | grep ssh

# トンネルを終了する場合
pkill -f "ssh -f -N -L 3306"

SSH設定ファイルでのポートフォワーディング設定

~/.ssh/configでポートフォワーディングを事前に設定することもできます。

1
2
3
4
5
Host db-tunnel
    HostName example.com
    User deploy
    LocalForward 3306 localhost:3306
    ServerAliveInterval 60

この設定を使用すると、以下のコマンドでトンネルを確立できます。

1
ssh -N db-tunnel

SCPによるファイル転送

scp(Secure Copy)コマンドは、SSH接続を使用してファイルを安全にコピーします。

scpの基本構文

1
2
3
4
5
# ローカルからリモートへファイルをコピー
scp [オプション] ローカルファイル user@host:リモートパス

# リモートからローカルへファイルをコピー
scp [オプション] user@host:リモートファイル ローカルパス

scpの使用例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# ローカルファイルをリモートサーバーにコピー
scp ./myfile.txt user@example.com:/home/user/

# リモートファイルをローカルにダウンロード
scp user@example.com:/var/log/app.log ./

# ディレクトリを再帰的にコピー(-r オプション)
scp -r ./mydir user@example.com:/home/user/

# SSH設定ファイルのHostエイリアスを使用
scp ./myfile.txt production:/home/deploy/

# ポートを指定してコピー(-P オプション、大文字のP)
scp -P 2222 ./myfile.txt user@example.com:/home/user/

scpのよく使うオプション

オプション 説明
-r ディレクトリを再帰的にコピー
-P ポート番号を指定(大文字)
-i 秘密鍵ファイルを指定
-p ファイルの更新日時やパーミッションを保持
-C 転送時に圧縮を有効化
-q 進捗表示を非表示

SFTPによるファイル転送

sftp(SSH File Transfer Protocol)は、対話的なファイル転送を行うためのコマンドです。FTPに似た操作感でファイルを転送できます。

sftpの基本的な使い方

1
2
3
4
5
# SFTPセッションを開始
sftp user@example.com

# SSH設定ファイルのHostエイリアスを使用
sftp production

SFTPセッション内のコマンド

SFTPセッション内で使用できる主なコマンドを以下に示します。

コマンド 説明 使用例
ls リモートディレクトリの内容を表示 ls -la
lls ローカルディレクトリの内容を表示 lls
cd リモートディレクトリを移動 cd /var/www
lcd ローカルディレクトリを移動 lcd ~/downloads
pwd リモートの現在のディレクトリを表示 pwd
lpwd ローカルの現在のディレクトリを表示 lpwd
get リモートからローカルへファイルをダウンロード get file.txt
put ローカルからリモートへファイルをアップロード put file.txt
mget 複数ファイルをダウンロード mget *.log
mput 複数ファイルをアップロード mput *.txt
mkdir リモートにディレクトリを作成 mkdir newdir
rm リモートのファイルを削除 rm oldfile.txt
exit / quit SFTPセッションを終了 exit

SFTPセッションの使用例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sftp> pwd
Remote working directory: /home/user
sftp> cd /var/www/html
sftp> ls
index.html  style.css  app.js
sftp> lcd ~/downloads
sftp> get index.html
Fetching /var/www/html/index.html to index.html
sftp> put newfile.txt
Uploading newfile.txt to /var/www/html/newfile.txt
sftp> exit

セキュリティのベストプラクティス

SSH接続をより安全に運用するためのベストプラクティスを紹介します。

クライアント側のセキュリティ

  1. パスフレーズ付きの秘密鍵を使用する:秘密鍵には必ずパスフレーズを設定しましょう

  2. 秘密鍵のパーミッションを適切に設定する

    1
    2
    3
    
    chmod 600 ~/.ssh/id_ed25519
    chmod 644 ~/.ssh/id_ed25519.pub
    chmod 700 ~/.ssh
    
  3. Ed25519アルゴリズムを使用する:古いDSAやRSA 1024ビットは使用しないでください

  4. ssh-agentを活用する:パスフレーズを毎回入力する手間を省きつつ、セキュリティを維持できます

サーバー側のセキュリティ設定

サーバー側のSSHデーモン(sshd)設定を強化するには、/etc/ssh/sshd_configを編集します。以下は推奨される設定例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# パスワード認証を無効化(公開鍵認証のみ許可)
PasswordAuthentication no

# rootログインを禁止
PermitRootLogin no

# 空のパスワードを禁止
PermitEmptyPasswords no

# 公開鍵認証を有効化
PubkeyAuthentication yes

# 接続を許可するユーザーを限定
AllowUsers deploy admin

# 最大認証試行回数
MaxAuthTries 3

設定変更後は、sshdを再起動します。

1
sudo systemctl restart sshd

トラブルシューティング

SSH接続でよく発生する問題と解決方法を紹介します。

接続がタイムアウトする

1
2
# 詳細ログを表示して原因を確認
ssh -vvv user@example.com

考えられる原因と対処法は以下のとおりです。

  • ファイアウォールでポート22がブロックされている:サーバーのファイアウォール設定を確認
  • SSHサービスが起動していないsudo systemctl status sshdで確認
  • ネットワーク経路の問題pingtracerouteで確認

Permission denied (publickey) エラー

1
Permission denied (publickey).

このエラーは、公開鍵認証に失敗した場合に発生します。以下を確認してください。

  1. 公開鍵がサーバーに正しく登録されているか

    1
    2
    
    # サーバー側で確認
    cat ~/.ssh/authorized_keys
    
  2. 秘密鍵のパーミッションが正しいか

    1
    2
    
    ls -la ~/.ssh/id_ed25519
    # 出力例: -rw------- 1 user user 419 Jan  1 00:00 /home/user/.ssh/id_ed25519
    
  3. サーバー側の.sshディレクトリのパーミッションが正しいか

    1
    2
    3
    
    # サーバー側で確認・修正
    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys
    

Host key verification failed エラー

1
2
3
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

このエラーは、サーバーのホスト鍵が変更された場合に発生します。サーバーの再構築など正当な理由がある場合は、以下のコマンドで古い鍵を削除します。

1
2
# 特定ホストの鍵を削除
ssh-keygen -R example.com

ただし、この警告が予期せず表示された場合は、中間者攻撃の可能性があるため、サーバー管理者に確認してください。

まとめ

本記事では、SSH接続の基本から実践的な活用方法までを解説しました。

  • SSHの基本sshコマンドでリモートサーバーに安全に接続できます
  • 公開鍵認証ssh-keygenで鍵を生成し、ssh-copy-idでサーバーに登録することで、より安全な認証を実現できます
  • SSH設定ファイル~/.ssh/configで複数サーバーへの接続を効率的に管理できます
  • ポートフォワーディング:SSHトンネルを使って、ファイアウォール越しにサービスへ安全にアクセスできます
  • ファイル転送scpsftpで安全にファイルを転送できます

SSH接続は日々の開発・運用業務で頻繁に使用するスキルです。公開鍵認証とSSH設定ファイルを適切に活用することで、セキュリティを維持しながら効率的にサーバーを操作できるようになります。

参考リンク