SSHトンネリングとプロキシ
1. 序章
私たちが自由に使えるより用途の広いツールの1つは、 sshです。リモートホストを管理するためのリモートアクセスツールとして広く知られている、非常に多くの便利な機能があります。知っておくと本当に便利です。 たとえば、 ssh を使用してファイルを転送、マウントリモートホストをネットワークファイルシステムとして使用し、キーを生成できます。
このチュートリアルでは、sshのプロキシ機能とトンネリング機能についてもう少し詳しく説明します。
2. コンセプト
TCP / IPスタックの初期の頃から、リモートノードアクセスは必須でした。 ただし、そのために設計されたプロトコル(インタラクティブアクセス用のtelnetおよびファイル転送用のFTP)には、非常に基本的なセキュリティ対策がありませんでした。データフローは暗号化されていませんでした。
その結果、これらのプロトコルを使用して転送されたデータは、tcpdumpやWiresharkなどのネットワークトラフィック分析ツールによってキャプチャおよび精査できます。 ユーザー名とパスワードはクリアテキストで交換されているため、攻撃者は簡単にそれらを収集できます。
この問題やその他の制限に対処するために、sshは接続に暗号化を実装しています。 そうすれば、適切な構成、強力な暗号化、およびキー交換スキーマを使用していれば、通信が途中で傍受されないようにすることができます。
より有用な機能の1つであり、広く知られていませんが、トンネルとプロキシを確立する機能です。 このようにして、 ssh セッションを使用して、ファイアウォールで保護されているサービスなど、他の方法では表示されない他のリモートサービスに接続できます。
写真のように、クライアントマシンは、 ssh セッションを開いているときに、SSHサーバーに双方向で機能するトンネルを開くように指示します。
また、 XWindows プロトコルのプロキシとして機能し、リモートGUIアプリケーションをローカルで開くことができます。また、 SOCKS4または5準拠のプロキシサーバーとして機能し、クライアントが複数の宛先にアクセスできるようにします。 SSHサーバーになりすましたリモートサイトから。
さらに印象的で危険なのは、VPNのような完全なエクスペリエンスを可能にするため、tunデバイスを使用してレベル2またはレベル3のパケットをトンネリングできることです。
3. サーバー構成
まず、 ssh接続を介したトンネルの許可は、ファイアウォールポリシーを貫通する可能性があるため、セキュリティ上の責任になる可能性があることに気付くかもしれません。 そのため、不要なアクセスに対して閉じたままにしておきたいサービスやホストを公開しないように注意する必要があります。 このため、一部のLinuxディストリビューションでは、デフォルトでトンネリングとプロキシが無効になっています。
3.1. SSHDオプション
sshセッションを提供するデーモンであるsshdの有効化は、sshd_configファイルを編集することによって行われます。 その場所は少し異なりますが、通常は / etc /sshまたは/etc /opensshにあります。 関連する構成キーは次のとおりです。
- AllowStreamLocalForwarding :Unixドメインソケットの転送を許可します。 省略した場合のデフォルトはyesです。
- AllowTcpForwarding :TCPポート転送を許可します。 省略した場合のデフォルトは許可です。 単一のTCPポート転送とソックスプロキシを有効にします
- DisableForwarding :すべての種類の転送を無効にします。 有効になっている場合は、他のすべての関連する構成オプションをオーバーライドします
- GatewayPorts :他のホストがクライアントに転送されたポートを使用できるようにします(リバーストンネル)。 デフォルトでは、SSHサーバーを実行しているホストのみがリバーストンネルを使用できます。 デフォルトでは無効
- PermitListen :クライアントへのポート転送を許可するためにバインドできるアドレスとポートを指定します。 GatewayPorts を有効にすると、より細かく制御できます。 デフォルトはlocalhost(’127.0.0.1’および’:: 1’)です。
- PermitOpen :TCP転送が指す可能性のあるアドレスとポートを指定します。 デフォルトでは、すべての宛先が有効になっています
- PermitTunnel :tunデバイス転送を許可するかどうかを指定します。 デフォルトはnoです
- X11Forwarding :X11転送を許可するかどうかを指定します。 デフォルトはnoです
- X11UseLocalhost :SSHサーバーホストのループバックアドレスからのみX11転送を許可するように強制します。 無効にすると、SSHサーバーネットワーク上の他のホストがそれを使用する可能性があります。 デフォルトはtrueです
3.2. その他の構成
ホスト上の他の構成は、sshの転送およびプロキシ機能に影響を与える可能性があります。 AppArmorおよびSELinuxは、これらのオプションの一部を禁止する場合があります。 また、一部のホストファイアウォール構成では、外部サービスとの接続および外部サービスからの接続が制限される場合があります( iptables に関するチュートリアルを参照)。 1024未満のリスニングポートのバインドには、デフォルトでroot権限が必要であることに注意してください。
もちろん、中間ファイアウォールは、通常はポートTCP / 22でSSHトラフィックを許可する必要がありますが、sshd_configファイルのデフォルトを変更することで他のポートを使用できます。
4. TCPトンネルを転送する
4.1. シングルポート
順方向または直接TCPトンネルは、クライアントからSSHサーバーへのSSH接続の方向に従うトンネルです。 SSH の入門チュートリアルでは、このタイプの転送について簡単に説明しています。 直接TCP転送トンネルを作成するには、コマンドラインで-Lオプションを使用する必要があります。
ssh -L [bind_address:]port:host:hostport [user@]remote_ssh_server
オプションのbind_addressは、接続をリッスンするクライアントローカルインターフェイスを割り当てます。 これを省略すると、sshはループバックインターフェイスにのみバインドします。 “ 0.0.0.0” または“ ::” を使用して、すべてのインターフェースにバインドすることもできます。 したがって、次のコマンドを発行すると、次のようになります。
ssh -L 0.0.0.0:8022:10.1.4.100:22 [email protected]
10.1.4.20 IPアドレスでホストにSSH接続を開き、クライアントポート8022でリッスンし、ホスト10.1.4.100のSSHアドレスを指すトンネルを作成します。
このように、接続がクライアントポート8022に入ると、SSHサーバーのIPアドレスを使用して、宛先のホストとポートに転送されます。これは、それらの間の通常のローカルネットワークとまったく同じように見えます。
同様に、ローカルソケットを転送するには(あまり一般的ではありません)、次を使用できます。
ssh -L local_socket:host:hostport [user@]remote_ssh_server
または、次を使用できます。
ssh -L local_socket:remote_socket [user@]remote_ssh_server
4.2. ダイナミックまたはマルチポート
バインディングポートへのSOCKSプロトコルを使用する接続はすべて、独自のIPアドレスを使用してSSHサーバーに転送されます。 これを行うには、次を使用します。
ssh -D [bind_address:]port [user@]remote_ssh_server
この場合、転送先のホストとポートを指定する必要さえないことに注意してください。 指定されたポート上のすべてのSOCKS準拠の着信接続は、トンネルを通過します。
もちろん、これを使用するには、コマンドラインで指定されたバインドされたアドレスとポートでプロキシサーバーを使用するようにトンネルを使用するアプリケーションを構成する必要があります。 たとえば、発行後:
ssh -D 8080 [email protected]
127.0.0.1、ポート8080でSOCKSプロキシサーバーを使用するようにクライアントホストでブラウザーを構成できます。 そうすれば、10.1.4.100にあるSSHサーバーにインストールされているブラウザを使用しているかのようにWebをナビゲートできます。
また、クライアントアプリケーションがSOCKSプロキシをサポートしていない場合はどうなりますか? プロキシチェーンやtsocksなどのソリューションを使用して、ソケットシステムコールをインターセプトし、接続をSOCKSプロキシに強制的に流すことができます。
5. 逆トンネル
5.1. シングルポート
リバースプロキシまたはコールバックプロキシを使用すると、上記と同様のトリックを逆方向に実行できます。 SSHセッションのリモート側のホストに対して、独自のローカルネットワーク上のサービスを開くことができます。 コマンド構文は、直接転送と非常によく似ています。
ssh -R [bind_address:]port:host:hostport [user@]remote_ssh_server
これにより、逆トンネルが作成されます。 リモートSSHサーバーで受信した接続をbind_address:portからローカルクライアントネットワークhost:hostportに転送します。 bind_address パラメーターを省略すると、ループバックインターフェイスにのみバインドされます。
同様に、ソケットを使用すると、次の3つの異なる構文を使用できます。
ssh -R remote_socket:host:hostport [user@]remote_ssh_server
ssh -R remote_socket:local_socket [user@]remote_ssh_server
ssh -R [bind_address:]port:local_socket [user@]remote_ssh_server
5.2. ダイナミックまたはマルチポート
最後に、直接転送の場合と同様に、クライアントのネットワークに向けられたリモートホスト上のSOCKSプロキシサーバーを公開できます。 これを行うには、ローカルの宛先ホストとポートを省略します。
ssh -R [bind_address:]port [user@]remote_ssh_server
これにより、ローカルクライアントネットワークへのSOCKSサーバーとして機能するリモートSSHサーバー上のポートが開き、リモートSSHサーバーに適用されるアウトバウンドトラフィックルールを貫通する可能性があります。
6. XWindowsトンネル
SSHは、必要なトンネルの確立を処理します。 また、SSHサーバー上のXクライアントアプリケーションに必要なDISPLAY環境変数を設定します。 そうすれば、ローカルクライアントのXサーバーに正しく接続する方法を知ることができます。
X11転送には、X11セキュリティ拡張機能の制限を適用する2種類があります(参照については、xhostおよびxauthを参照してください)。
ssh -X [user@]remote_ssh_server
または、X11セキュリティ拡張機能を適用しない信頼できる環境を想定してトンネルを作成します。
ssh -Y [user@]remote_ssh_server
7. 複数のトンネルと複数のホストホッピング
タイプと方向を組み合わせて、必要な数のトンネルを作成できます。コマンドラインにオプションを追加することで、これを実現できます。
ssh -X -L 5432:<DB server IP>:5432 -R 873:<local RSYNC server>:873 [user@]remote_ssh_server
これにより、リモートPostgreSQLサーバーへの直接転送、ローカル rsync サーバーへの逆トンネルが開かれ、GUIアプリケーションがローカルXサーバーに流れることができます。
また、 SSHトンネルを使用してさらに遠くのSSHサーバーに到達し、必要な数のファイアウォールレイヤーを貫通するトンネルを作成し、目的のポイントに到達できるまで各接続にトンネルを作成できます。
ssh -L 8022:<server2>:22 user@server1
ssh -L 8023:<server3>:22 -p 8022 user@localhost
ssh -p 8023 user@localhost
このシーケンスにより、各ステップで、server1およびserver2から、ローカルポート8023で開かれたトンネルが
8. 構成ファイル
複雑なシナリオでは、コマンドラインに複数のトンネルを作成すると、コマンドラインが非常に長くなる可能性があるため、注意が必要な場合があります。
そのため、 sshの最も優れた機能の1つは、構成ファイルで任意のコマンドラインパラメーターを許可することです。 グローバルsshクライアント構成ファイル( / etc / ssh /ssh_configまたは/etc/ openssh / ssh_configにあります)を使用するか、〜にあるユーザー固有の構成ファイルを使用できます。 /.ssh/config。 デフォルトである存在しない場合は、新しいものを作成する必要があります。
これらのファイルでは、転送トンネルやプロキシなど、一般的に使用される各エンドポイントにデフォルト構成を指定できます。
host 10.1.4.100
ForwardX11 yes
LocalForward 0.0.0.0:5432 10.1.4.200:5432
RemoteForward localhost:8022 localhost:22
user baeldung
これにより、ユーザー’ baeldung ‘を使用して10.1.4.100のリモートSSHサーバーに接続し、次のことが可能になります。
- XWindowsリバーストンネル
- ローカルポート5432からリモートホスト10.1.4.200ポート5432への直接トンネリング
- SSHサーバーのローカルクライアントホストへのループバックインターフェイスのポート8022でのリバース/コールバックトンネル
圧縮、Kerberos認証転送など、他の多くのオプションを使用できます。 また、ホスト仕様ではワイルドカードを使用できます。
9. 永続的なトンネル
ちなみに、SSHトンネルはSSH接続が維持されている間だけ存在します。 セッションキープアライブの頻度とタイムアウトを構成して接続損失の検出を容易にすることもできますが、SSHセッションの作成と再接続を完全に自動化すると便利です。
そのための便利なソフトウェアはautosshです。 このユーティリティは、SSHセッションを自動的に作成および再作成できます。 SSHキーのチュートリアルに示すように、認証キーを追加すると、autosshが実行されている限り、ユーザーの介入なしにトンネルが開きます。 その構文は次のとおりです。
autossh [-V] [-M port[:echo_port]] [-f] [SSH_OPTIONS]
- -V:autosshバージョンを表示
- -M:ポートに直接トンネルを作成し、逆トンネルecho_portにループバックします。 それは生きているチェックメカニズムを提供します。 ただし、最近のOpenSSHでは、sshd_configファイルのServerAliveIntervalおよびServerAliveCountMaxオプションを使用して同様の結果を得ることができます。
- -f: ssh を実行する前に、autosshをバックグラウンドで強制的に実行します
- SSH_OPTIONS :sshを開始するために使用するオプション
このように、持続的接続を開始するには、次を使用できます。
autossh -X -L 5432:<DB server IP>:5432 -R 873:<local RSYNC server>:873 [user@]remote_ssh_server
ホスト構成を定義した場合、コマンドラインははるかに簡単です。
autossh -f [host]
10. 結論
この記事では、 sshを使用して、トンネリング機能を使用してリモートホストとの間で到達可能性を向上させるための優れたトリックをいくつか紹介しました。
ただし、ホストへのsshアクセスはサイバー攻撃の表面を広げることを常に覚えておく必要があります。 したがって、あらゆる種類のトンネリングを使用すると、リスクが高まり、SSHサーバーネットワークを介した水平方向の移動が容易になる可能性があります。
最後に、さらに高度なタイプのトンネリングがあります。tunデバイストンネリングです。 本格的なVPN(仮想プライベートネットワーク)のように機能するため、これはさらに危険です。 このタイプのトンネルは、エンドポイントが配置されている2つのリモートネットワークセグメントをバインドします。
これを使用して、両側がローカルネットワークまたはレイヤー3トンネル上にあるかのように動作するレイヤー2トンネルを作成できます。 この場合、各サイドには独自のIPサブネットワークがあり、SSHエンドポイントはそれらの間でトラフィックをルーティングするように構成する必要があります。