Linux における SSH による安全なリモートアクセス

CompTIABeginner
オンラインで実践に進む

はじめに

この実験 (Lab) では、Secure Shell (SSH) プロトコルを使用して Linux システムへのリモートアクセスを保護する基本を学びます。鍵ベースの認証の設定によるセキュリティ強化、システム間の安全なファイル転送、ポートフォワーディングのための SSH トンネルの作成といった、SSH の基本的な機能について実践的な経験を積むことができます。

まず、より現実的な実験環境をシミュレートするために Docker コンテナをセットアップします。次に、ホストマシンに OpenSSH クライアントをインストールし、ssh-keygen ユーティリティを使用して新しい RSA キーペアを生成します。その後、Docker サーバーを設定してこの鍵を認証に使用できるようにし、ホストとコンテナ化されたサーバー間の安全なパスワードなし接続を確立します。最後に、安全なファイル転送のために scp コマンドを、ローカルポートをリモートサービスに転送して安全なトンネルを作成するために ssh -L コマンドを使用する練習を行います。

Docker SSH サーバーの設定と鍵ペアの生成

このステップでは、リモート SSH サーバーをシミュレートするための Docker コンテナをセットアップし、ホストマシンで安全な鍵ペアを生成します。このアプローチは、クライアント(あなたのホスト)とサーバー(Docker コンテナ)を分離することで、より現実的な環境を提供します。

この環境には Docker と OpenSSH クライアントが既にインストールされているため、サーバーの設定に直接進むことができます。

まず、Docker サービスが実行されていることを確認します。

sudo systemctl start docker
sudo systemctl enable docker

次に、SSH サーバーとして機能する Docker コンテナを作成します。ベースイメージとして Ubuntu を使用し、SSH サーバー機能で設定します。Dockerfile を作成します。

cat > Dockerfile << 'EOF'
FROM ubuntu:22.04

## OpenSSH サーバーおよびその他のユーティリティをインストール
RUN apt-get update && \
    apt-get install -y openssh-server nginx sudo && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

## SSH アクセス用のユーザーを作成
RUN useradd -m -s /bin/bash sshuser && \
    echo 'sshuser:password123' | chpasswd && \
    usermod -aG sudo sshuser

## SSH の設定
RUN mkdir /var/run/sshd && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
    sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config

## ユーザー用の SSH ディレクトリを作成
RUN mkdir -p /home/sshuser/.ssh && \
    chown sshuser:sshuser /home/sshuser/.ssh && \
    chmod 700 /home/sshuser/.ssh

## SSH ポートを公開
EXPOSE 22 80

## SSH サービスを開始
CMD ["/usr/sbin/sshd", "-D"]
EOF

Docker イメージをビルドします。

sudo docker build -t ssh-server .

Docker コンテナを実行し、ホストのポート 2222 をコンテナのポート 22 にマッピングします。

sudo docker run -d --name ssh-lab-server -p 2222:22 -p 8080:80 ssh-server

コンテナが実行されていることを確認します。

sudo docker ps

実行中のコンテナを示す出力が表示されるはずです。

CONTAINER ID   IMAGE        COMMAND               CREATED         STATUS         PORTS                                        NAMES
...            ssh-server   "/usr/sbin/sshd -D"   ...             Up ...         0.0.0.0:2222->22/tcp, 0.0.0.0:8080->80/tcp   ssh-lab-server

次に、SSH 鍵ペアを生成します。SSH 鍵は、パスワードのみを使用するよりも安全な方法で SSH を使用してサーバーにログインできます。鍵ペアは、秘密にしておく必要がある 秘密鍵 (private key) と、共有できる 公開鍵 (public key) で構成されます。

ssh-keygen コマンドを使用して新しい鍵ペアを作成します。鍵のタイプは rsa、鍵のサイズは強力なセキュリティのために 2048 ビットに指定します。-f フラグを使用すると、鍵のファイル名を指定できるため、整理に役立ちます。鍵の名前は ~/.ssh/id_rsa_lab_ssh とします。

以下のコマンドを実行します。パスフレーズを求められたら、パスフレーズなしで続行するために Enter を 2 回押すだけです。この実験では簡潔にするためにパスフレーズを省略しますが、実際のシナリオでは、秘密鍵を保護するために常に強力なパスフレーズを使用する必要があります。

ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa_lab_ssh

