2026年8月7日

2026年8月7日

SSHのポートノッキング設定方法(knockdで22番を普段は閉じておく)

ポートノッキングは、SSH のポートを普段はファイアウォールで閉じておき、決められた順番で別のポートに接続を試みた送信元 IP にだけ一時的に開ける仕組みです。この記事では、Debian/Ubuntu 系のサーバーに knockd を入れて設定し、クライアントからノックして接続するまでの手順と、締め出されないための準備、仕組みの限界までを説明します。読み終えると、自分のサーバーで試験的にポートノッキングを動かし、本番に入れるかどうかを判断できるようになります。

ポートノッキングで何が変わるか

SSH を 22 番で公開していると、インターネット上の自動スキャンから絶えずログイン試行が届きます。公開鍵認証にしてパスワード認証を無効にしていれば突破される可能性は低いものの、ログが埋まり、将来 OpenSSH に脆弱性が見つかったときに直接狙われる位置にあることは変わりません。

ポートノッキングを入れると、22 番は通常時「閉じている」ように見えます。正しい順番でノックした IP だけが数秒〜数十秒の間 22 番に接続でき、接続が確立したあとは通常の SSH と同じように使えます。

ただし、これは認証の代わりではありません。ノックの順番は通信を盗聴されれば分かりますし、同じ NAT の内側にいる別の人にも開いてしまいます。公開鍵認証・root ログイン禁止などの基本対策をしたうえで、さらに露出を減らすための追加の層と考えてください。

作業前に締め出し対策を用意する

ファイアウォールを触る作業では、設定ミスで自分が SSH に入れなくなる事故が起きやすくなります。始める前に次の3つを確認してください。

  • SSH 以外の入り口:VPS やクラウドの管理画面にあるコンソール機能(シリアルコンソール・Web コンソールなど)から、ログインできることを事前に試しておきます。
  • 今の SSH セッションを閉じない:設定中は既存のセッションを開いたままにし、確認は別のターミナルから新しく接続して行います。
  • 時間がたつと元に戻る仕掛け:心配なら、作業前に「10分後にファイアウォール設定を元に戻す」ジョブを at などで予約しておき、うまくいったら取り消す方法もあります。

また、クラウドのセキュリティグループや VPS 事業者側のパケットフィルターを使っている場合、ノックに使うポートがそこで遮断されているとサーバーまで届きません。外側のフィルターと OS のファイアウォールの両方を確認します。

knockd をインストールする

Debian/Ubuntu ではパッケージで入ります。

sudo apt update
sudo apt install knockd

このパッケージにはサーバー側の knockd と、クライアント用の knock コマンドの両方が含まれます。RHEL 系では標準リポジトリに無い場合があり、EPEL などの追加リポジトリやソースからのビルドになります。

Debian 系の古いパッケージでは /etc/default/knockd に START_KNOCKD=0 があり、1 にしないと起動しないものがありました。監視するネットワークインターフェースもここの KNOCKD_OPTS="-i eth0" か、設定ファイルの Interface で指定します。インターフェース名は ip -br addr で確認してください(クラウドでは ens3 や enp1s0 など eth0 以外の名前が多くあります)。

ファイアウォールの前提を作る

knockd は「ノックを検知してコマンドを実行する」だけで、ポートを閉じる役目はファイアウォールが担います。前提として、次の状態にしておきます。

  1. 確立済みの通信(ESTABLISHED,RELATED)は許可する
  2. 22 番への新規接続は許可しない(最後に DROP される)

iptables で書くと次のような形です。既存のルールがある場合は、そのまま流すのではなく sudo iptables -S で現状を確認してから組み込んでください。

# 確立済みの通信を許可(ノック後に開いた接続を、閉じたあとも維持するために必要)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT

# 22番への新規接続は落とす(ノックで開ける許可ルールはこれより前に挿入される)
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

1 行目が抜けていると、ノック後に接続できても、一定時間後に許可ルールが消えた時点でセッションが切れます。ルールを永続化する方法は環境によって異なり、iptables-persistent や nftables の設定ファイルなどを使います。

knockd.conf を書く

設定は /etc/knockd.conf です。開ける・閉じるを別々のノックにする書き方もありますが、閉じ忘れを防ぐため「開けてから一定時間後に自動で閉じる」書き方をおすすめします。

[options]
    UseSyslog
    Interface = eth0

[openSSH]
    sequence      = 7421:tcp,9183:udp,5367:tcp
    seq_timeout   = 10
    tcpflags      = syn
    start_command = /usr/sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    cmd_timeout   = 30
    stop_command  = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

