1 ssh ポートフォワーディングとは?
暗号化機能を備えていないアプリケーションの通信をsshが間に入って中継することで、暗号化を行うことができます。
具体的には以下のようになります。
1. アプリXがポートX宛てにデータを送信する
2. ポートXでListen(受信データ待ち)しているsshにデータが届けられる
3. sshからsshdにデータを送信する。このとき、クライアントでデータを暗号化する。
4. サーバは受信したデータを復号する
5. 復号したデータをsshdが受信する
6. sshdがポートYでListenしているアプリYにデータを転送する
client(ローカル) server(リモート) +----------------------+ +---------------------+ | | | | | | | | | | | アプリY | | | | A | | | | | | |アプリX ---> ポート(X)| | ポート(Y) | | | | | A | | V | | | | | ssh ----|----(暗号化データ)----|--------> sshd | | | | | | | | | +----------------------+ +---------------------+
2 検証環境
2.1 ネットワーク構成
サーバとクライアントの2台構成です。図中のeth0はNICの名前です。
192.168.122.0/24 client(eth0) ------------------------------------------(eth0) server .181 .216
3 ポートフォワーディングの書式
ポートフォワーディングは、以下の方法があります。書式は次のとおりです。
- ローカルからリモートへのポートフォワーディング(-L)
ssh -L 転送元ポート番号:転送先ホスト:転送元ポート番号 sshサーバ
- リモートからローカルへのポートフォワーディング(-R)
ssh -R 転送元ポート番号:転送先ホスト:転送元ポート番号 sshサーバ
4 ローカルからリモートへのポートフォワーディング
ここでは、ローカルからリモートへのポートフォワーディングを試してみます。
4.1 接続手順
サーバでncコマンドを実行します。ncプロセスが11111番ポートでListenするようにします。なお、ncコマンドのインストール方法、使い方は、ncコマンドの使い方(ネットワーク実験の幅が広がるなぁ~) - hana_shinのLinux技術ブログを参照してください。
[root@server ~]# nc -kl 11111
サーバでターミナルをもう1つ開きます。そして、lsofコマンドを実行します。ncプロセスがTCPの11111番ポートでListenしていることがわかります。なお、lsofコマンドのインストール方法、使い方はlsofコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
[root@server ~]# lsof -c nc -a -i -a -nP COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nc 1810 root 3u IPv6 33827 0t0 TCP *:11111 (LISTEN) nc 1810 root 4u IPv4 33828 0t0 TCP *:11111 (LISTEN)
クライアントの22222番ポートへのデータ送信をサーバの11111番ポートに転送する設定をします。
[root@client ~]# ssh -L 22222:192.168.122.216:11111 192.168.122.216 root@192.168.122.216's password: Permission denied, please try again. root@192.168.122.216's password: Last failed login: Wed Apr 13 19:20:07 JST 2022 from client on ssh:notty There was 1 failed login attempt since the last successful login. Last login: Wed Apr 13 19:15:29 2022 from client [root@server ~]#
このとき、クライアントでlsofコマンドを実行します。sshがTCPの22222番ポートでListenしていることがわかります。
[root@client ~]# lsof -i -a -i:22222 -Pn COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ssh 1704 root 4u IPv6 36501 0t0 TCP [::1]:22222 (LISTEN) ssh 1704 root 5u IPv4 36502 0t0 TCP 127.0.0.1:22222 (LISTEN)
クライアントでncコマンドを実行します。
[root@client ~]# nc localhost 22222 12345
このとき、クライアントでlsofコマンドを実行します。ncコマンドは、sshがListenしているTCPの22222番ポートにTCPコネクションを確立していることがわかります。
[root@client ~]# lsof -c nc -a -i -a -nP COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nc 1739 root 3u IPv6 36556 0t0 TCP [::1]:40726->[::1]:22222 (ESTABLISHED)
次に、クライアントで"12345"と入力します。
[root@client ~]# nc localhost 22222 12345
サーバでncコマンドの実行結果を確認します。クライアントで入力した文字列が表示されることがわかります。
[root@server ~]# nc -kl 11111 12345
4.2 ポートフォワーディング中の状態
ポートフォワーディング中は、以下のようになっています。()内はポート番号を表します。
client server +-----------------------------------------+ +-----------------------------------------+ | | | | | nc ssh | | sshd nc | | +---------+ +------------------+ | | +------------------+ +---------+ | | | | | | | | | | | | | | | (40726) | | (22222) (xxxxx) | | | | (22) (YYYYY) | | (11111) | | | +---------+ +------------------+ | | +------------------+ +---------+ | | A | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +--- localhost ---+ | | | | +--------+ | | | | (127.0.0.1) | | | | |+------------------------+ | | | | | | | || | | | | | | | || | +---|-------------------------- (eth0) ---+ +-- (eth0) -------------------------------+ | .181 | | .216 | | | V +------------------+ 端末 192.168.122.0/24
4.3 送信データの確認
ポートフォワーディングのとき、送信データが暗号化されているかどうかを確認してみます。ポートフォワーディングを使用すると送信データが暗号化されますが、使用しないと暗号化されないことを確認します。
4.3.1 ポートフォワーディングを使用しない場合
サーバで firewall-cmdコマンドを実行します。ncプロセスがListenするTCPの11111番ポートを解放します。なお、 firewall-cmdコマンドの使い方は、firewall-cmdの使い方 - hana_shinのLinux技術ブログを参照してください。
[root@server ~]# firewall-cmd --add-port=11111/tcp success
ポートの状態を確認します。TCPの11111番ポートが解放されたことがわかります。
[root@server ~]# firewall-cmd --list-ports 11111/tcp
クライアントでtcpdumpコマンドを実行します。なお、tcpdumpコマンドの使い方は、tcpdumpの使い方(基本編) - hana_shinのLinux技術ブログを参照してください。
[root@client ~]# tcpdump -i eth0 src host 192.168.122.181 and dst port 11111 -xx -n
クライアントでncコマンドを実行します。そして、クライアントからサーバの11111番ポートにデータ("111...111")を送信します。
[root@client ~]# nc 192.168.122.216 11111 1111111111111111111111111111111111111111
tcpdumpの実行結果を確認します。クライアントで入力した文字列("111...111")が暗号化されていないことがわかります。1はASCIIコードで0x31です。
[root@client ~]# tcpdump -i eth0 src host 192.168.122.181 and dst port 11111 -xx -n tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 20:19:45.956086 IP 192.168.122.181.37590 > 192.168.122.216.vce: Flags [P.], seq 10279061:10279102, ack 1430832885, win 229, options [nop,nop,TS val 4362757 ecr 4326873], length 41 0x0000: 5254 006f b0ca 5254 00d0 e3a7 0800 4500 0x0010: 005d b0ed 4000 4006 12cf c0a8 7ab5 c0a8 0x0020: 7ad8 92d6 2b67 009c d895 5548 c6f5 8018 0x0030: 00e5 772e 0000 0101 080a 0042 9205 0042 0x0040: 05d9 3131 3131 3131 3131 3131 3131 3131 0x0050: 3131 3131 3131 3131 3131 3131 3131 3131 0x0060: 3131 3131 3131 3131 3131 0a
4.3.2 ポートフォワーディングを使用した場合
クライアントでtcpdumpを実行します。
[root@client ~]# tcpdump -i eth0 src host 192.168.122.181 and dst port 22 -xx -n
もう1つターミナルを開きます。そして、ncコマンドを実行して、localhostの22222番ポートに文字列("111...1111")を送信します。
[root@client ~]# nc localhost 22222 1111111111111111111111111111111111111111
tcpdumpの実行結果を確認します。クライアントで入力した文字列("111...111")は暗号化されていることがわかります。
[root@client ~]# tcpdump -i eth0 src host 192.168.122.181 and dst port 22 -xx -n tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 20:10:25.072515 IP 192.168.122.181.52946 > 192.168.122.216.ssh: Flags [P.], seq 777051684:777051760, ack 3185009407, win 309, options [nop,nop,TS val 3801873 ecr 3713766], length 76 0x0000: 5254 006f b0ca 5254 00d0 e3a7 0800 4510 0x0010: 0080 2e56 4000 4006 9533 c0a8 7ab5 c0a8 0x0020: 7ad8 ced2 0016 2e50 de24 bdd7 62ff 8018 0x0030: 0135 7751 0000 0101 080a 003a 0311 0038 0x0040: aae6 ad38 3b20 9e12 7e80 604b 86fd ecd2 0x0050: 9b4d 9690 9737 9dc8 64c2 f008 1258 af14 0x0060: c43b c994 8a10 fd86 59cd 87b5 434e 7cc4 0x0070: 4993 9295 63cb b450 a8c3 c4db 20ab b8f0 0x0080: 5820 fbbb 05bb cc49 db3a 6e96 034b
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