コマンドは鍵ペアを生成し、ファイルが保存されている場所を表示します。

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/labex/.ssh/id_rsa_lab_ssh
Your public key has been saved in /home/labex/.ssh/id_rsa_lab_ssh.pub
The key fingerprint is:
SHA256:... labex@...
The key's randomart image is:
+---[RSA 2048]----+
|        .o*+..   |
|       . =.o. .  |
|      . o o. .   |
|       o .  .    |
|      . S        |
|     . . .       |
|      o .        |
|     o .         |
|    E .          |
+----[SHA256]-----+

鍵ファイルが作成されたことを確認するには、~/.ssh ディレクトリの内容を一覧表示します。新しい秘密鍵 (id_rsa_lab_ssh) と公開鍵 (id_rsa_lab_ssh.pub) が表示されるはずです。

ls -l ~/.ssh/id_rsa_lab_ssh*

出力は次のようになり、2 つの新しいファイルが表示されます。

-rw------- 1 labex labex 1876 ... /home/labex/.ssh/id_rsa_lab_ssh
-rw-r--r-- 1 labex labex  401 ... /home/labex/.ssh/id_rsa_lab_ssh.pub

これで、SSH サーバーのインストールと鍵ペアの作成が完了しました。これらは次のステップで、安全な認証の設定とテストに使用します。

SSH 鍵認証の設定とテスト

このステップでは、Docker SSH サーバーが公開鍵を認識するように設定し、パスワードなしでのログインを可能にします。このプロセスには、公開鍵を Docker コンテナにコピーし、その後接続をテストすることが含まれます。

SSH サーバーが鍵を使用してあなたを認証するためには、公開鍵がサーバーの ~/.ssh/authorized_keys ファイルに配置されている必要があります。私たちのサーバーは Docker コンテナで実行されているため、ホストマシンからコンテナに公開鍵をコピーする必要があります。

まず、docker cp コマンドを使用して、公開鍵を Docker コンテナにコピーします。

sudo docker cp ~/.ssh/id_rsa_lab_ssh.pub ssh-lab-server:/home/sshuser/.ssh/authorized_keys

次に、コンテナ内で適切なファイルパーミッションを設定する必要があります。SSH はセキュリティに非常に厳格であり、パーミッションが緩すぎると鍵の使用を拒否します。適切なパーミッションを設定するために、以下のコマンドを実行します。

sudo docker exec ssh-lab-server chown sshuser:sshuser /home/sshuser/.ssh/authorized_keys
sudo docker exec ssh-lab-server chmod 600 /home/sshuser/.ssh/authorized_keys

公開鍵を追加し、パーミッションを設定したので、鍵ベース認証のテスト準備ができました。コンテナのポート 22 にマッピングしたポート 2222 を使用して、ユーザー sshuser として、作成した秘密鍵を指定して Docker コンテナに SSH 接続を試みます。

秘密鍵ファイルを示す -i フラグと、ポートを指定する -p を使用して ssh コマンドを使用します。

ssh -i ~/.ssh/id_rsa_lab_ssh -p 2222 sshuser@localhost

初めて新しいホストに接続するため、ホストの認証を確認するように求められる場合があります。yes と入力して Enter を押します。

The authenticity of host '[localhost]:2222 ([127.0.0.1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:....
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2222' (ED25519) to the list of known hosts.

すべてが正しく設定されていれば、パスワードを求められることなくすぐにログインできます。ウェルカムメッセージが表示され、コマンドプロンプトが変更されて、Docker コンテナ内にいることが示されます。

Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-88-generic x86_64)
...
sshuser@containerid:~$

SSH セッションを終了してホスト端末のプロンプトに戻るには、exit と入力して Enter を押すだけです。

exit

パスワードなしで正常にログインできたことは、鍵ベース認証がホストと Docker コンテナの間で正しく機能していることを確認します。この方法は、従来のパスワード認証よりも大幅に安全です。

scp を使用した安全なファイル転送

このステップでは、ホスト間でファイルを安全に転送するために Secure Copy Protocol (scp) の使用方法を学びます。scp は基盤となる SSH プロトコルを利用しており、既に設定した鍵ベース認証を含む、同じ暗号化および認証メカニズムの恩恵を受けます。

まず、転送に使用できるサンプルファイルを現在の作業ディレクトリ ~/project に作成しましょう。ファイル名は source_file.txt とします。

echo "This is a test file for scp." > source_file.txt

ファイルを一覧表示することで、ファイルが作成されたことを確認できます。

ls -l source_file.txt

出力には新しく作成されたファイルが表示されるはずです。

-rw-r--r-- 1 labex labex 29 ... source_file.txt

次に、scp を使用して source_file.txt を Docker コンテナの /tmp ディレクトリにコピーし、リモートサーバーへの安全なファイル転送を実証します。scp の基本的な構文は scp -i [private_key] -P [port] [source_file] [user]@[host]:[destination_path] です。

