linux – コマンドラインから手動でポートを閉じる

linux port sockets

クライアントとサーバアプリケーション間でリスニングモードになっているオープンポートを閉じたいのですが、どうすればいいですか?

Linuxでポートを閉じるための手動のコマンドラインオプションはありますか?

注: 私は、”接続されたソケットを所有しているアプリケーションだけがそれを閉じる必要があり、アプリケーションが終了したときに発生することを知るようになりました。”

開くアプリでしかできないのがよくわからない・・・。それでも他に方法があるのか知りたくてたまりません

  123  None  2010-04-06


ベストアンサー

私も同じ問題を抱えていました。プロセスは生き続けなければなりませんが、ソケットは閉じなければなりません。実行中のプロセスでソケットを閉じるのは不可能ではありませんが、難しいです

  1. プロセスを見つけます

    netstat -np
    

    source/destination ip:port portstate pid/processnameマップを取得します

  2. ソケットのファイルディスクリプタをプロセス内で検索します

    lsof -np $pid
    

    プロセス名、pid、user、fileDescriptor、…接続文字列のリストを取得します

    接続に一致するfileDescriptor番号を探します。それは “97 “を意味する “97u “のようなものになります

  3. これでプロセスを接続します

    gdb -p $pid
    
  4. 今すぐソケットを閉じてください

    call close($fileDescriptor) //does not need ; at end.
    

    example:

    call close(97)
    

    次にgdbをデタッチします

    quit
    

    そしてソケットは閉じている

143  Dankó Dávid  2013-11-01


あなたはここで間違った質問をしているようです。ソケットをオープンしているアプリケーションの外部からポートを閉じることはできません。これを行う唯一の方法は、ポートを所有しているプロセスを完全に終了させることです。そうすれば、1~2分ほどでポートが再び利用できるようになります。以下のようになっています(気にならなければ、特定のポートを所有しているプロセスを殺す方法を説明するところまで読み飛ばしてください)

ポートはOSが異なるプロセスに割り当てるリソースです。これは、OS にファイルポインタを要求するのと似ています。しかし、ファイルポインタとは異なり、ポートを所有できるのは一度に一つのプロセスだけです。BSD ソケットインタフェースを介して、プロセスはポートのリッスンを要求することができ、OS はそれを許可します。OS はまた、他のプロセスが同じポートを取得しないようにします。どの時点でも、プロセスはソケットを閉じることでポートを解放することができます。OSはその後、ポートを解放します。あるいは、ポートを解放せずにプロセスが終了した場合、OSは最終的にポートを解放します(すぐに解放されるわけではありませんが: 数分かかります)

さて、あなたがやりたいこと(コマンドラインからポートを閉じるだけ)は、2つの理由で不可能です。まず、もしそれが可能だとしたら、あるプロセスが他のプロセスのリソース(ポート)を盗むことができるということになります。これは、特権プロセスに制限されていない限り、悪いポリシーでしょう。第二の理由は、ポートを所有しているプロセスを実行し続けさせた場合、ポートを所有しているプロセスに何が起こるのかが不明確であることです。プロセスのコードは、このリソースを所有していると仮定して書かれています。このリソースを単純に奪ってしまうと、それ自体がクラッシュしてしまうので、たとえ特権プロセスであっても、OSはこのようなことはさせてくれません。その代わり、単純に殺すしかありません

とにかく、ここでは特定のポートを所有しているプロセスを 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を送ることができます

さっきも言ったように、これをやってもポートが再オープンするまでに数分はかかります。これを高速化する方法を知らない。どなたかご存知の方がいらっしゃいましたら、ぜひ教えていただきたいです

83  None  2010-04-06


フューザーも使用できます

fuser -k -n *protocol portno*

ここでプロトコルはtcp/udp、portnoは閉じたい番号です。例えば、以下のようになります

fuser -k -n tcp 37

詳細は ユーザーマニュアルページ をご覧ください

21  RedBaron  2012-02-13


代わりにiptablesを使うこともできます

iptables -I INPUT -p tcp --dport 80 -j DROP

これは基本的にあなたが望むことを達成します。これはすべての TCP トラフィックをポート 80 に落とします

6  supercheetah  2010-04-06


netstat -anp | grep 80

apache を実行している場合は、”httpd” を教えてくれるはずです (これは単なる例です。アプリケーションが使用しているポートを 80 の代わりに使用してください)

pkill -9 httpd

or

killall -9 httpd

3  Ben  2010-04-06


ss でリスニングソケットを閉じることができます

