By

portwarpで ssm-session-manager を活用する

はじめに

AWSで最近リリースされた、ssm-session-manager と言う機能は、「IAMで権限管理ができるssh」なのだと思って、「これは便利なものができた」と喜んだのですが、実際に使ってみたらいろいろ制限がありました。

一つの問題は、/bin/shを決め打ちで起動してしまうことですが、他にも、ssh の代替にしようと思うと、以下のような機能が欲しくなります。

  • port forwarding
  • scp/rsync などのファイル転送

特に、テスト中などは、本来、プライベートなサーバを一時的に外から見たいということがよくあります。「プライベート」とは、AWS内にある別のサーバにAPIなどのサービスするのが目的で、ネットワーク的に外部に公開されていないものです。

そのネットワーク内に、sshができるサーバがあれば、ssh -L .... で、port forwardingをして、ローカルのサーバからAWS内のプライベートなサーバに接続することができます。しかし、ssm-session-managerには、この機能がありません。

そこで、これを実現するツールを作ってみました。

このアイディアは、下記の記事を元にしています。

portwarpとは

portwarpとは、piping-server経由で、サーバとクライアントを接続し、両者の間で port forwardingを行うツールです。

ポイントは、piping-serverportwarp server のつなぎ方ですね。

portwarp サーバからの outbound connection で接続するので、このサーバを動かすマシンのポートを開ける必要がないことです。つまり、VPC内で孤立しているネットワークに、外部から接続するトンネルを一時的に開けることができるわけです。

必要なもの

  • piping-server: portwap server および portwarp client からアクセスできるもの
  • docker または ruby 実行環境

以下の例では、piping-server の URL を https://piping.server/ として記述します。ご自分が使用されるサーバのURLと置き換えて使用してください。

portwarpのインストール

Dockerを使用する場合

$ docker pull essa/portwarp

rubyを使用する場合

$ git clone https://github.com/essa/portwarp
$ cd portwarp
$ bundle

Dockerでインストールした場合は、起動方法は以下のようになります。

$ docker run --net=host -ti essa/portwarp portwarp .....

rubyの場合は、次のようになります。

$ bundle exec bin/portwarp .....

使用方法

最初にサーバ側を起動します。

$ docker run --net=host -ti essa/portwarp portwarp https://piping.server/
I, [2019-03-24T13:36:14.547737 #1]  INFO -- : portwarp start
I, [2019-03-24T13:36:14.547936 #1]  INFO -- : server mode
I, [2019-03-24T13:36:14.589788 #1]  INFO -- : server start url = https://piping.server/29ef18e25dddece9

portwarp は起動時に、制御用パイプのURLを表示します。これをクライアント側の起動パラメータとしてください。

$ bundle exec bin/portwarp https://piping.server/29ef18e25dddece9 8080 private.server.local:80

クライアント側では、URLの後に、転送用ポートの番号と転送先を指定します。パラメータが3つ以上あるとクライアントモードになります。

クライアント側が起動したら、localhost:8080private.server.local:80 に接続された状態になります。このまま、ローカルマシンのブラウザで http://localhost:8080 にアクセスすると、転送先のサーバに接続できます。

次のように転送先の後ろにコマンドをつけると、port forwardingの確立後に、そのコマンドを起動します。

$ bundle exec bin/portwarp https://piping.server/29ef18e25dddece9 8080 private.server.local:80 curl http://localhost:8080/

そのサーバで sshd が起動していれば ssh で接続することもできます。

$ bundle exec bin/portwarp https://piping.server/29ef18e25dddece9 1022 localhost:22 ssh -p 1022 ssm-user@localhost

この場合、転送先の localhost:22 は、portwarp サーバから見た localhostなので、portwarpサーバを起動しているマシンの sshd に接続します。

このように ssh のポート指定をすれば、sshでファイル転送を行う、scp, rsynce, git なども同様に使用することができます。

rsyncの使用例

$ bundle exec bin/portwarp https://cached-downloads.degica.com:8081/5820c3fd8748bb7f 2022 localhost:22 'rsync -rv -e "ssh -p 2022" source_directory user@localhost:target_directory'

まとめ

portwarpというツールを併用することにより、ssh による外部からのアクセスを完全に遮断して、ssm-session-managerのみの運用に切り替えることができました。

  • 社内専用の piping-serverを用意する(VPN経由で接続するもの)
  • プライベートネットワーク内に踏み台用サーバを用意し、ssm-session-managerの権限を与える
  • 踏み台サーバのセキュリティグループは、inboundは完全遮断、outboundは 80 のみ許可
  • プライベートネットワーク内のサーバには openssh-server をインストールして、port 22は、踏み台サーバからのアクセスのみ許可する

これで、上記の例のようにして、踏み台サーバ経由で、プライベートネットワーク内のサーバに外部から ssh接続したり、プライベートなサーバに直接アクセスして調査したり、テストしたりすることができます。

この経路が開いているのは portwarp サーバ起動中だけです。これを終了すれば、外部からのアクセスは完全にできなくなります。これで、通常時は安全な運用をしながら、導入時やトラブル時には、制限なく自由にアクセスすることができるようになりました。

また、そのアクセスの権限は、ssmの権限として、AWS IAMによって管理することができます。

一緒にユニークな決済サービスを作ってくれる Rails エンジニアを募集中です!
多国籍なメンバーと一緒に仕事をしてみませんか?詳細はこちらのリンクです:D