从命令行手动关闭端口

从命令行手动关闭端口

我想关闭客户端和服务器应用程序之间处于监听模式的开放端口。

Linux 中是否有任何手动命令行选项可以关闭端口?

笔记: 我了解到“只有拥有连接套接字的应用程序才应该关闭它,这将在应用程序终止时发生。”

我不明白为什么只有通过打开它的应用程序才有可能......但我仍然渴望知道是否还有其他方法可以做到这一点。

答案1

我遇到了同样的问题,进程必须保持活动状态,但套接字必须关闭。在正在运行的进程中关闭套接字并非不可能,但很困难:

  1. 找到进程:

    netstat -np
    

    你会得到一张source/destination ip:port portstate pid/processname地图

  2. 在进程中定位套接字的文件描述符

    lsof -np $pid
    

    您将获得一个列表:进程名称、pid、用户、文件描述符......一个连接字符串。

    找到与连接相匹配的文件描述符编号。它将类似于“97u”,表示“97”。

  3. 现在连接流程:

    gdb -p $pid
    
  4. 现在关闭套接字:

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

    例子:

    call close(97)
    

    然后分离 gdb:

    quit
    

    并且插座已关闭。

答案2

你问的问题有点不对。实际上不可能简单地从打开套接字并监听该端口的应用程序外部“关闭端口”。唯一的方法是完全终止拥有该端口的进程。然后,大约一两分钟后,该端口将再次可用。以下是正在发生的事情(如果你不介意,请跳到最后,我将向您展示如何终止拥有特定端口的进程):

端口是操作系统分配给不同进程的资源。这类似于向操作系统请求文件指针。但是,与文件指针不同,一次只有一个进程可以拥有一个端口。通过 BSD 套接字接口,进程可以请求监听端口,然后操作系统将授予该请求。操作系统还将确保没有其他进程获得相同的端口。在任何时候,进程都可以通过关闭套接字来释放端口。然后操作系统将回收该端口。或者,如果进程在没有释放端口的情况下结束,操作系统最终将回收该端口(尽管这不会立即发生:它需要几分钟)。

现在,您想要做的事情(简单地从命令行关闭端口)由于两个原因而无法实现。首先,如果可能的话,这意味着一个进程可以简单地窃取另一个进程的资源(端口)。除非仅限于特权进程,否则这将是一个糟糕的政策。第二个原因是,如果我们让拥有端口的进程继续运行,不清楚会发生什么。进程的代码是假设它拥有此资源而编写的。如果我们简单地将其拿走,它最终会自行崩溃,因此即使您是一个特权进程,操作系统也不会允许您这样做。相反,您必须简单地杀死它们。

无论如何,以下是如何终止拥有特定端口的进程的方法:

sudo netstat -ap | grep :<port_number>

这将输出与进程保持端口相对应的行,例如:

tcp  0  0 *:8000   *:* LISTEN  4683/procHoldingPort

在这种情况下,进程控制端口是打开端口的进程的名称,4683是它的 pid,并且8000(注意是TCP)是它所持有的端口号。

然后,查看最后一列,你会看到 /。然后执行以下命令:

kill  <pid>

如果这不起作用(您可以通过重新运行 netstat 命令进行检查)。请执行以下操作:

kill -9 <pid>

一般来说,如果可以的话,最好避免发送 SIGKILL。这就是为什么我告诉你kill在 之前先尝试一下kill -9。只需使用kill即可发送更温和的 SIGTERM。

就像我说的,如果你这样做,端口重新打开仍然需要几分钟的时间。我不知道有什么方法可以加快速度。如果有人知道,我很乐意听听。

答案3

定影器也可以使用

fuser -k -n *protocol portno*

此处的协议为 tcp/udp,端口号为您希望关闭的端口号。例如

fuser -k -n tcp 37

更多信息fuser 手册页

答案4

您也可以使用 iptables:

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

它基本上实现了你想要的。这将丢弃到端口 80 的所有 TCP 流量。

相关内容