各項目の意味は次のとおりです。

  • sequence:ノックするポートと順番です。上の例はあくまで例なので、そのまま使わず自分で決めてください。7000,8000,9000 のような連番や、よく使われるポート(80、443 など)は避けます。TCP と UDP を混ぜると推測されにくくなります。
  • seq_timeout:最初のノックから最後のノックまでに許す秒数です。
  • tcpflags = syn:TCP の接続開始パケットだけをノックとして数えます。
  • start_command / stop_command:%IP% にノックした送信元 IP が入ります。-A(末尾に追加)ではなく -I(先頭に挿入)にしているのは、前の手順で作った DROP より前に許可ルールを置くためです。
  • cmd_timeout:start_command の実行から stop_command までの秒数です。この間に SSH 接続を始めれば、ESTABLISHED の許可によって接続はその後も続きます。

iptables のパスは command -v iptables で確認してください。UFW を使っている環境なら、ufw insert 1 allow from %IP% to any port 22 proto tcp と ufw delete allow from %IP% to any port 22 proto tcp の組み合わせにする方法もあります。

設定したら起動して、自動起動を有効にします。

sudo systemctl enable --now knockd
sudo systemctl status knockd

クライアントからノックして接続する

手元の PC にも knockd パッケージ(または knock コマンド)を入れ、ノックしてから SSH します。

knock -v server.example.com 7421:tcp 9183:udp 5367:tcp
ssh user@server.example.com

毎回打つのが面倒なら、シェルの関数やエイリアスにまとめておくと便利です。Windows では WSL の knock を使うか、Test-NetConnection などで順番に接続を試す方法もありますが、UDP を含める場合は専用のクライアントのほうが扱いやすくなります。

動作を確認する

サーバー側でログを見ながら、別の端末からノックします。

sudo journalctl -u knockd -f
# UseSyslog の場合は /var/log/syslog などにも出ます

正しくノックできると、送信元 IP と段階(Stage)、セッションを開いたこと、実行したコマンドがログに出ます(表記はバージョンにより異なります)。あわせて sudo iptables -S INPUT で許可ルールが一時的に追加され、cmd_timeout 後に消えることを確認します。

うまくいかないときは、よくある原因から順に確認します。

  1. ノックがサーバーに届いていない:クラウド側のフィルターでノック用ポートが遮断されている、または Interface の指定が違う。ログに何も出ないならここを疑います。
  2. 順番や時間切れ:ログに途中の Stage しか出ない場合、seq_timeout が短すぎるか、クライアントの指定がずれています。
  3. ルールの位置が悪い:許可ルールが DROP より後ろに入っている。-I を使っているか確認します。
  4. 接続後すぐ切れる:ESTABLISHED,RELATED の許可が無い状態です。

ポートノッキングの限界と代替案

ポートノッキングには構造上の弱点があります。ノックは平文のポート番号の並びなので、通信経路を観測できる相手には再送(リプレイ)されえます。また、会社や携帯回線などの共有 IP からノックすると、同じ IP を使う他人にも短時間開きます。IPv6 で接続する環境では、使うツールのバージョンとファイアウォールの設定が IPv6 に対応しているかも別途確認が必要です(2026年10月現在、ディストリビューションのパッケージによって状況が異なります)。

より強い仕組みとしては次のものがあります。

  • fwknop(Single Packet Authorization):暗号化と HMAC で認証した1つのパケットでポートを開ける方式で、単純なノックよりリプレイに強くなっています。
  • VPN 経由に限定する:WireGuard などで管理用ネットワークを作り、SSH はその内側からだけ受け付けます。
  • 接続元 IP の制限:固定 IP から管理しているなら、ファイアウォールでその IP だけを許可するのが最も単純です。

どの方法を選んでも、公開鍵認証、パスワード認証の無効化、fail2ban などによる試行のブロックといった基本の対策はそのまま残しておきます。

まとめ

  • ポートノッキングは、決めた順番でノックした IP にだけ SSH を一時的に開ける仕組みで、knockd で実装できます。
  • 作業前に管理画面のコンソールで入れることを確かめ、既存セッションを開いたまま別端末で確認します。
  • ファイアウォールは「ESTABLISHED を許可、22 番の新規は DROP」を前提にし、許可ルールは -I で先頭に入れ、cmd_timeout で自動的に閉じます。
  • ノックは盗聴やリプレイに弱いため認証の代わりにはなりません。強度が必要なら fwknop や VPN、接続元 IP の制限を検討します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