我想关闭客户端和服务器应用程序之间处于侦听模式的开放端口。
Linux中是否有任何手动命令行选项来关闭端口?
注意: 我知道“只有拥有连接套接字的应用程序才能关闭它,这将在应用程序终止时发生。”
我不明白为什么只有打开它的应用程序才有可能...但是我仍然很想知道是否还有其他方法可以做到。
我想关闭客户端和服务器应用程序之间处于侦听模式的开放端口。
Linux中是否有任何手动命令行选项来关闭端口?
注意: 我知道“只有拥有连接套接字的应用程序才能关闭它,这将在应用程序终止时发生。”
我不明白为什么只有打开它的应用程序才有可能...但是我仍然很想知道是否还有其他方法可以做到。
Answers:
我有同样的问题,该进程必须保持活动状态,但是套接字必须关闭。在正在运行的进程中关闭套接字不是不可能的,但是很困难:
定位过程:
netstat -np
你得到一张source/destination ip:port portstate pid/processname
地图
在进程中找到套接字的文件描述符
lsof -np $pid
您将得到一个列表:进程名称,PID,用户,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感到困惑。在我的情况下过程是一个Chrome标签,我试图关闭打开的WebSockets ...
shutdown
:call shutdown($fileDescriptor, 0)
。
您在这里提出了错误的问题。实际上,不可能简单地从打开侦听套接字的应用程序外部“关闭端口”。唯一的方法是完全杀死拥有该端口的进程。然后,大约一两分钟后,该端口将再次可用。这是正在发生的事情(如果您不关心,请跳到最后,我向您展示如何杀死拥有特定端口的进程):
端口是操作系统分配给不同进程的资源。这类似于要求操作系统提供文件指针。但是,与文件指针不同,一次只能有一个进程拥有一个端口。通过BSD套接字接口,进程可以发出侦听端口的请求,然后操作系统将批准该端口。操作系统还将确保没有其他进程获得相同的端口。在任何时候,该过程都可以通过关闭套接字来释放端口。然后,操作系统将收回该端口。或者,如果进程在没有释放端口的情况下结束,则操作系统最终将收回该端口(尽管不会立即发生:这将需要几分钟)。
现在,您要执行的操作(仅从命令行关闭端口)由于两个原因而无法实现。首先,如果可能的话,这意味着一个进程可以简单地窃取另一个进程的资源(端口)。除非限于特权进程,否则这将是错误的策略。第二个原因是,如果让端口继续运行,尚不清楚拥有该端口的进程将发生什么情况。假定过程拥有该资源,则编写该过程的代码。如果我们只是简单地删除它,它最终将自己崩溃,因此即使您是特权进程,OS也不允许您这样做。相反,您必须简单地杀死它们。
无论如何,这是如何杀死拥有特定端口的进程:
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
之前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秒,内核为我完成。
您可能只需要找出哪个进程打开了与端口关联的套接字,然后杀死该进程即可。
但是,您将必须意识到,除非该进程的处理程序取消初始化它正在使用的所有内容(打开的文件,套接字,派生类,除非在终止时正确关闭,否则这些内容会持续存在),那么您将已经创建了该处理程序。拖累系统性能。另外,套接字将保持打开状态,直到内核意识到该进程已被终止为止。通常只需要一分钟。
我想更好的问题是:您要停止哪个端口(属于哪个进程)?
如果您想终止发现的后门或病毒,那么在终止数据之前,至少应了解来回的数据。(wireshark对此很有用)(还有进程的可执行文件名称,因此您可以删除它并防止其在重新启动时再次出现),或者,如果已安装了某些文件(例如HTTPD或FTPD等),则您应该已经可以访问过程本身。
通常它将具有一个控制程序(HTTPD停止|启动之类的东西)。或者,如果这是系统性的事情,那么您可能不应该将其弄乱。无论如何,我认为既然其他所有人都在给您“如何做”的角度,我应该给您一些警告。
您可以使用名为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状态,则基本上可以使您再次绑定到相同的地址/端口。每个端口仍然有一个插座!
但是,此信息仅应用作开发辅助,因为TIME_WAIT首先存在是有原因的,在其他答案中已经对此进行了解释。