ポートノッキングは、事前定義された一連のポートを「ノック」(つまり接続)することでネットワークポートを動的に開く方法です。これは、ポートノッキングシーケンスが実行されない限り、問題のポートが閉じられるため、開いているネットワークポートをポートスキャンから隠すのに特に役立ちます。十分な長さのポートノッキングシーケンスをブルートフォース攻撃することは事実上不可能です。たとえば、3つのTCPポートの組み合わせを(ブルートフォース攻撃で)正常に推測するには、攻撃者は281兆の可能な組み合わせのそれぞれをノックして、スキャンする必要があります。各ポートノッキングシーケンスの後にポートを開きます。ご想像のとおり、これには非常に長い時間がかかります。
このガイドは、Debian 10にノックされた柔軟なポートノッキングデーモンをインストールするのに役立ちます。デモンストレーションの目的で、SSHポートを隠すように構成しますが、他のポート/サービスはこのアプローチで保護できます。
- Debian10を実行しているサーバー。
- サーバーへのrootアクセス。
- $EDITOR環境変数を設定する必要があります。
- テスト用の2番目のシステム。
注:ポートノッキングを使用してSSHポートを隠す場合は、別のアクセス方法(たとえば、コンソール経由)があることを確認してください。これは、誤ってロックアウトした場合に役立ちます。
knockdをインストールする前に、次のコマンドを使用してシステムのパブリックネットワークインターフェイスの名前を確認してください。
ip link show | grep -v lo
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
インターフェイス名(この場合はens18)をメモします。後で必要になります。
ステップ1:Knockdのインストール
knockdは、接続をリッスンし、それに応じてポートを開くポートノッキングデーモンです。ポートノッキングを実装するために、nockedwithiptablesルールを使用します。次のように必要なパッケージをインストールします。
apt update apt install knockd iptables-persistent
ステップ2:ノックされた構成
Knockdは、単一の構成ファイル/etc/knockd.confを使用して、ノッキングシーケンスおよびその他のパラメーターを定義します。 2つの実用的な動作モードがあります。 1つ目は、事前定義されたポートを開閉するために1つのノッキングシーケンスを必要とし、もう1つは別々の開閉シーケンスを使用します。ユーザーの操作が少なくて済むため、前者を使用します。
まず、既存の構成ファイルをバックアップします。
mv /etc/knockd.conf /etc/knockd.conf.bak
次に、テキストエディタで構成ファイルを開きます。
$EDITOR /etc/knockd.conf
そして、以下に示す構成を入力します:
(ens18をネットワークインターフェイスの名前に置き換えます。)
[options] UseSyslog Interface = ens18 [SSH] sequence = 1000,2000,3000 seq_timeout = 15 tcpflags = syn start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 20
これにより、ノックは正しいノックシーケンス(この場合は1000、2000、3000)を受信した後にポート22へのトラフィックを有効にし、20秒の遅延後にトラフィックを再度無効にするように指示します。したがって、SSH接続はこの20秒間のみ受け入れられます。
次に、ファイル/ etc / default / knockdを編集してノックを有効にします:
$EDITOR /etc/default/knockd
そして、START_KNOCKDを1に設定します:
START_KNOCKD=1
ファイルを保存して終了します。また、ノック用にsystemdユニットを変更します。これを行うには、新しいユニットファイルを作成して、デフォルトを上書きします。
$EDITOR /etc/systemd/system/knockd.service
そして、以下を貼り付けます:
[Unit] Description=Port-Knock Daemon After=network.target Requires=network.target Documentation=man:knockd(1) [Service] EnvironmentFile=-/etc/default/knockd ExecStartPre=/usr/bin/sleep 1 ExecStart=/usr/sbin/knockd $KNOCKD_OPTS ExecReload=/bin/kill -HUP $MAINPID KillMode=mixed Restart=always SuccessExitStatus=0 2 15 ProtectSystem=full CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN [Install] WantedBy=multi-user.target
次に、次のコマンドを使用して、新しいユニットをロードして有効にします。
systemctl daemon-reload systemctl enable --now knockd.service
ステップ3:ファイアウォールルール
この時点で、Knockdの準備はできていますが、すべてのトラフィックはデフォルトでファイアウォールを介して有効になっています。ポート22/tcpへのアクセスを拒否するファイアウォールルールを作成します。
次のコマンドは、既存の接続が中断されないようにします。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ポート22/tcpへの接続をドロップするルールは次のとおりです。
iptables -A INPUT -p tcp --destination-port 22 -j DROP ip6tables -A INPUT -p tcp --destination-port 22 -j DROP
次に、現在のルールチェーンを保存して、再起動後も永続化できるようにします。
iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
ステップ4:テスト
別のシステムから、サーバーへの新しいSSHセッションを開始してみてください。接続できないはずです。ノッキングシーケンスを実行するには、さまざまなツールを使用できますが、Knockdに含まれているノッキングクライアントであるノックを使用してデモンストレーションを行います。手順1に示すように、ノックされたパッケージを別のシステムにインストールしてから、次のコマンドを実行します。
knock server_ip_address 1000 2000 3000 ssh [email protected]_ip_address
SSH接続が成功するはずです。
あるいは、Knockdは、ネットワークポートを開いたり閉じたりするために2つの異なるシーケンスを必要とするように構成できます。これは、ポートを長期間開いたままにしておきたい場合に便利です。この方法でKnockdを構成するには、構成ファイルを開きます。
$EDITOR /etc/knockd.conf
そして、既存の構成を次のように置き換えます。
[options] UseSyslog Interface = your_interface [openSSH] sequence = 1000,2000,3000 seq_timeout = 15 tcpflags = syn start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT [closeSSH] sequence = 3000,2000,1000 seq_timeout = 15 tcpflags = syn start_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
次に、サービスを再起動して新しい構成をロードします。
systemctl restart knockd.service
Knockdは、SSHやその他のサービスで非常に一般的なブルートフォース攻撃に対する効果的なソリューションになる可能性があります。 systemdが失敗するとKnockdを再起動しますが、ポートノッキングを使用してSSHポートを非表示にする場合は、サーバーにアクセスするためのバックアップ方法が常に必要です。