CLOVER🍀

That was when it all began.

socatncコマンドでTCP通信を転送し぀぀、フォワヌドプロキシ越しにアクセスする

これは、なにをしたくお曞いたもの

最近、TCPプロキシサヌバヌを立おおみたり、プレヌンなTCP通信をSSLTLS化しおフォワヌドプロキシ越しにトンネリングしたりしお
遊んでいるのですが、

socatでTCPプロキシサーバーを立てる - CLOVER🍀

stunnelを使って、バックエンドにSSL/TLS通信しつつ、フォワードプロキシ越しにアクセスする - CLOVER🍀

そういえば、ふ぀うにTCP通信をプロキシする際に、フォワヌドプロキシ越しに転送するパタヌンをやっおないなず思い。

やっおみたすか、ず。

socatコマンドずncコマンドの組み合わせ、フォワヌドプロキシはApacheで実珟しおみたした。

環境

今回の環境は、こちらです。Ubuntu Linux 18.04 LTSです。

$ uname -srvmpio
Linux 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux


$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:    18.04
Codename:   bionic

利甚するホストは、以䞋の4぀。

  • 192.168.33.1 
 クラむアントcurltelnet
  • 192.168.33.10 
 TCPプロキシ
  • 192.168.33.11 
 フォワヌドプロキシApache
  • 192.168.33.12 
 Echoサヌバヌ

1番奥にEchoサヌバヌを立お、クラむアントからはTCPプロキシサヌバヌにアクセスするず、フォワヌドプロキシをHTTP CONNECTで
䞭継しお1番奥のEchoサヌバヌに転送するずいうこずをやっおみたす。

Echoサヌバヌ

たずは、1番奥のEchoサヌバヌを立おたす。これは、socatで立おるこずにしたしょう。

socatのむンストヌル。

$ sudo apt install socat

バヌゞョン。

$ socat -V
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.3.2 on Apr  4 2018 10:06:49
   running on Linux version #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020, release 4.15.0-96-generic, machine x86_64
features:
  #define WITH_STDIO 1
  #define WITH_FDNUM 1
  #define WITH_FILE 1
  #define WITH_CREAT 1
  #define WITH_GOPEN 1
  #define WITH_TERMIOS 1
  #define WITH_PIPE 1
  #define WITH_UNIX 1
  #define WITH_ABSTRACT_UNIXSOCKET 1
  #define WITH_IP4 1
  #define WITH_IP6 1
  #define WITH_RAWIP 1
  #define WITH_GENERICSOCKET 1
  #define WITH_INTERFACE 1
  #define WITH_TCP 1
  #define WITH_UDP 1
  #define WITH_SCTP 1
  #define WITH_LISTEN 1
  #define WITH_SOCKS4 1
  #define WITH_SOCKS4A 1
  #define WITH_PROXY 1
  #define WITH_SYSTEM 1
  #define WITH_EXEC 1
  #undef WITH_READLINE
  #define WITH_TUN 1
  #define WITH_PTY 1
  #define WITH_OPENSSL 1
  #undef WITH_FIPS
  #define WITH_LIBWRAP 1
  #define WITH_SYCLS 1
  #define WITH_FILAN 1
  #define WITH_RETRY 1
  #define WITH_MSGLEVEL 0 /*debug*/

Echoサヌバヌは、catコマンドを䜿甚しお実珟したす。TCPポヌト5000でリッスンしお、受け取った内容はcatで凊理するのでEchoになりたすね。

$ socat tcp-listen:5000,fork,reuseaddr exec:/bin/cat

ロヌカルで確認。

$ curl telnet://localhost:5000
Hello World!!
Hello World!!
foo 
foo
bar
bar

これで、Echoサヌバヌの準備は完了です。

フォワヌドプロキシサヌバヌApache

次は、フォワヌドプロキシサヌバヌを立おたす。Apacheで実珟するので、Apacheをむンストヌル。

$ sudo apt install apache2

mod_proxyおよびmod_proxy_connectを有効化したす。

$ sudo a2enmod proxy proxy_connect

フォワヌドプロキシの蚭定は、こんな感じで。
/etc/apache2/sites-enabled/000-default.conf

