Quantcast
Channel: mattintosh note
Viewing all articles
Browse latest Browse all 891

SSH の Match Exec で接続元の環境が異なっても同じホスト名を使いたい

$
0
0

私はよく外出先から自宅のサーバに SSHで接続する。

自宅のサーバに「家にいるときはプライベート IP やローカルドメイン、外出先からだと自宅のグローバル IP やグローバルドメインなどで接続する」という場合、ホスト名別に設定を分けて書いていた。コンフィグに書くとこんな感じ。

~/.ssh/config

Hostrpi rpi-homeUser pi
    IdentityFile ~/.ssh/rpi_id_rsa

HostrpiHostName192.168.1.100Hostrpi-homeHostNameexample.comPort12345

ホスト名を変えれば家でも外出先でもサーバに簡単に接続できる。

Terminal

# 自宅から接続する場合
$ ssh rpi

# 外出先から接続する場合
$ ssh rpi-home

自分がいま自宅にいるか外出先かは問うまでもないのでこの設定でも特に問題は無い。しかし、やはり人間なのでたまに外にいるのにローカルのホスト名を叩いてしまったりすることがある。当然そんなホストは無いので SSHは沈黙し、そしてホスト名を間違ったことに気づく。

そこで、ssh_config の Matchブロックを使うことで条件に応じて HostNamePortを変えるようにしてみる。Execの終了ステータスが 0でない場合に True とする場合は !Execで反転する。if else が使えないので仕方がない。

HostrpiUser pi
    IdentityFile ~/.ssh/rpi_id_rsa

# ホスト名 rpi で ping が成功した場合MatchHostrpi  Exec "ping -c1 -t1 raspberrypi.local"HostNameraspberrypi.local# ホスト名 rpi で ping が失敗した場合MatchHostrpi !Exec "ping -c1 -t1 raspberrypi.local"HostNameexample.comPort12345

ホスト名で一致する Matchが二つあるので pingも二回行われてしまうが、その結果によって HostNameが切り替わるので接続時のホスト名を気にする必要はなくなる。

$ ssh rpi

True になる Matchが複数存在する場合は先に出現した方が利用される。下記に雑な例を示すが、この状態で自宅で実行すると pingが両方とも成功して先に記述されている HostName 192.168.1.100が有効になる。

HostrpiUser pi
    IdentityFile ~/.ssh/rpi_id_rsa

MatchHostrpi Exec "ping -c1 -t1 192.168.1.100"HostName192.168.1.100MatchHostrpi Exec "ping -c1 -t1 192.168.1.100"HostNameexample.comPort12345

しかし、例えば公共の場所に自宅のサーバのプライベート IP アドレスと同じマシンが存在する場合、pingはいいとしても SSHのログイン試行履歴が残ってしまうかもしれない。これはとても恥ずかしいし、相手も不安に思うかもしれない。(通常は StrictHostKeyChecking yesなはずなので接続先のフィンガープリントが違えばそもそも SSHが教えてくれるのだがそれは置いておく)

そこで、厳密にホストを識別するためにサーバのフィンガープリントを照合するようにしてみる。

Matchブロックの結果が True になるものが複数ある場合は先の Matchが適用されるので自宅と外出先の両方を同時にチェックしてしまえばいいだろう。ちなみに例のフィンガープリントは github.com のもの。

HostrpiUser pi
    IdentityFile ~/.ssh/rpi_id_rsa

MatchHostrpi Exec "ssh-keyscan -T1 -trsa 192.168.1.100 | grep -sq '192.168.1.100 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='"HostName192.168.1.100MatchHostrpi Exec "ssh-keyscan -T1 -p 12345 -trsa example.com | grep -sq 'example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='"HostNameexample.comPort12345

正常な場合、フィンガープリント照会が三回ほど走ることになり無駄ではある。そう、Exec行にどこまで書けるのかやってみたかっただけである。

ちなみに Execは複数書いてもいいっぽい。この場合、左から順に Execが実行され、すべての終了ステータスが 0(True)であれば有効になる。途中で 0以外(False)になった場合はそこで Execは終了する。何のシェルを使っているかまでは調べていないがシェルのビルトインコマンドも認識している様子。

MatchExec date           Exec /usr/bin/false
    # 失敗MatchExec /usr/bin/false Exec date
    # 失敗MatchExec date           Exec /usr/bin/true
    # 成功MatchExec /usr/bin/true  Exec date
    # 成功

Viewing all articles
Browse latest Browse all 891

Trending Articles