公開サーバのSSHのポートフォワード機能を使ってバックエンドのPCと通信(TCP, UDP)する。


概要

自分が公開しているサーバでSSHサービスが動いているとき、SSHのポートフォワード機能を使えばそのサーバの後ろにあるPCとかと通信できる。
なるべく追加インストールしなくてすむようにした。

想定ネットワーク

DMZ上の公開サーバでSSHサービスが動いていて、そのバックエンドのネットワークにPCとかサーバが存在していると想定する。

概念図
     [clientA(Linux)]   [clientB(Windows)]
     (192.168.22.5)    (192.168.22.100)
            |                    |
            +--------------------+
            |
            |
     (192.168.22.200)
    [SSH server(Linux)]
            |
            +----------------+
            |                |
          [PC]            [server]
    (192.168.111.100)  (192.168.111.200)

TCP通信

clientA(Linux)からSSH server(Linux)に対してSSHポートフォワード設定を行う。

ダイナミックポートフォワード(SOCKS5 proxy)を使う

SSHのダイナミックポートフォワード設定

clientA(Linux)
# ssh -D 192.168.22.5:9150 -f -N [email protected]
[email protected]'s password:
#

proxychains設定

/etc/proxychains.confを下記のように編集する。

clientA(Linux)
# vi /etc/proxychains.conf

------------------------
(/etc/proxychains.confを下記の内容で編集)
# Quiet mode (no output from library)
quiet_mode

(snip)

[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks5  192.168.22.5 9150

バックエンドのPC(192.168.111.100)にRDP接続してみる

clientA(Linux)
# proxychains xfreerdp /v:192.168.111.100 /u:**** /p:****
ProxyChains-3.1 (http://proxychains.sf.net)
[10:47:00:753] [6624:6625] [INFO][com.freerdp.client.common.cmdline] - loading channelEx cliprdr
[10:47:00:907] [6624:6625] [INFO][com.freerdp.gdi] - Local framebuffer format  PIXEL_FORMAT_BGRX32
[10:47:00:907] [6624:6625] [INFO][com.freerdp.gdi] - Remote framebuffer format PIXEL_FORMAT_RGB16
[10:47:00:987] [6624:6625] [INFO][com.winpr.clipboard] - initialized POSIX local file subsystem

ローカルポートフォワードを使う

clientB(Windows)の「リモートデスクトップ接続」を使ってバックエンドのPC(192.168.111.100)にRDP接続するときに使える。

SSHのローカルポートフォワード設定

clientA(Linux)
# ssh -L 192.168.22.5:3389:192.168.111.100:3389 [email protected]

clientB(Windows)からclientA(Linux)経由でバックエンドのPC(192.168.111.100)にRDP接続してみる

UDP通信

ローカルポートフォワード設定とnetcat relayを組み合わせる。
clientA(Linux)SSH server(Linux)の双方で操作する必要がある。
今回はバックエンドにあるserver(192.168.111.200)とUDP/161(snmp)通信を行う。
ちなみにUDPは通信が途切れやすく、都度都度フォワードを再設定する必要があった。

SSH server(Linux)側の設定

操作ユーザにroot権限は必要ない。

netcat relay用のFIFOを作成する。

SSHserver(Linux)
$ mkfifo /tmp/pipe

netcat relayを設定する。

UDP通信をフォワードしたいIPとポート(今回は192.168.111.200:161)を指定する。

  • SSH serverではTCP/31337で通信を待ち受ける。待ち受けポートがTCPなので注意。
  • UDP通信のフォワード先(192.168.111.200)からの出力を/tmp/pipeに流し込み、それを自身のTCP/31337に返すイメージ。
SSHserver(Linux)
$ nc -l -p 31337 < /tmp/pipe | nc -u 192.168.111.200 161 > /tmp/pipe

clientA(Linux)側の設定

SSHのローカルポートフォワード設定

clientA(Linux)
# ssh -L 1337:localhost:31337 [email protected]

netcat relay用のFIFOを作成する。

clientA(Linux)
# mkfifo /tmp/pipe

netcat relayを設定する。

  • clientA(Linux)ではUDP/161(snmp)で通信を待ち受ける。
  • 自身のTCP/1337からの出力を/tmp/pipeに流し込み、それを自身のUDP/161に返すイメージ。
clientA(Linux)
# nc -l -u -p 161 < /tmp/pipe | nc localhost 1337 > /tmp/pipe

snmpwalkやってみる。

バックエンドのserver(192.168.111.200)に対してUDP/161で通信し、情報を取得できた。

clientA(Linux)
# snmpwalk localhost -c public -v2c

iso.3.6.1.2.1.1.1.0 = STRING: "Linux fileserver 4.8.0-36-generic #36~16.04.1-Ubuntu SMP Sun Feb 5 09:39:57 UTC 2017 x86_64"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (238794) 0:39:47.94
iso.3.6.1.2.1.1.4.0 = STRING: "Me <[email protected]>"
iso.3.6.1.2.1.1.5.0 = STRING: "fileserver"
iso.3.6.1.2.1.1.6.0 = STRING: "Sitting on the Dock of the Bay"
iso.3.6.1.2.1.1.7.0 = INTEGER: 72
(snip)