-i フラグを使用して秘密鍵を指定し、-P を使用してポート 2222(Docker コンテナの SSH ポート)を指定し、コンテナの sshuser アカウントにファイルを転送します。

scp -i ~/.ssh/id_rsa_lab_ssh -P 2222 source_file.txt sshuser@localhost:/tmp/destination_file.txt

ファイル転送の進捗状況を示す出力が表示され、小さなファイルの場合は瞬時に完了するはずです。

source_file.txt                                   100%   29     6.7KB/s   00:00

ファイルが正常にコピーされたことを確認するには、Docker コンテナに接続し、宛先ファイルを一覧表示します。

sudo docker exec ssh-lab-server ls -l /tmp/destination_file.txt

出力は、コピーされたファイルの存在と詳細を確認します。

-rw-r--r-- 1 sshuser sshuser 29 ... /tmp/destination_file.txt

ファイルの内容が正しく転送されたかも確認できます。

sudo docker exec ssh-lab-server cat /tmp/destination_file.txt

これにより、以下が表示されるはずです。

This is a test file for scp.

これで、scp を使用してファイルを正常に転送し、ネットワーク経由でシステム間でデータを移動する安全で実用的な方法を実証しました。

ssh -L を使用したポートフォワーディングのための SSH トンネル作成

このステップでは、SSH の最も強力な機能の 1 つであるトンネリング、別名ポートフォワーディングについて学びます。これにより、ローカルマシン上のポートからリモートサーバー上のポートへのネットワークトラフィックを安全に転送でき、暗号化されていないプロトコルを安全な SSH 接続内に効果的にラップします。ここではローカルポートフォワーディングを練習します。

これを実証するために、接続できるポートで実行されているサービスが必要です。幸いなことに、Docker コンテナには既に Nginx がインストールされ、設定されています。コンテナ内で Nginx サービスを開始する必要があります。

まず、Docker コンテナ内で Nginx サービスを開始します。

sudo docker exec ssh-lab-server service nginx start

コンテナ内で Nginx が正しく実行されていることを確認できます。

sudo docker exec ssh-lab-server service nginx status

出力はサービスが実行中であることを示すはずです。

 * nginx is running

次に、SSH トンネルを作成しましょう。ローカルポートフォワーディングを意味する -L フラグを持つ ssh コマンドを使用します。構文は ssh -L [LOCAL_PORT]:[DESTINATION_HOST]:[DESTINATION_PORT] [USER]@[SERVER] です。

ローカルマシンのポート 9090 から Docker コンテナ内のポート 80 へのトラフィックを転送します。-N フラグは、SSH にリモートコマンドを実行しないように指示します。これはポート転送のみを行う場合に最適です。Docker コンテナの SSH サービスに接続するにはポート 2222 を使用することに注意してください。

このコマンドを実行します。このコマンドは現在のターミナルを占有し、プロンプトを返しません。 トンネルをテストするには、新しいターミナルを開く必要があります。

ssh -i ~/.ssh/id_rsa_lab_ssh -N -L 9090:localhost:80 -p 2222 sshuser@localhost

次に、ターミナルタブバーの + アイコンをクリックして、新しいターミナルを開きます。この新しいターミナルでは、curl を使用してトンネルをテストできます。localhost:9090 にアクセスすることで、リクエストは SSH を介して Docker コンテナ内のポート 80 に安全にトンネルされます。

curl http://localhost:9090

デフォルトの Nginx ウェルカムページの HTML コンテンツが表示され、トンネルが機能していることを確認できます。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

ホストマシンから Docker コンテナ内で実行されているサービスへのトラフィックを転送する安全なトンネルを正常に作成しました。接続を閉じるには、最初のターミナルssh コマンドを実行しているターミナル)に戻り、Ctrl+C を押します。その後、2 番目のターミナルを閉じることができます。

まとめ

この実験では、Secure Shell (SSH) プロトコルを使用して Linux システムでのリモートアクセスを保護するための基本的なスキルを学びました。主な目的は、鍵ベース認証の設定とテスト、scp を使用した安全なファイル転送、およびポートフォワーディングのための SSH トンネルの作成でした。

まず、システムのパッケージリストを更新し、openssh-serveropenssh-client の両方のパッケージをインストールすることを含む環境準備から始めました。SSH サービスがアクティブであることを確認した後、ssh-keygen コマンドを使用して安全な 2048 ビット RSA キーペアを生成しました。この基本的なステップにより、後続のステップで安全なパスワードなし接続を確立するために必要な公開鍵と秘密鍵が作成されました。