Home
Packages
Forums
Wiki
GitLab
Security
AUR
Download
コンテンツにスキップ
メインメニュー
メインメニュー
サイドバーに移動
非表示
案内
メインページ
目次
コミュニティに貢献
最近の出来事
おまかせ表示
特別ページ
交流
ヘルプ
貢献
最近の更新
最近の議論
新しいページ
統計
リクエスト
ArchWiki
検索
検索
表示
アカウント作成
ログイン
個人用ツール
アカウント作成
ログイン
ポートノッキングのソースを表示
ページ
議論
日本語
閲覧
ソースを閲覧
履歴を表示
ツール
ツール
サイドバーに移動
非表示
操作
閲覧
ソースを閲覧
履歴を表示
全般
リンク元
関連ページの更新状況
ページ情報
表示
サイドバーに移動
非表示
←
ポートノッキング
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループに属する利用者のみが実行できます:
登録利用者
。
このページのソースの閲覧やコピーができます。
[[Category:ファイアウォール]] [[en:Port knocking]] [[es:Port Knocking]] ポートノッキングとはデフォルトではファイアウォールによって閉じられているポートを外部から密かに開く方法です。ポートノッキングでは予め決めておいた順番で閉じているポートを叩きます。正しい順番のポートの"ノック" (接続試行) を受け取ったとき、ファイアウォールは特定のポートを開いて接続を許可します。 標準的なポートスキャンに対して、ポートのサービスが使われていないかのようにみせかけることができるという利点があります。この記事ではデーモンや iptables を使ってポートノッキングを利用する方法を説明します。 {{Warning|ポートノッキングはあくまでセキュリティ戦略の一環として考えてください。ポートノッキングだけでシステムを防護することは不可能です。[[Wikipedia:Security through obscurity|遮蔽によるセキュリティ]] (攻撃者が知らないことを前提とするセキュリティ) は脆いものです。SSH を保護する場合、ポートノッキングと組み合わせて使うことができる強固な方法として [[SSH 鍵]]があります。また、上記の例で使われているポートは実際には使わないでください。}} == イントロダクション == 以下に進む前に {{Pkg|iptables}} をインストール・設定する必要があります。iptables については [[iptables]] を読んでください。 iptables の '''recent''' モジュールを使うことで (成功あるいは失敗した) ポート接続に基づく IP アドレスのリストを動的に作成することができます。'''recent''' を利用して、特定の IP アドレスから正しいポートがノックされたかどうかをファイアウォールに判断させ、正解なら、特定のポートを開きます。 ポートノッキングをするセッションは以下のようになります: {{bc|<nowiki> $ ssh username@hostname # No response (Ctrl+c to exit) ^C $ nmap -Pn --host_timeout 201 --max-retries 0 -p 1111 host #knocking port 1111 $ nmap -Pn --host_timeout 201 --max-retries 0 -p 2222 host #knocking port 2222 $ ssh user@host # Now logins are allowed user@host's password: </nowiki>}} {{Note|iptables ではポートノッキングを一つのルールで設定できるコマンドが開発されています。多数の高度なオプションも用意されていますが、標準カーネルではまだ利用できません (2013年8月現在)。興味がある場合、次を参照: {{AUR|xtables-addons}}。}} ノックに使用するポートはランダムに選択するのが良いでしょう。[https://www.random.org/ random.org] で 1 から 65535 の間のポート番号を生成できます。一般的に使われているポートは選択しないように注意してください。[https://www.grc.com/PortDataHelp.htm ポートデータベース] や {{Ic|/etc/services}} ファイルを参照してください。 == デーモンヘルパーによるポートノッキング == 専用のデーモンを使うことでポートノッキングを管理できます。ヘルパープログラムを使えばルールを簡単に設定できる他、高度な機能も存在します。 {{Pkg|knockd}} はネットワークにセキュリティレイヤーを追加する [http://www.portknocking.org/ ポートノッキング] デーモンです。knockd の [http://www.zeroflux.org/cgi-bin/cvstrac.cgi/knock/wiki wiki] にはポートノッキングの設定例が3つ載っています。設定例を多少改変することで iptables ファイアウォールに簡単に統合できます。[[シンプルなステートフルファイアウォール]]に従って iptables を設定した場合、{{Ic|INPUT}} チェインの設定をファイアウォールで使用する {{Ic|open}} チェインに置き換えてください。 例: {{bc|<nowiki> [options] logfile = /var/log/knockd.log [opencloseSSH] sequence = 8881:tcp,7777:tcp,9991:tcp seq_timeout = 15 tcpflags = syn,ack start_command = /usr/bin/iptables -A TCP -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 10 stop_command = /usr/bin/iptables -D TCP -s %IP% -p tcp --dport 22 -j ACCEPT </nowiki>}} == iptables によるポートノッキング == 以下では {{ic|/etc/iptables/iptables.rules}} ファイルを作成して SSH のポートノッキングを処理します。{{ic|8881}}, {{ic|7777}}, {{ic|9991}} ポートが順番に"ノック"されたときに SSH の標準ポートである 22 を開くようにルールを設定します。 まずサンプルスクリプトの filter ポリシーとチェインを定義します。サンプルにある OUTPUT ACCEPT は必須で、これがないと SSH ポートが開いてもトラフィックが拒否されるため接続できません。最後の3つのチェインは後のルールでポートノッキングをするのに必要です。 {{hc|# Filter definition| *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :TRAFFIC - [0:0] :SSH-INPUT - [0:0] :SSH-INPUTTWO - [0:0] }} 次にメインのチェインである {{ic|TRAFFIC}} のルールを追加します。ポートノッキングでは適切なポートに順番で接続リクエストを送信します。ネットワークトラフィックを制御して SSH などの接続を確立するために ICMP が必要です。 {{hc|# INPUT definition| -A INPUT -j TRAFFIC -A TRAFFIC -m state --state ESTABLISHED,RELATED -j ACCEPT -A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 22 -m recent --rcheck --seconds 30 --name SSH2 -j ACCEPT }} 最後のルールは、接続してきた IP が {{ic|SSH2}} のリストに載っている場合に、ポート22を30秒間開きます。最初に条件が確認されるチェインの一番上に持ってくることで、まず接続試行のリストを作成して、後にポートノッキングの判別に使います。上記の例では、30秒後にポートは閉じられますが、他には何も行われません。したがって、同じ IP から再度ポートノッキングを行うことができます。 最後のルールがトラフィックを承認しなかった場合 (例: 30秒間接続がなかった場合) でもリストの IP が {{ic|SSH2}} に接続できるように、リストから IP を削除して最初からノックするようにします。シーケンスを適切に処理するために、リストを確認したら直後に削除するのが重要です。 -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH2 --remove -j DROP 最初に処理したシーケンスの末端にきて、以下のルールでポートシーケンスの確認を行います。一つずつノックするポートが正しいかどうか確認するルールを作成します。シーケンスが問題なければ、IP をリストに追加して次のノックにジャンプします。{{ic|SSH-INPUT}} や {{ic|SSH-INPUTTWO}} にジャンプされなかった場合、間違ったポートがノックされた、あるいは (こちらの方が多いですが) 他のトラフィックだということです。したがって、次のルールで {{ic|SSH2}} のルールと同じように、リストから IP を削除してトラフィックを拒否します。 {{bc|-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 9991 -m recent --rcheck --name SSH1 -j SSH-INPUTTWO -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH1 --remove -j DROP}} 次のポートのノックも同じように設定します。同じリストに対応するルールが組み合っていて正しい順番であれば、{{ic|TRAFFIC}} チェインのシーケンスの順番は自由にできます。 {{bc|-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 7777 -m recent --rcheck --name SSH0 -j SSH-INPUT -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH0 --remove -j DROP}} ルールの最後のブロックでは、接続試行した IP を各自の ''recent'' リストに設定して、IP がノッキングシーケンスの次のステップに行けるように許可します。 まずはシーケンスの最初のノックのルールで、新しい接続試行がポートノッキングの開始かもしれないのでメインチェインの {{ic|TRAFFIC}} の一部としてチェックします。正解 (正しいポート) ならノックを最初のリスト {{ic|SSH0}} にセットします。ルールの最後のブロックで {{ic|SSH0}} を確認して、2番目のノック (7777) を確認するルールでは1番目のポートの recent ノックが必要とし、問題ない場合に次の recent リスト ({{ic|SSH1}}) をセットします。これによってリストがシーケンス処理されます。 {{bc|-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 8881 -m recent --name SSH0 --set -j DROP -A SSH-INPUT -m recent --name SSH1 --set -j DROP -A SSH-INPUTTWO -m recent --name SSH2 --set -j DROP -A TRAFFIC -j DROP COMMIT}} 正しいポートがノックされた場合でも、トラフィックは最後のルールでドロップしていることに注意してください。この DROP は接続試行が実はノックであることを他人に悟られないように隠すために設定しています。 ルールの設定が完了したら、新しく設定したルールを使って {{ic|iptables.service}} を起動します: {{bc|# systemctl daemon-reload # systemctl restart iptables}} 上記のコマンドを全て実行した後の {{ic|iptables.rules}} ファイルは以下のようになります: {{bc| *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :TRAFFIC - [0:0] :SSH-INPUT - [0:0] :SSH-INPUTTWO - [0:0] # TRAFFIC chain for Port Knocking. The correct port sequence in this example is 8881 -> 7777 -> 9991; any other sequence will drop the traffic -A INPUT -j TRAFFIC -A TRAFFIC -p icmp --icmp-type any -j ACCEPT -A TRAFFIC -m state --state ESTABLISHED,RELATED -j ACCEPT -A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 22 -m recent --rcheck --seconds 30 --name SSH2 -j ACCEPT -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH2 --remove -j DROP -A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 9991 -m recent --rcheck --name SSH1 -j SSH-INPUTTWO -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH1 --remove -j DROP -A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 7777 -m recent --rcheck --name SSH0 -j SSH-INPUT -A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH0 --remove -j DROP -A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 8881 -m recent --name SSH0 --set -j DROP -A SSH-INPUT -m recent --name SSH1 --set -j DROP -A SSH-INPUTTWO -m recent --name SSH2 --set -j DROP -A TRAFFIC -j DROP COMMIT # END or further rules }} == ポートノッキングスクリプト == 設定が完了したら、ポートノッキングを行うツールが必要です。上記で触れている {{Pkg|knockd}} には簡単に設定できる {{ic|knock}} ツールが付属しています。上流のサイトでは他の OS 用の {{ic|knock}} ツールが配布されています。 ここでは {{Pkg|nmap}} を使います。シンプルなシェルスクリプト ({{ic|knock.sh}}) でポートノッキングを自動化します: {{hc|knock.sh|2= #!/bin/bash HOST=$1 shift for ARG in "$@" do nmap -Pn --host_timeout 100 --max-retries 0 -p $ARG $HOST done }} 以下では上記のスクリプトを使います。他の影響を考慮して、テストはローカルホストで行います。 まず、ネットワークケーブルを接続してから、SSHD が listen する IP を設定します: [user@host ~]# ip link set up dev enp8s0 [user@host ~]# ip address add 192.168.1.1/24 dev enp8s0 [user@host ~]# ip route add default via 192.168.1.1 [user@host ~]# systemctl status sshd |grep listening Aug 21 14:36:53 host sshd[3572]: Server listening on 192.168.1.1 port 22 次に、SSHD が接続を承認するかどうか確認、そしてスクリプトを実行した後に SSH ログインに成功することを確認します: {{bc|<nowiki> $ ssh user@host # No response (Ctrl+c to exit) ^C $ sh knock.sh host 8881 7777 9991 $ history -r $ ssh user@host # Now logins are allowed user@host's password: Last login: Tue Aug 20 23:00:27 2013 from host</nowiki>}} 最初の接続試行は、接続が DROP されて何も応答しないため停止するはずです。最後のルールの DROP を REJECT に変更しておけば、代わりに {{ic|$ connection refused}} が返ってきます。最後に、ログインが成功したら、カーネルの ''recent'' リストでノックが成功していることを確認します: {{bc|<nowiki>[user@host ~]$ cat /proc/net/xt_recent/SSH* src=192.168.1.1 ttl: 64 last_seen: 296851 oldest_pkt: 1 296851 src=192.168.1.1 ttl: 64 last_seen: 297173 oldest_pkt: 1 297173 src=192.168.1.1 ttl: 64 last_seen: 297496 oldest_pkt: 1 297496 [user@host ~]$ exit logout Connection to 192.168.1.1 closed.</nowiki>}} {{Warning|上記の設定によるセキュリティを保証することはできません。あくまで特定のポートのサービスの存在を遮蔽できるというだけです。他の方法でもセキュリティを守るようにしてください。上記の設定を使うときは、自己責任で行なってください。}} == 参照 == * [http://www.portknocking.org/ Port knocking ホームページ] * [http://en.wikipedia.org/wiki/Port_knocking Wikipedia on Port knocking]
このページで使用されているテンプレート:
テンプレート:AUR
(
ソースを閲覧
)
テンプレート:Bc
(
ソースを閲覧
)
テンプレート:Hc
(
ソースを閲覧
)
テンプレート:Ic
(
ソースを閲覧
)
テンプレート:Note
(
ソースを閲覧
)
テンプレート:Pkg
(
ソースを閲覧
)
テンプレート:Warning
(
ソースを閲覧
)
ポートノッキング
に戻る。
検索
検索
ポートノッキングのソースを表示
話題を追加