クライアントアプリケーションとサーバーアプリケーションの間でリスニングモードになっている開いているポートを閉じます。
Linuxでポートを閉じるための手動のコマンドラインオプションはありますか?
注:私は「接続されたソケットを所有するアプリケーションだけがそれを閉じるべきであることを知りました。アプリケーションは終了します。 "
なぜそれがそれを開くアプリケーションによってしか可能ではないか私は理解していません...しかし私はまだそれをするために他の方法があるかどうか知りたがっています。
私は同じ問題を抱えていました、プロセスは生き続けなければなりませんが、ソケットは閉じなければなりません。実行中のプロセスでソケットを閉じることは不可能ではありませんが難しいです。
プロセスを見つけます。
netstat -np
source/destination ip:port portstate pid/processname
マップを入手
プロセス内でソケットのファイル記述子を見つけます。
lsof -np $pid
リストを取得します:プロセス名、pid、ユーザー、fileDescriptor、...接続文字列。
接続に一致するfileDescriptor番号を見つけます。
次にプロセスを接続します。
gdb -p $pid
今ソケットを閉じます。
call close($fileDescritor)
//does not need ; at end.
それからデタッチ:
quit
そしてソケットは閉じています。
あなたはここで間違った質問をするようなものです。それを待機しているソケットを開いたアプリケーションの外部から単純に「ポートを閉じる」ことは実際には不可能です。これを行う唯一の方法は、ポートを所有しているプロセスを完全に強制終了することです。その後、約1、2分で、ポートは再び使用可能になります。これが現在進行中のものです(気にしないのであれば、特定のポートを所有しているプロセスを強制終了する方法を示す最後までスキップしてください)。
ポートは、OSによってさまざまなプロセスに割り当てられたリソースです。これは、ファイルポインタをOSに要求するのと似ています。ただし、ファイルポインタとは異なり、一度に1つのプロセスしかポートを所有できません。 BSDソケットインタフェースを介して、プロセスはポート上で待機するように要求することができます。その後、OSはそれを許可します。 OSは他のプロセスが同じポートを取得しないようにもします。どの時点でも、プロセスはソケットを閉じることによってポートを解放できます。その後OSはポートを再利用します。あるいは、ポートを解放せずにプロセスが終了した場合、OSは最終的にポートを再利用します(ただし、すぐには実行されません。数分かかります)。
さて、あなたがしたいこと(単にコマンドラインからポートを閉じる)は、2つの理由で不可能です。まず、可能であれば、あるプロセスが別のプロセスのリソース(ポート)を単に盗むことができるということです。特権プロセスに限定しない限り、これは悪い方針です。 2つ目の理由は、ポートを実行したままにした場合にそのポートを所有していたプロセスに何が起こるのかが不明であることです。プロセスのコードは、それがこのリソースを所有していると仮定して書かれています。単にそれを取り除けば、それはそれ自身でクラッシュすることになるでしょう、それであなたが特権的なプロセスであっても、OSはあなたにこれをさせません。代わりに、あなたはそれらを単に殺さなければなりません。
とにかく、これは特定のportを所有しているプロセスをkillする方法です:
Sudo netstat -ap | grep :<port_number>
これにより、プロセス保持ポートに対応する行が出力されます。次に例を示します。
tcp 0 0 *:8000 *:* LISTEN 4683/procHoldingPort
この場合、procHoldingPortはポートを開いたプロセスの名前です4683がpid、8000(TCPであることに注意)は、それが保持するポート番号です。
それから、最後の列を見てください、あなたは/を見るでしょう。それからこれを実行してください:
kill <pid>
それでもうまくいかない場合(netstatコマンドを再実行して確認できます)。これを行う:
kill -9 <pid>
一般的には、可能であればSIGKILLを送信しないようにします。これがkill -9
の前にkill
を試すようにあなたに言う理由です。 kill
を使うだけで穏やかなSIGTERMが送られます。
私が言ったように、これをしてもポートが再び開くのに数分かかるでしょう。これをスピードアップする方法がわかりません。他の誰かがそうしているなら、私はそれを聞きたいです。
フューザーも使用できます
fuser -k -n *protocol portno*
ここでprotocolはtcp/udpで、portnoは閉じたい番号です。例えば。
fuser -k -n tcp 37
fuserのmanページ で詳細情報
代わりにiptablesを使うこともできます。
iptables -I INPUT -p tcp --dport 80 -j DROP
それは基本的にあなたが望むものを達成します。これにより、すべてのTCPトラフィックがポート80にドロップされます。
netstat -anp | grep 80
Apacheを実行している場合は、 "httpd"と表示されます(これは単なる例です。アプリケーションで使用されているポートの代わりに80を使用してください)。
pkill -9 httpd
または
killall -9 httpd
ポートが関連付けられているソケットがどのプロセスによって開かれているのかを調べて、そのプロセスを強制終了することもできます。
しかし、そのプロセスがそれが使用していたすべてのもの(オープンファイル、ソケット、フォーク、終了時に適切に閉じられていない限り残る可能性があるもの)を初期化解除するハンドラを持っていなければシステムパフォーマンスを低下させます。さらに、ソケットは、プロセスが強制終了されたことをカーネルが認識するまで開いたままになります。それは通常ちょうど約1分かかります。
私はもっと良い質問があると思います:どのポート(どのプロセスに属している)を止めたいですか?
あなたが見つけたバックドアやウイルスに終止符を打とうとしているのなら、あなたはそれを終了する前に少なくともどのデータが行ったり来たりしているかを学ぶべきです。 (wiresharkがこれに適しています)(そしてプロセスの実行ファイル名なので削除して再起動時に戻ってこないようにすることもできます)または、インストールしたもの(HTTPDやFTPDなど)の場合はプロセス自体.
通常は制御プログラム(HTTPD stop | startまたは何か)を持ちます。あるいは、それがシステムのものであれば、おそらくそれを台無しにしてはいけません。とにかく、私は他のみんながあなたに「ハウツー」の角度を与えているので、私はあなたに警告を与えるべきだと思いました。
最初にmongoとnodeのプロセスを探し、それから以下のことをしました。
ps -A | grep node
10418 pts/23 00:00:05 node
10551 pts/23 00:00:00 node
ps -A | grep mongo
10490 pts/23 00:00:00 mongod
確認したら、killコマンドでプロセスを強制終了します。
kill -9 10418
kill -9 10490
最後にmeteor
と入力すれば、再び動くはずです。
より早くポートを解放したい場合は、次の値を設定する必要があります。
echo 1 > /proc/sys/net/ipv4/tcp_fin_timeout
60秒(デフォルト)から1秒に設定します。
厳密に言えば、この答えは質問自体には答えないことを私は知っていますが、それを読むことは関連情報かもしれません:
ソケットをポート(およびアドレス)にバインドするデフォルトの動作は、ソケットがプロセスの突然の終了によってクローズされると、ソケットはしばらくの間TIME_WAITのままになるというものです。これは、このアドレス/ポートにすぐには再バインドできないことを意味します。標準のBSDソケットインタフェースを介してシステム自体を開発している場合は、(少なくともある程度までは)SO_REUSEADDRソケットオプションを使ってこの動作を制御できます。ソケットがTIME_WAITステータスにある場合、これは基本的にあなたが再び同じアドレス/ポートにバインドすることを可能にします。それでも、ポートごとに1つのソケットがあります。
ただし、TIME_WAITがそもそも存在する理由があるため、この情報は開発援助としてのみ使用する必要があります。他の回答で既に説明しました。
Iptablesを変更して再起動するスクリプトを書くことができます。ポート上のすべてのパケットをドロップするルールを追加するためのスクリプトと、そのルールを削除するための別のスクリプト。
他の回答では、ポートにバインドされたプロセスを強制終了する方法を説明しました - これはあなたが望むものではないかもしれません。サーバーを稼働させ続けたいが、クライアントからの接続を防ぐには、プロセスを停止しないでポートをブロックします。
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
もう1つの問題:カーネルがいつかポート自体を所有している場合があります。 NATルーティングでは、いくつかのポートをNAT用に開いたままにしておくことができます。あなたはこのためにプロセスを強制終了することはできません、これはカーネルであり、そして再設定と再起動が必要です。
ss を使用して、リスニングソケットを閉じることができます。
Sudo ss --kill state listening src :1234
ここで、1234はポート番号です。
ssはiproute2パッケージの一部であるため、最新のLinuxに既にインストールされている強力な変更があります。
関連する質問への回答 からこれについて学びました。
ソケット上のトラフィックが不要で、プロセスを継続したい場合は、 tcpkill を使用します。
tcpkill -i eth0 Host xxx.xxx.xxx.xxx and port yyyy
そのポート上のすべてのトラフィックを傍受して傍受するスニッフィングデーモンを起動します。アプリケーションをネットワーク分割についてテストするのに非常に便利です。