用途
私は自宅から、趣味の用途で使っている VPS にアクセスできるようにしています。
IP が固定できない状況でも、ある程度のセキュリティを担保できるように、ポートノッキングを設定しています。
ノッキングを行わないとそもそも SSH のポートにアクセスできないように設定しています。
状況
実際にノックするとき、 knock を使っているのですが、
3 個以上のポートをノックする手順を設定した時に、なぜだか上手く動作しないということがありました。
結局、根本の原因はわからなかったのですが、現象そのものはオプションの指定で解決したので備忘録として書き留めておきます。
OS は OS X 10.11.3 (15D21) で、 knock は knock 0.7 です。 Homebrew を使ってインストールしました。
テスト
問題を切り分けるために SSH の代わりに Netcat にし、何度か実験しました。
(仮に SSH のポートを 10022 、ノックする手順を 10023, 10024, 10025 とします。)
テストしたコマンド
$ knock 10023 10024 10025
$ nc -v -z my.example.com 10022
(同時に別の端末で tcpdump を grep 付きで起動しておく)
こんな感じで出れば成功
Connection to my.example.com port 10022 [tcp/*] succeeded!
このようにコマンドを叩くと、だいたい 2, 3 回チャレンジして成功する、という感じでした。
少し間を置いて実行すると 1 回で成功することもありますし、 8 回連続でタイムアウトして失敗したこともありました。
対処方法
delay のオプションとして -d1 を指定します。
1 ミリ秒待つ、ということです。
$ knock -d1 10023 10024 10025
たった 1 ミリ秒待っただけで、この問題は発生しなくなりました。
(推測: このオプションがないと、順番通りでなく SYN を送ってしまう、または到達してしまうということ? )
どこかのポートスキャンを防ぐような Firewall に引っかかっているのであれば、閾値が 1 ミリ秒のような小さい時間に設定するメリットは薄いと思うので、まだ自分の中では納得がいってません。
また、 tcpdump を見る限りでも、 -d1 がある場合とない場合で動作に違いはなさそうでした。
余談
ssh_config に次のように設定しておくと、 ssh のコマンド実行時に knock も実行するので、非常に楽です。
ProxyCommand bash -c 'knock -d1 %h [ノックするポート] ; nc %h %p'