ある機器へSSHアクセスする際、他のサーバ(jump server)を経由しないといけない場合は、SSHのproxyコマンドは有効である。簡単な環境でその使い方について説明する。
環境
- OS X: Mojave
- Docker desktop ver 2.0.0.3
環境構築
仮に以下のようなな環境ある。ユーザが target server
へアクセスしたい。もしくは、targetサーバとscpでファイル交換したい。しかし、セキュリティ制限によって、ユーザから直接にtarget server
へアクセスするのは許可されていない。かならずproxy server
を経由する。一番シンプルなのは、順次にproxyサーバへログインしてから、targetサーバへログインして、作業さうる
毎回2段ログインすると大変である。より簡単な方法はSSHのproxyコンマンドを使うことである。簡単にSSH proxyコマンドを説明するために、以下のNWをdockerイメージを使い説明する。
+-------------+ +--------------+ +---------------+
| ユーザ +---+ proxy server +---+ target server |
+-------------+ +--------------+ +---------------+
Dockerイメージ
まず、簡単に環境をつくるため、sshサーバを動くdockerイメージを作成する。
以下のDockerfileを準備する。
FROM centos:centos7
# OpenSSH サーバをインストールする
RUN yum -y install openssh-server openssh-clients
# root でログインできるようにする
RUN sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config
# root のパスワードを 設定
RUN echo 'rootpassword!' | passwd --stdin root
# 使わないにしてもここに公開鍵を登録しておかないとログインできない
RUN ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -N "" -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t ed25519 -N '' -f /etc/ssh/ssh_host_ed25519_key
# sshd の使うポートを公開する
EXPOSE 22
# sshd を起動する
CMD ["/usr/sbin/sshd", "-D"]
必要に応じて rootpassword!
を変更し、Dockerfileと同じフォルダーでイメージを作成する。
$ docker build -t centos7-sshd .
成功すると、以下のようなイメージが出来上がる。
bash-3.2# docker images centos7-sshd
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-sshd latest d9c6d7216802 22 hours ago 299MB
このイメージを使い、2つコンテナーを起動させる。なお、proxyサーバ
を従来のport 22の代わりに、20022を待ち受けるようにした。
$ docker run -d --hostname centos7-sshd-proxy -p 20022:22 --name centos7-sshd-proxy centos7-sshd:latest
$ docker run -d --hostname centos7-sshd-target --name centos7-sshd-target centos7-sshd:latest
ここで2つsshサーバのコンテナが動くようになる。次回、コンテナーを起動したいときは簡単にstart
でできる。
$ docker start centos7-sshd-proxy centos7-sshd-target
2段ログイン
前節で作った2つのコンテナのSSH portは以下のようになる。
+-------------+ +--------------+ +---------------+
| ユーザ +----(20022)-+ proxy server +---(22)-+ target server |
+-------------+ +--------------+ +---------------+
ユーザがホストから127.0.0.2:20022へ proxyサーバ
へアクセスできる。
$ ssh -p 20022 root@127.0.0.1
Enter passphrase for key '/Users/<省略>/.ssh/id_rsa':
root@127.0.0.1's password:
X11 forwarding request failed on channel 0
Last login: Mon May 20 11:33:29 2019 from gateway
更に、そこからport 22でtargetサーバ
へSSHログインできる。ここで、proxy
からtarget
へアクセスする際、docker内部のNWを使う。そのIPは以下のように確認できる
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos7-sshd-target
172.17.0.3
このIPを使い、target
へSSHをしてみる
[root@centos7-sshd-proxy ~]# ssh root@127.17.0.3
<省略>
root@127.17.0.3's password:
Last login: Mon May 20 11:40:34 2019 from gateway
[root@centos7-sshd-proxy ~]#
proxyサーバを経由してtargetへログインする環境を構築して、確認できた。
proxyコマンド
上のように2段ログインより、proxyコマンドを使うとこより、直接にtargetへログインすることができる。
bash-3.2# ssh -o ProxyCommand='ssh -p 20022 -W %h:%p root@127.0.0.1' root@172.17.0.3
root@127.0.0.1's password:
root@172.17.0.3's password:
Last login: Mon May 20 11:47:38 2019 from 172.17.0.2
[root@centos7-sshd-target ~]#
パスワードが2回に聞かれ、1回目はproxyサーバのもので、2回目はtargetのものである。proxyコマンドは以下のようなフォーマットになる。
ssh -o ProxyCommand='ssh -l root -p 20022 -W %h:%p <proxyユーザ>@<proxyサーバ>' <targetユーザ>@<targetアドレス>
もうちょっと遊ぶ
とりあえず、やりたいことはできた。しかし、よく%h:%p
はデフォルトホスト名とデフォルトポートだと説明されるが、少し意味わからない。ちょっといじってみた
bash-3.2# ssh -o ProxyCommand='ssh -p 20022 -W 172.17.0.3:22 root@127.0.0.1' xxx
root@127.0.0.1's password:
root@xxx's password:
Last login: Mon May 20 11:57:13 2019 from 172.17.0.2
[root@centos7-sshd-target ~]#
これで、proxy経由でtargetへログインできた。それに、途中でなぞののroot@xxx's password:
表示になっている。もうちょっと調べてみる。
まず、-W
についてsshのmanは以下のように書いてある
-W ホスト :ポート
クライアントの標準入力と標準出力を、安全な通信路を通してホスト のポート 上に接続します。このオプションは、-N ,-T ,ExitOnForwardFailureおよびClearAllForwardingsを暗黙のうちに含んでいますが、これらは設定ファイルまたは-o オプションにより上書きすることができます。
-W
はフォワードの設定するものである。今回の目的であれば、proxyサーバへログインした後、全てinput/output は %h:%p へフォワードされている。すなわち、ユーザからの操作はすべてtargetへフォワードされている。なお、%h
,%p
はProxyCommand中の特別意味を持っている。%h
はProxyCommandの後(本来接続したい)のホストで、%p
はその接続の時にポート番号である。%h
は明示的に書かれている場合、ホストはあまり意味がもっていなくなる(上のxxx
)
sshログインと同様に、scp
とProxyコマンドを使い、`targetサーバ`とフィアルやりとりも可能
$ scp -o ProxyCommand='ssh -p 20022 -W %h:%p root@127.0.0.1' test.txt root@172.17.0.3:/tmp/
まとめ
簡単にsshサーバのdockerイメージをサクセスおよびそのイメージを使い、sshのproxyコマンドの追加たを説明した。