在Linux系统中,监听通常指某个进程或服务在网络端口上等待连接请求的状态,常见于Web服务器(如Nginx、Apache)、数据库服务(如MySQL、Redis)或自定义应用程序,停止监听可能是出于安全加固、服务迁移、资源释放或故障排查等需求,以下是详细的方法和步骤,涵盖不同场景下的监听停止操作。
查找监听信息:定位目标是前提
停止监听前,需先明确当前系统中有哪些进程或服务正在监听,以及监听的端口和协议,常用的工具有netstat
和ss
(推荐,因ss
是netstat
的升级版,性能更优)。
使用ss
命令查看监听
ss
命令可快速显示TCP、UDP等协议的 socket 统计信息,常用选项如下:
-t
:显示TCP端口-u
:显示UDP端口-l
:仅显示监听状态的端口-n
:以数字形式显示地址和端口(避免域名解析延迟)-p
:显示使用该端口的进程ID(PID)和名称
示例:查看所有监听的TCP和UDP端口
ss -tulnp
输出示例中,Local Address:Port
列显示监听地址和端口(如0.0.0:80
表示监听所有IPv4地址的80端口),PID/Program name
列对应进程信息(如nginx: master process
)。
使用netstat
命令(传统工具)
若系统未安装ss
,可用netstat
,选项与ss
类似:
netstat -tulnp
筛选特定端口的监听
若需查看特定端口(如8080端口)的监听情况:
ss -tulnp | grep ':8080'
命令对比表格
命令 | 常用选项 | 功能描述 |
---|---|---|
ss |
-tulnp |
显示TCP/UDP监听端口,进程ID及名称 |
netstat |
-tulnp |
传统工具,功能同ss ,但性能略低 |
停止系统服务监听:适用于常规服务
大多数Linux服务(如Nginx、Apache、SSH、MySQL)通过系统服务管理器(如systemd
、SysV
)启动,停止监听需通过服务管理命令。
使用systemctl
管理(主流系统)
现代Linux发行版(如Ubuntu 16+、CentOS 7+)使用systemd
,操作如下:
- 停止服务(立即终止进程,释放端口):
systemctl stop nginx # 以Nginx为例
- 禁用自启动(避免服务开机自动运行,长期生效):
systemctl disable nginx
- 查看服务状态(确认是否已停止):
systemctl status nginx
若输出中显示
Active: inactive (dead)
,则表示服务已停止。
使用service
命令(传统SysVinit)
旧版系统(如CentOS 6、Ubuntu 14)或兼容模式下,可用service
命令:
service nginx stop
针对特定服务的注意事项
- Nginx/Apache:停止服务前建议检查配置文件语法(
nginx -t
),避免因配置错误导致后续启动失败。 - MySQL/PostgreSQL:若数据库正在处理事务,直接停止可能导致数据损坏,建议先执行
mysqladmin shutdown
(MySQL)或pg_ctl stop
(PostgreSQL)优雅关闭。
终止特定进程监听:适用于非服务进程
若监听来自自定义脚本、Java/Python程序等非系统服务进程,需通过进程ID(PID)终止进程。
查找目标进程PID
通过ps
命令结合grep
筛选进程:
ps aux | grep "python" # 查找Python进程
注意:grep
自身也会出现在结果中,可通过grep -v grep
过滤:
ps aux | grep "python" | grep -v grep
终止进程
根据进程重要性选择终止方式:
- 优雅终止(推荐):发送
SIGTERM
信号(15),允许进程清理资源后退出:kill PID # PID为上一步查到的进程ID
- 强制终止:若进程无响应,发送
SIGKILL
信号(9),立即终止进程(可能导致数据丢失):kill -9 PID
批量终止同名进程
若多个同名进程需终止,可用pkill
或killall
:
pkill -f "python app.py" # 根据进程名或命令终止 killall nginx # 终止所有名为nginx的进程
通过防火墙禁止监听:临时阻断外部访问
若需快速禁止外部访问监听端口(但不停止进程),可通过防火墙规则实现。
使用iptables
(传统防火墙)
- 添加规则(禁止TCP 80端口入站):
iptables -A INPUT -p tcp --dport 80 -j DROP
- 保存规则(避免重启失效):
service iptables save # CentOS/RHEL iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu
使用firewalld
(CentOS 7+、RHEL 7+)
- 添加规则(永久禁止80端口):
firewall-cmd --permanent --add-port=80/tcp firewall-cmd --reload # 重新加载防火墙
- 移除规则(若需恢复访问):
firewall-cmd --permanent --remove-port=80/tcp firewall-cmd --reload
验证监听是否停止
执行停止操作后,需再次检查端口监听状态:
ss -tulnp | grep ":80" # 检查80端口是否仍监听
若无输出,或State
列不再是LISTEN
,则表示监听已停止。
注意事项
- 权限问题:停止系统服务或终止进程需root权限(
sudo
),普通用户会提示“Permission denied”。 - 服务依赖:若服务被其他服务依赖(如PHP-FPM依赖Nginx反向代理),直接停止可能导致依赖服务异常。
- 配置文件修改:停止服务后,若需彻底移除监听,建议修改服务配置文件(如Nginx的
nginx.conf
)并注释或删除监听指令,再重启服务。 - 日志排查:若停止失败,可通过系统日志(
journalctl -u nginx
)或应用日志(如Nginx的error.log
)排查原因。
相关问答FAQs
Q1:为什么用systemctl stop
停止服务后,端口依然在监听?
A:可能原因包括:(1)服务未完全停止(如systemctl status
仍显示active
),可尝试systemctl kill
强制终止;(2)存在多个服务实例(如Nginx的master进程未退出,需手动终止master PID);(3)服务使用了“端口复用”(如SO_REUSEADDR选项),需先关闭该选项再重启,建议检查进程列表(ps aux | grep 服务名
),确认是否有残留进程。
Q2:如何区分监听端口是来自系统服务还是独立进程?
A:通过ss -tulnp
输出中的PID/Program name
列判断:若进程名为系统服务(如nginx
、mysqld
),则属于系统服务;若为脚本名(如python
、java
)或自定义路径(如/usr/local/bin/myapp
),则为独立进程,可通过systemctl status
查看服务状态,或cat /proc/PID/status
查看进程的启动命令和父进程信息进一步确认。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/35723.html