sudo ss --kill state listening src :1234

1234 はポート番号です

ss は iproute2 パッケージの一部なので、現代の Linux にはすでにインストールされているという強い変化があります

関連する質問への回答から知りました

3  Tom Anderson  2019-08-07


ポートに関連付けられたソケットを開いたプロセスを見つけて、そのプロセスを終了させることができるでしょう

しかし、そのプロセスが使用していたすべてのもの (開いているファイル、ソケット、フォーク、終了時に適切に閉じないと残るもの) を初期化しないハンドラを持っていないと、システムのパフォーマンスに影響を与えることに気づかなければなりません。さらに、カーネルがプロセスが終了したことに気づくまでソケットは開いたままになります。これには通常 1 分程度かかります

もっと良い質問があると思います。どのポート(どのプロセスに属している)を停止したいか?

見つけたバックドアやウィルスに終止符を打とうとしているのであれば、少なくとも終了させる前にどのようなデータが行き来しているのかを知るべきです。(wireshark が良いでしょう) (そして、プロセスの実行可能な名前があれば、それを削除して再起動時に戻ってこないようにすることができます) あるいは、それがインストールされたものであれば (HTTPD や FTPD など)、すでにプロセス自体にアクセスできるようになっているはずです

普通は制御プログラム(HTTPD stop|startとか)を持っているはずです。あるいは、システム上の問題であれば、おそらくそれに手を出すべきではないでしょう。とにかく、他のみんなが「ハウツー」の観点からあなたに説明しているので、私はあなたに注意点を与えるべきだと思いました

2  jackenheimer  2012-04-22


ポートを早くリリースしたい場合は、以下の値を設定する必要があります

echo 1 > /proc/sys/net/ipv4/tcp_fin_timeout

をクリックして、60秒(デフォルト)から1秒に設定します

2  Daniel  2015-04-23


最初に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 するだけです

kill -9 10418
kill -9 10490

最後にmeteorと入力すると、再び動作するはずです

2  abautista  2015-05-27


iptables を修正して再起動するスクリプトを書くことができます。ポート上のすべてのパケットを削除するルールを追加するためのスクリプトと、 そのルールを削除するためのスクリプトがあります

他の回答では、ポートにバインドされているプロセスを終了させる方法が示されていますが、これはあなたが望むものではないかもしれません。サーバを実行し続けたいが、クライアントからの接続を防ぎたい場合は、プロセスを停止するのではなく、ポートをブロックしたいのです

1  Michael Shimmins  2010-04-06


もう一つの問題: カーネルがポート自体を所有している場合があります。NAT ルーティングが NAT 使用のためにいくつかのポートを開放していることを知っています。これはカーネルであり、再設定と再起動が必要です

1  Rich Homolka  2013-11-01


killcxという名前のコマンドを使用して、強制終了されるプロセスがない状態で接続を終了させることができます

  • syntax:
killcx [dest_ip:dest_port] {interface}

dest_ip              : remote IP
dest_port            : remote port
interface (optional) : network interface (eth0, lo etc).
  • example:
killcx 120.121.122.123:1234
killcx 120.121.122.123:1234 eth0

1  shuaiming  2015-07-29


この回答は、厳密には質問自体には答えていないことは承知していますが、これを読むと関連性のある情報かもしれません

ソケットをポート(とアドレス)にバインドする際のデフォルトの動作は、プロセスの突然の終了によってソケットが閉じられた場合、ソケットはしばらくTIME_WAIT状態になります。これは、このアドレスやポートにすぐに再バインドできないことを意味します。標準の BSD ソケットインターフェースを使ってシステム自体を開発している場合、SO_REUSEADDR ソケットオプションを使って(少なくともある程度は)この挙動を制御することができます。これは基本的に、ソケットがTIME_WAIT状態にある場合に、同じアドレス/ポートに再度バインドすることを可能にします。しかし、ポートごとに1つのソケットを使用することになります

しかし、この情報は、他の回答ですでに説明したように、そもそもTIME_WAITが存在する理由があるので、あくまで開発援助として利用すべきです

1  Tommi Tuura  2015-10-15


ソケット経由のトラフィックを遮断したいが、プロセスを存続させたい場合。tcpkill

tcpkill -i eth0 host xxx.xxx.xxx.xxx and port yyyy

スニッフィングデーモンを起動し、そのポート上のすべてのトラフィックを遮断して破棄します。ネットワークスプリットのためにアプリケーションをテストするのに非常に便利です

0  RickyA  2016-03-30


タイトルとURLをコピーしました