socatコマンドを利用した お手軽TCPリレー

2020.10.02

こんにちは!DA(データアナリティクス)事業本部 インテグレーション部の大高です。

AWS環境下でプライベートサブネットからの接続しか許可していないRDSなどに接続する場合、パブリックサブネット上のEC2インスタンスを経由してアクセスするケースがあるかと思います。

<このようなイメージです>

やり方は色々あると思いますが、今回はsocatコマンドを利用した接続を試してみたので書いていきたいと思います!

socatコマンドとは?

socatは「Multipurpose relay (SOcket CAT)」の頭文字を取ったコマンドで、ざっくりと説明すると「様々なソケット通信をリレーしてくれるユーティリティ」です。

man コマンドで見てみると以下のように説明されていました。

Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources (see address types), and because lots of address options may be applied to the streams, socat can be used for many different purposes.

Socatは、2つの双方向バイトストリームを確立し、それらの間でデータを転送するコマンドラインベースのユーティリティです。 ストリームは、さまざまなタイプのデータシンクとソース(アドレスタイプを参照)の大規模なセットから構築でき、多くのアドレスオプションがストリームに適用される可能性があるため、socatはさまざまな目的に使用できます。

EC2インスタンスにsocatをインストールする

まずはインストールですが、これは単純にyumコマンドでインストールします。

$ sudo yum install socat -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package socat.x86_64 0:1.7.3.2-2.amzn2.0.1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================
 Package                Arch                    Version                               Repository                   Size
========================================================================================================================
Installing:
 socat                  x86_64                  1.7.3.2-2.amzn2.0.1                   amzn2-core                  291 k

Transaction Summary
========================================================================================================================
Install  1 Package

Total download size: 291 k
Installed size: 1.1 M
Downloading packages:
socat-1.7.3.2-2.amzn2.0.1.x86_64.rpm                                                             | 291 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : socat-1.7.3.2-2.amzn2.0.1.x86_64                                                                     1/1
  Verifying  : socat-1.7.3.2-2.amzn2.0.1.x86_64                                                                     1/1

Installed:
  socat.x86_64 0:1.7.3.2-2.amzn2.0.1

Complete!

socatコマンドを使ってみる

では使ってみましょう。今回はRDS(PostgreSQL)に対して通信をしたいので、EC2インスタンスのグローバルIPアドレスに対するTCP 5432ポートへの通信を、RDSへリレーさせます。

具体的には以下のコマンドとなります。

$ socat tcp4-listen:5432,reuseaddr,fork TCP:foo-bar.ap-northeast-1.rds.amazonaws.com:5432

指定したオプションを細かくみていきましょう。

tcp4-listen:5432

これは見たまんまですね。TCPの5432ポートをLISTENしています。

reuseaddr

このオプションを付けることで、コネクションが切れてもサーバープロセスを直ちに再起動してくれるそうです。

Option reuseaddr allows immediate restart of the server process.

fork

コネクション毎に子プロセスとしてプロセスをフォークしてくれるオプションになります。これで複数接続ができるということですね。

(TCP4-LISTEN) and forkcqs a new child process for each connection

TCP:foo-bar.ap-northeast-1.rds.amazonaws.com:5432

これもそのままですね。TCPでfoo-bar.ap-northeast-1.rds.amazonaws.com5432ポートに受け渡しています。

ローカルのPC環境からどうやって接続するのか?

上記でEC2上でsocatを実行したら、あとはローカルのPC環境からEC2インスタンスのグローバルIPアドレスを指定して接続するだけです。

たとえば、EC2インスタンスのグローバルIPアドレスが50.100.200.1だったとすると、50.100.200.15432ポートにアクセスすると、EC2インスタンスのsocatが通信をリレーしてくれるので、あたかもfoo-bar.ap-northeast-1.rds.amazonaws.com5432ポートへアクセスしているように処理できるようになります。

まとめ

以上、socatコマンドのご紹介でした。標準コマンドではないのでインストールが必要なのですが、お手軽に利用できるので個人的には好きなコマンドです。

どなたかのお役に立てば幸いです。それでは!