SSHトンネリングとは:リモートサービスに安全にアクセスする方法
SSHトンネリングを使用して、ローカル、リモート、および動的転送により、プライベートデータベース、Webアプリ、リモートサービスにアクセスします。
SSHトンネリングの解説:リモートサービスへの安全なアクセス
SSHトンネリングは、サービスをインターネットに公開せずにリモートサービスにアクセスするのに役立ちます。データベース、管理ダッシュボード、開発サーバーが踏み台ホストからのみアクセス可能な場合、SSHトンネルを使用すると、ローカルツールに安全なパスを提供できます。
主なパターンは、ローカル転送、リモート転送、動的転送です。それぞれ異なる質問に答えます:リモートのものにアクセスする必要があるか、ローカルのものを公開する必要があるか、SOCKSプロキシを作成する必要があるかです。
SSHトンネリングとは?
SSHトンネリングは、アプリケーショントラフィックをSSH接続内にラップします。サービスに直接接続する代わりに、ローカルまたはリモートの転送ポートに接続します。SSHはそのトラフィックを暗号化されたセッションを通じて運び、トンネルの正しい側から最終的な宛先に接続します。
トンネルは、SSHクライアントとSSHサーバー間のトラフィックを暗号化します。最終的な宛先がSSHサーバーの先にある場合、その最後の区間は宛先サービスが提供するセキュリティを使用します。機密性の高いサービスの場合は、トンネルを使用する場合でもTLSまたはネイティブ暗号化を有効にしておいてください。
SSHトンネルの種類
SSHには3つの主要なポート転送タイプがあり、それぞれ異なる目的に使用されます:
1. ローカルポート転送(-L)
ローカルポート転送は最も一般的なタイプです。これにより、ローカルマシンのポートからリモートマシン(またはリモートSSHサーバーからアクセス可能なマシン)のポートにトラフィックを転送できます。これは、リモートサーバーの内部ネットワーク上またはサーバー自体で実行されているサービスにアクセスするのに理想的であり、ローカルネットワークから直接アクセスできない場合に使用します。
仕組み: SSHクライアントがマシン上で待機します。SSHサーバーが宛先に接続します。
ユースケース: 踏み台ホストのみがアクセスできるMySQLデータベース(ポート3306)にアクセスする。
コマンド構文:
ssh -L [ローカルポート]:[宛先ホスト]:[宛先ポート] [SSHユーザー]@[SSHサーバー]
例:
db.internal.example.com(ポート3306)でMySQLデータベースが実行されており、bastion.example.comにのみSSH接続できるとします。ローカルマシンのポート8888からデータベースにアクセスするには:
ssh -L 8888:db.internal.example.com:3306 [email protected]
このコマンドを実行した後、ローカルのMySQLクライアントを開き、localhost:8888に接続します。トラフィックはbastion.example.comを経由してdb.internal.example.com:3306に安全にトンネリングされます。
リモートシェルが必要ない場合は-Nを使用します:
ssh -N -L 8888:db.internal.example.com:3306 [email protected]
スクリプトの場合は、-o ExitOnForwardFailure=yesを追加して、ローカルリスナーを作成できない場合にSSHが終了するようにします。
2. リモートポート転送(-R)
リモートポート転送はローカル転送の逆を行います。これにより、リモートSSHサーバーのポートからローカルマシンまたはローカルマシンからアクセス可能なマシンのポートにトラフィックを転送できます。これは、ローカルマシン(またはローカルネットワーク上のマシン)で実行されているサービスをリモートサーバーまたはそのネットワークに公開するのに便利です。
仕組み: SSHサーバーがリモートポートで待機します。SSHクライアントがトンネルの自側から宛先に接続します。
ユースケース: リモートの同僚が、ローカルマシンで実行されているWeb開発サーバー(例:ポート5000のFlaskアプリ)にアクセスできるようにする。ローカルマシンを直接インターネットに公開する必要はありません。
コマンド構文:
ssh -R [リモートポート]:[宛先ホスト]:[宛先ポート] [SSHユーザー]@[SSHサーバー]
例:
ローカルマシンのlocalhost:5000でWebアプリケーションを実行しているとします。remote.example.comのユーザーがremote.example.comのポート9000に接続してアクセスできるようにしたい場合:
ssh -R 9000:localhost:5000 [email protected]
一般的なOpenSSH設定では、リモートリスナーはSSHサーバーのループバックインターフェースでのみ利用可能です。つまり、リモートホストのユーザーはlocalhost:9000をテストできますが、他のマシンがremote.example.com:9000に必ずしも到達できるわけではありません。
リスナーを他のマシンに公開するには、通常、コマンドで0.0.0.0などのバインドアドレスと、サーバー側のGatewayPorts設定(clientspecifiedやyesなど)が必要です。注意:リモート転送は、ラップトップやローカルネットワーク上のサービスをリモートネットワークに公開する可能性があります。
3. 動的ポート転送(-D)
動的ポート転送は、ローカルマシン上にSOCKSプロキシを作成します。特定の宛先にトラフィックを転送する代わりに、このSOCKSプロキシを使用するように設定されたアプリケーションが、SSHサーバーからアクセス可能な任意のホストとポートに接続できるようにします。これにより、SSH接続を多目的プロキシサーバーとして効果的に利用できます。
仕組み: SSHクライアントがSOCKSプロキシとして待機します。SOCKSをサポートするアプリケーションは、そのローカルプロキシにリクエストを送信し、SSHサーバーが外部接続を行います。
ユースケース: 自宅やオフィスのSSHサーバーを経由してすべてのブラウザトラフィックをルーティングすることで、公共Wi-Fiネットワークから安全にWebを閲覧する。これにより、ブラウジングアクティビティが暗号化されます。
コマンド構文:
ssh -D [ローカルポート] [SSHユーザー]@[SSHサーバー]
例:
ローカルマシン上でポート1080をリッスンするSOCKSプロキシを作成するには:
ssh -D 1080 [email protected]
このコマンドを実行した後、ブラウザや他のアプリケーションを設定して、localhost:1080のSOCKSプロキシを使用するようにします。アプリケーションがSOCKS5を介したリモートDNSをサポートしている場合、DNSプライバシーが重要な場合はそれを有効にします。
実用的なアプリケーションと利点
SSHトンネリングには、幅広い実用的なアプリケーションがあります:
- 安全なデータベースアクセス: プライベートネットワーク内の特定のサーバーからのみアクセス可能なデータベース(PostgreSQL、MySQL、MongoDBなど)に、データベースポートを直接インターネットに公開せずにアクセスする。
- 内部Webサービスへのアクセス: 公開されていない内部Webアプリケーション、管理インターフェース、監視ダッシュボードに接続する。
- 暗号化されていないプロトコルの保護: VNC、FTP、プレーンHTTPなどの安全でないプロトコルを暗号化されたSSHトンネル内にラップし、機密性と完全性を提供する。
- ネットワーク制限の回避: それらに到達することが許可されているサーバーを介してサービスにアクセスする。これは、組織のネットワークポリシーに準拠している場合にのみ行ってください。
- 安全なリモート開発: リモートサーバーで実行されている開発環境やツールへの安全なアクセスを提供する。
まとめ
ラップトップがプライベートなリモートサービスにアクセスする必要がある場合は、ローカル転送を使用します。リモートホストが近くのサービスに一時的にアクセスする必要がある場合は、リモート転送を使用します。信頼できるSSHサーバーを介したSOCKSプロキシが必要な場合は、動的転送を使用します。トンネルは可能な限り狭く保ち、作業が終わったら閉じてください。