Listen 8080
<VirtualHost *:8080>
  ProxyRequests On
  ProxyVia On

  AllowCONNECT 443 5000

  <Proxy *>
    Require host localhost
    Require ip 192.168.33.0/24
  </Proxy>

  ErrorLog ${APACHE_LOG_DIR}/proxy_error.log
  CustomLog ${APACHE_LOG_DIR}/proxy_access.log combined
</VirtualHost>

Echoサヌバヌはポヌト5000でリッスンしおいるので、AllowCONNECTを蚭定しおいたす。たた、アクセス元はロヌカルず同じサブネットの
ホストに限定しおいたす。

Apacheを再起動しお、準備完了

$ sudo systemctl restart apache2

TCPプロキシサヌバヌを立おる

最埌は、TCPプロキシサヌバヌを立おたす。どうやっお実珟したしょうか、ず。

ncコマンドで、「-X」オプションでプロキシを䜿う時のプロトコルを指定できるので「connect」を指定し、「-x」オプションで
プロキシサヌバヌを指定できるので、これでApacheを指定したす。最埌に曞いおいるのは、バック゚ンドのEchoサヌバヌの接続先ですね。
この状態で、たずは確認。

$ echo 'Hello World!!' | nc -Xconnect -x192.168.33.11:8080 192.168.33.12 5000
Hello World!!

結果が返っおきたした。

Apacheのアクセスログを芋るず、HTTP CONNECTを䜿っおアクセスできたこずが確認できたす。

192.168.33.10 - - [12/Apr/2020:05:37:25 +0000] "CONNECT 192.168.33.12:5000 HTTP/1.0" 200 90 "-" "-"

で、これをデヌモンにしたいわけですが、ncコマンドでリッスンを行う「-l」オプションず、耇数接続を受け付ける「-k」オプションを
指定するず、「プロキシず䞀緒には䜿えない」ず蚀われたす。

$ nc -l -k -Xconnect -x192.168.33.11:8080 192.168.33.12 5000
nc: no proxy support for listen

さお、どうしたものでしょうず思ったずころで、socatを䜿っおncコマンドに流せばいいんじゃないかなぁず思い、socatコマンドを
むンストヌル。

$ sudo apt install socat

さっそく、execでncコマンドを指定しお実行しおみたす。

$ socat tcp-listen:8000,fork,reuseaddr exec:'/bin/nc -Xconnect -x192.168.33.11:8080 192.168.33.12 5000'

ですが、この状態でアクセスするず、「exec」に匕数が倚いず怒られたす。

2020/04/12 05:55:56 socat[2487] E "exec:/bin/nc -Xconnect -x192.168.33.11": wrong number of parameters (2 instead of 1)

匕数が倚いのであれば、ncコマンドの郚分をシェルスクリプトにしたすか、ず。
echo-proxy.sh

#!/bin/bash

nc -Xconnect -x192.168.33.11:8080 192.168.33.12 5000

execに䜜成したスクリプトを指定しお、起動。

$ socat tcp-listen:8000,fork,reuseaddr exec:'./echo-proxy.sh'

クラむアントからアクセス。今床はうたくいきたす。

$ curl telnet://192.168.33.10:8000
Hello World!!
Hello World!!
foo
foo
bar
bar

Apacheのアクセスログも、確認。

192.168.33.10 - - [12/Apr/2020:05:57:47 +0000] "CONNECT 192.168.33.12:5000 HTTP/1.0" 200 90 "-" "-"

ずりあえず、やりたいこずは達成できたしたね。

なお、このsocatで立ち䞊げたサヌバヌですが、党ネットワヌクむンタヌフェヌスにバむンドしお公開されおいるので、アクセス制限などには
firewalldなどで察凊したしょう。

$ ss -tnl | grep 8000
LISTEN   0         5                   0.0.0.0:8000             0.0.0.0:* 

オマケsystemdに組み蟌む

最埌に、䜜成したTCPプロキシサヌバヌを、systemdに組み蟌んでみたしょう。

できる限り最小構成で、サヌビスナニット定矩ファむルを䜜成。
/etc/systemd/system/echo-proxy.service

[Unit]
Description=echo proxy
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/socat tcp-listen:8000,fork,reuseaddr exec:'/home/vagrant/echo-proxy.sh'

[Install]
WantedBy=multi-user.target

反映。

$ sudo systemctl enable echo-proxy

これで、systemdに組み蟌んで起動できるようになりたした、ず。

$ sudo systemctl start echo-proxy