クライアントとサーバーアプリケーション間でリッスンモードになっている開いているポートを閉じたい。
Linuxにポートを閉じるための手動のコマンドラインオプションはありますか?
注: 私はことを知っているようになった「接続されたソケットを所有する唯一のアプリケーションは、アプリケーションが終了したときに起こるであろう、それを閉じる必要があります。」
なぜそれを開くアプリケーションによってのみ可能になるのか理解していません...しかし、私はまだ他の方法があるかどうかを知りたいと思っています。
クライアントとサーバーアプリケーション間でリッスンモードになっている開いているポートを閉じたい。
Linuxにポートを閉じるための手動のコマンドラインオプションはありますか?
注: 私はことを知っているようになった「接続されたソケットを所有する唯一のアプリケーションは、アプリケーションが終了したときに起こるであろう、それを閉じる必要があります。」
なぜそれを開くアプリケーションによってのみ可能になるのか理解していません...しかし、私はまだ他の方法があるかどうかを知りたいと思っています。
回答:
私は同じ問題を抱えていました。プロセスは生き続けなければなりませんが、ソケットは閉じなければなりません。実行中のプロセスでソケットを閉じることは不可能ではありませんが困難です。
プロセスを見つけます:
netstat -np
source/destination ip:port portstate pid/processname
地図を取得します
プロセスでソケットのファイル記述子を見つけます
lsof -np $pid
リストを取得します:プロセス名、pid、user、fileDescriptor、...接続文字列。
接続に一致するfileDescriptor番号を見つけます。「97u」のような「97」を意味します。
プロセスを接続します:
gdb -p $pid
ソケットを閉じます:
call close($fileDescriptor) //does not need ; at end.
例:
call close(97)
次に、gdbを切り離します。
quit
そして、ソケットは閉じられます。
sudo lsof -np $pid
私は約200行を与えて、私は望ましいFDを見つける方法について混乱しています。私の場合、プロセスは、クロームのタブであり、私は...開けWebSocketををクローズしようとしている
shutdown
:call shutdown($fileDescriptor, 0)
。
ここで間違った質問をしているようなものです。それをリッスンするソケットを開いたアプリケーションの外部から単純に「ポートを閉じる」ことは実際に不可能です。これを行う唯一の方法は、ポートを所有するプロセスを完全に終了することです。その後、約1〜2分で、ポートが再び使用可能になります。進行状況は次のとおりです(気にしない場合は、最後までスキップして、特定のポートを所有しているプロセスを強制終了する方法を示します)。
ポートは、OSによって異なるプロセスに割り当てられるリソースです。これは、OSにファイルポインターを要求することに似ています。ただし、ファイルポインターとは異なり、一度に1つのプロセスだけがポートを所有できます。BSDソケットインターフェイスを介して、プロセスはポートでリッスンする要求を行うことができ、OSはそれを許可します。OSは、他のプロセスが同じポートを取得しないようにします。いつでも、プロセスはソケットを閉じることでポートを解放できます。その後、OSはポートを再利用します。または、ポートを解放せずにプロセスが終了した場合、OSは最終的にポートを回収します(すぐには発生しませんが、数分かかります)。
さて、あなたがしたいこと(単にコマンドラインからポートを閉じる)は、2つの理由で不可能です。まず、可能であれば、1つのプロセスが別のプロセスのリソース(ポート)を単純に盗むことを意味します。特権プロセスに制限されない限り、これは悪いポリシーです。2番目の理由は、ポートを実行し続けた場合にポートを所有していたプロセスに何が起こるかが不明であるためです。プロセスのコードは、このリソースを所有していると想定して記述されています。単純にそれを取り除いた場合、それはそれ自体でクラッシュすることになります。したがって、特権プロセスであっても、OSはこれを許可しません。代わりに、単にそれらを殺す必要があります。
とにかく、特定のポートを所有するプロセスを強制終了する方法は次のとおりです。
sudo netstat -ap | grep :<port_number>
portを保持しているプロセスに対応する行が出力されます。例:
tcp 0 0 *:8000 *:* LISTEN 4683/procHoldingPort
この場合、procHoldingPortはポートを開いたプロセスの名前、4683はそのpid、8000(TCPであることに注意)は保持するポート番号です。
次に、最後の列を見ると、/が表示されます。次に、これを実行します:
kill <pid>
それが機能しない場合(netstatコマンドを再実行して確認できます)。これを行う:
kill -9 <pid>
一般に、可能であればSIGKILLを送信しないようにすることをお勧めします。これがkill
前に試すように言った理由ですkill -9
。使用kill
するだけで、より穏やかなSIGTERMが送信されます。
先ほど言ったように、これを行うとポートが再び開くまでに数分かかります。これを高速化する方法がわかりません。他の誰かがそうするなら、私はそれを聞きたいです。
unix.tools.port.close(<my port number>)
私が使うような賢明なものを投稿するまでinit 6
。
フューザーも使用できます
fuser -k -n *protocol portno*
ここで、プロトコルはtcp / udpであり、portnoは閉じたい番号です。例えば
fuser -k -n tcp 37
fuser
実行された後、強制終了されたプロセスを再起動する「ガーディアン」プロセスがあるかもしれません。
fuser
ため、ポートを使用してプロセスを見つけて強制終了しますが、ソケットが閉じられていないという事実は解決しません。60秒で、カーネルがそれを行います。
おそらく、ポートが関連付けられているソケットを開いたプロセスを見つけて、そのプロセスを強制終了できます。
ただし、そのプロセスが使用していたすべての要素(ファイル、ソケット、フォーク、終了時に適切に閉じられない限り残る可能性のあるものを開く)を初期化解除するハンドラーを持たない限り、それを作成することに気づかなければなりませんシステムのパフォーマンスを引き下げます。さらに、プロセスが強制終了されたことをカーネルが認識するまで、ソケットは開いたままになります。通常、これには約1分かかります。
より良い質問は、どのポート(どのプロセスに属しているか)を停止することです。
発見したバックドアまたはウイルスに終止符を打とうとしている場合は、終了する前に少なくともどのデータが行き来しているかを知る必要があります。(wiresharkはこれに適しています)(プロセスの実行可能ファイル名であるため、削除して再起動時に戻ってくるのを防ぐことができます)または、インストールしたもの(HTTPDやFTPDなど)の場合は、既にアクセスできるはずですプロセス自体。
通常、制御プログラム(HTTPD stop | startなど)があります。または、それがシステムに関するものである場合、おそらくそれを台無しにすべきではありません。とにかく、他の皆があなたに「ハウツー」の角度を与えているので、私はあなたに警告を与えるべきだと思いました。
iptablesを変更して再起動するスクリプトを作成できます。ポート上のすべてのパケットをドロップするルールを追加するための1つのスクリプト、前述のルールを削除するための別のスクリプト。
他の回答は、ポートにバインドされたプロセスを強制終了する方法を示しています-これはあなたが望むものではないかもしれません。サーバーを実行し続けたいが、クライアントからの接続を防止する場合は、プロセスを停止せずにポートをブロックします。
killcxという名前のコマンドを使用して、強制終了するプロセスなしで接続を閉じることができます。
killcx [dest_ip:dest_port] {interface} dest_ip : remote IP dest_port : remote port interface (optional) : network interface (eth0, lo etc).
killcx 120.121.122.123:1234 killcx 120.121.122.123:1234 eth0
この答えは厳密に言えば質問自体に答えるものではないことを知っていますが、これを読むと関連情報になるかもしれません:
ソケットをポート(およびアドレス)にバインドするデフォルトの動作では、プロセスの突然の終了によってソケットが閉じられると、ソケットはしばらくTIME_WAITのままになります。これは、このアドレス/ポートにすぐに再バインドできないことを意味します。標準のBSDソケットインターフェイスを介してシステム自体を開発している場合は、SO_REUSEADDRソケットオプションを使用して(少なくともある程度まで)この動作を制御できます。これにより、ソケットがTIME_WAITステータスの場合、基本的に同じアドレス/ポートに再度バインドできます。ただし、ポートごとにまだ1つのソケット!
ただし、TIME_WAITがそもそも存在する理由があるため、この情報は開発支援としてのみ使用する必要があります。他の回答で既に説明しています。
ssを使用してリスニングソケットを閉じることができます。
sudo ss --kill state listening src :1234
ここで、1234はポート番号です。
ssはiproute2パッケージの一部であるため、最新のLinuxに既にインストールされている強力な変更があります。
関連する質問への答えからこれについて学びました。