Linuxサーバーを公開した翌朝、ログを見ると見知らぬIPアドレスからのSSHログイン試行が数百件——そんな光景に心当たりはないでしょうか。攻撃者はインターネット上を常にスキャンしており、22番ポートが開いているサーバーはすぐに標的にされます。
fail2banや鍵認証への切り替えは有効な対策です。しかし「そもそもSSHポートが外から見えない状態」を作れれば、攻撃の出発点すら与えずに済みます。この記事では、ポートノッキングという手法でSSHポートをポートスキャナーから隠す仕組みと、Linux(knockd)での具体的な実装手順を現場目線で解説します。

ポートノッキングとは?
ポートノッキングとは、あらかじめ決めた順序で複数のポートへの接続を試みることで、ファイアウォールルールを動的に変更する仕組みです。ドアをノックする動作に例えられており、正しい順序で「ノック」したIPアドレスのみがSSHポートに接続できるようになります。
通常、SSHポート(22番)はファイアウォールで閉じたままにしておきます。外部からは存在しないように見える状態です。正規ユーザーだけが知っている「ノックのシーケンス」を送信すると、ファイアウォールが一時的にそのIPアドレスだけに22番ポートを開放する、という流れです。
ポートノッキングの最大の利点は、Nmapなどのポートスキャナーにも22番ポートが検出されない点にあります。スキャンをかけても「closed」または「filtered」としか表示されないため、攻撃者はSSHが稼働していることに気づきません。
ネットワークセキュリティの観点では、「攻撃者に情報を与えない」こと自体がひとつの防御層です。多層防御の考え方と組み合わせることで、個々の対策の弱点を補い合えます。
攻撃者がポートスキャンで狙うもの
攻撃者がサーバーを発見した後、最初に行う作業がポートスキャンです。22番ポートが開いていればSSHが稼働していると判断し、次のような攻撃を仕掛けてきます。
・ブルートフォース攻撃: 大量のパスワードを自動で試し、正規アカウントへの侵入を試みる
・パスワードスプレー攻撃: よく使われるパスワードを多数のアカウントに対して横断的に試す
・バージョン指紋採取: SSHデーモンのバージョンを特定し、未パッチの既知脆弱性を悪用する
・クレデンシャルスタッフィング: 他サービスから流出したIDとパスワードの組み合わせをリスト攻撃する
これらの攻撃はいずれも、「ポートが開いている」ことが前提です。ポートノッキングによってSSHポートを隠すと、攻撃者はSSHの存在すら確認できないため、上記の攻撃フローがそもそも始まらなくなります。
ポートスキャンの仕組みと検知・防御の詳細については、ポートスキャンとは?攻撃者の事前調査手法と防御策を現場目線で解説も参照してください。
ポートノッキングの認証シーケンスの仕組み
ポートノッキングがどのように機能するか、処理の流れを順に説明します。
① 正規ユーザーがクライアント(自分のPC)から、決まった順序でサーバーの複数ポートへ接続を試みます(例: 7391番→8204番→9537番にTCP接続)。
② サーバー上で動作しているknockdデーモンがネットワークインターフェイスを常時モニタリングしており、この接続シーケンスを検知します。
③ 正しいシーケンスを受信すると、knockdがiptables(またはfirewalld / nftables)のルールを動的に変更し、その送信元IPアドレスからの22番ポートへのアクセスを許可します。
④ ユーザーはSSH接続を確立します。
⑤ 接続終了後、逆順のシーケンス(9537番→8204番→7391番)を送ることで22番ポートを再び閉じます。
knockdはパケットのペイロードを読むのではなく、接続先ポート番号の順序のみを判定基準とします。SYNパケットが届けばよいため、実際にTCPコネクションが確立しなくても動作します。また、 seq_timeout パラメータで「5秒以内にシーケンスを完了しなければ無効」という制限を設けられるため、タイミング推測の余地を大幅に狭めます。
LinuxへのSSHポートノッキング実装手順(knockd)
ここではDebian/Ubuntu系とRHEL/Rocky Linux系の両方で使える手順を紹介します。作業前に現在のSSHセッションを維持したまま進めてください。設定ミスで締め出された場合に備え、クラウドプロバイダーのコンソール接続(VPSの管理画面など)も事前に確認しておくと安心です。
1. knockdのインストール
各ディストリビューション向けのパッケージ名は以下のとおりです。
# Debian / Ubuntu sudo apt update && sudo apt install -y knockd # RHEL 8/9 / Rocky Linux / AlmaLinux(EPELリポジトリが必要) sudo dnf install -y epel-release sudo dnf install -y knock-server
2. knockd.confの設定
設定ファイル /etc/knockd.conf を編集します。ポート番号は例ですので、実際には1024以上の予測されにくい番号を自分で決めてください。3つのポートを使うのが一般的ですが、5つ以上にするとより推測されにくくなります。
[options] UseSyslog # モニタリングするインターフェイス名(ip aで確認して環境に合わせる) Interface = eth0 [openSSH] sequence = 7391,8204,9537 seq_timeout = 5 command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 9537,8204,7391 seq_timeout = 5 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn
%IP% は接続元のIPアドレスに自動的に置き換えられます。seq_timeout = 5 は5秒以内にシーケンスを完了しないと認証が無効になる設定です。この短いウィンドウが、偶発的なシーケンス一致をほぼ不可能にします。
3. ファイアウォールの初期ルール設定
knockdを有効にする前に、22番ポートへの新規接続をデフォルトでDROPするルールを追加します。以下はiptablesを使った手順です。firewalldやnftablesをお使いの場合も、22番ポートへのINBOUNDをDROPにした上でknockdを起動する流れは同じです。
# 既存の確立済みSSHセッションを維持(作業中のセッションが切れないように先に設定) sudo iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT # 22番ポートへの新規接続をDROP(これを設定してもknockd経由でのみ開放される) sudo iptables -A INPUT -p tcp --dport 22 -j DROP # knockdサービスを有効化・起動 sudo systemctl enable knockd sudo systemctl start knockd # iptablesルールを永続化(Debian/Ubuntu) sudo apt install -y iptables-persistent sudo netfilter-persistent save
設定後、別のターミナルからポートスキャンで22番を確認するとfilteredまたはclosedになっていることが確認できます。
4. クライアント側の操作(knock)
SSH接続前に、自分のPCから knock コマンドでシーケンスを送信します。
# クライアント(自分のPC)にknockをインストール # Debian / Ubuntu sudo apt install -y knockd # macOS(Homebrew) brew install knock # ノックシーケンスを送信してSSHポートを開く knock SERVER_IP_ADDRESS 7391 8204 9537 # knockの完了後、SSH接続 ssh -i ~/.ssh/id_ed25519 user@SERVER_IP_ADDRESS # 切断後にSSHポートを再度閉じる(closeSSHシーケンス) knock SERVER_IP_ADDRESS 9537 8204 7391
ノック→SSH接続の一連の操作は、シェルスクリプトにまとめると日常の運用コストを大幅に下げられます。
LinuxでのSSH鍵ペアの作成・設定については、姉妹サイトLinuxMaster.JPも参考になります。
中小企業でも今日からできること
「ポートノッキングはエンタープライズ向け」というイメージがあるかもしれませんが、情シスが1人でも管理するVPSやオンプレミスサーバーに十分実用的です。導入ステップを段階的に整理すると次のとおりです。
・ステップ1 — SSH鍵認証に切り替える: sshd_configでパスワード認証を無効化し、公開鍵認証のみを許可する。この段階でブルートフォースの大部分を防げる
・ステップ2 — fail2banを設定する: fail2banを導入し、認証失敗を繰り返すIPを自動ブロックする保険を用意する
・ステップ3 — ポートノッキングを追加する: knockdを導入し22番ポートを隠す。ノックシーケンスはチームでパスワードマネージャーに記録して共有する
・ステップ4 — 復旧経路を確保する: クラウドプロバイダーのコンソールや、帯域外管理(IPMI等)でロックアウト時の復旧経路を事前に確認する
これらを組み合わせることで、攻撃者にとってSSHが「存在しない」も同然の状態を作れます。完璧な対策は存在しませんが、攻撃者が「費用対効果が合わない」と判断してターゲットを変える効果は十分に期待できます。
よくある誤解と注意点
【注意】ポートノッキング単体は「完全な防御」ではない
ポートノッキングは「隠蔽によるセキュリティ(Security through Obscurity)」の側面を持ちます。シーケンスが第三者に知られた場合、または通信を傍受してシーケンスが解析された場合は防御が崩れます。したがって、SSH鍵認証・fail2ban・sshd_configの強化と組み合わせた多層防御として位置づけることが重要です。単体では使わないようにしてください。
【注意】fwknopによるSPA(シングルパケット認証)という上位互換
knockdよりさらに強固な手法として、fwknop(Firewall KNock OPerator)を使ったシングルパケット認証(SPA)があります。SPAでは暗号化された1つのパケットで認証を完了するため、通信の傍受やリプレイ攻撃への耐性が高くなります。セキュリティ要件が厳しい環境、たとえば金融系の自社サーバーや個人情報を多く扱うシステムでは、SPAの採用も選択肢に入れてください。
【注意】動的IPアドレス環境では設定を調整する
ISP(インターネットサービスプロバイダー)によって自分のPC側のIPが頻繁に変わる環境では、closeSSHシーケンスで都度ルールを削除するか、タイムアウト付きの自動削除ルール(例: -m conntrack や cron で定期的に古いルールを削除する)を組み合わせると管理が楽になります。

本記事のまとめ
ポートノッキングは、SSHポートをポートスキャナーから隠し、攻撃の入口すら与えない実践的な多層防御の一手です。
| 対策 | 防げる主な攻撃 | 難易度 |
|---|---|---|
| ポートノッキング(knockd) | ポートスキャン検出・ブルートフォースの大部分 | 低~中(設定30分程度) |
| SSH鍵認証 | パスワード推測攻撃 | 低 |
| fail2ban | 繰り返しの認証試行 | 低 |
| sshd_config強化 | デフォルト設定の悪用・バージョン指紋採取 | 低 |
まずはSSH鍵認証への切り替えとfail2banの設定を完了させてから、ポートノッキングを追加する順序で進めると、誤設定によるロックアウトリスクを最小化できます。「正しく知れば正しく備えられる」——このひとつひとつの積み重ねが、攻撃者にとって攻略困難なサーバーを作ります。
PR
SSH設定・ファイアウォール・ログ監視まで、Linuxサーバーの堅牢化手順をひとつひとつ丁寧に解説。ポートノッキング導入後の次のステップを体系的に学びたい方に最適な一冊です。
