端口占用查看和网络监控
端口管理是Linux系统运维的重要组成部分。了解哪些端口被占用、被哪些进程使用,对于服务部署、故障排查和安全监控都至关重要。
基本端口查看命令
netstat命令
netstat
是传统的网络统计工具,功能强大且广泛使用。
# 查看所有端口监听状态
netstat -tunlp
# 参数说明:
# -t: 显示TCP端口
# -u: 显示UDP端口
# -n: 以数字形式显示地址和端口
# -l: 只显示监听状态的端口
# -p: 显示进程ID和进程名(需要root权限)
# 查看特定端口
netstat -tunlp | grep :80
netstat -tunlp | grep :22
# 查看所有网络连接
netstat -tuanp
# 查看TCP连接状态统计
netstat -ant | awk '{print $6}' | sort | uniq -c
ss命令
ss
是现代Linux系统推荐的网络工具,性能比netstat更好。
# 查看所有监听端口
ss -tunlp
# 查看TCP监听端口
ss -tln
# 查看UDP监听端口
ss -uln
# 查看特定端口
ss -tunlp | grep :80
ss -tunlp sport = :80
# 显示进程信息
ss -tlnp
# 查看连接统计
ss -s
lsof命令
lsof
(List Open Files)可以查看指定端口的详细使用情况。
# 查看指定端口占用
lsof -i :80
lsof -i :22
lsof -i :3306
# 查看TCP端口
lsof -i tcp:80
# 查看UDP端口
lsof -i udp:53
# 查看指定进程的网络连接
lsof -i -p [PID]
# 查看指定用户的网络连接
lsof -i -u username
高级端口分析
端口扫描和服务识别
#!/bin/bash
# port_scanner.sh - 简单端口扫描脚本
TARGET=${1:-"localhost"}
START_PORT=${2:-1}
END_PORT=${3:-1000}
echo "扫描主机: $TARGET"
echo "端口范围: $START_PORT - $END_PORT"
echo "=============================="
for port in $(seq $START_PORT $END_PORT); do
# 使用timeout避免长时间等待
if timeout 1 bash -c "echo >/dev/tcp/$TARGET/$port" 2>/dev/null; then
echo "端口 $port: 开放"
# 尝试识别服务
service=$(grep "^[^#]*\s$port/" /etc/services | head -1 | awk '{print $1}')
if [ -n "$service" ]; then
echo " 服务: $service"
fi
fi
done
端口使用分析脚本
#!/bin/bash
# port_analysis.sh - 端口使用情况分析
echo "系统端口使用分析报告"
echo "===================="
echo "生成时间: $(date)"
echo
echo "1. 监听端口统计:"
echo "---------------"
netstat -tln | awk 'NR>2 {print $4}' | cut -d: -f2 | sort -n | uniq -c | sort -nr | head -10
echo -e "\n2. 服务进程端口占用:"
echo "-------------------"
ss -tlnp | awk 'NR>1 {
split($4, addr, ":")
port = addr[length(addr)]
if (port != "" && port != "*") {
split($6, proc, ",")
gsub(/.*pid=/, "", proc[1])
gsub(/,.*/, "", proc[1])
print port "\t" proc[1] "\t" $6
}
}' | sort -n | head -20
echo -e "\n3. 网络连接状态统计:"
echo "-------------------"
netstat -ant | awk 'NR>2 {print $6}' | sort | uniq -c | sort -nr
echo -e "\n4. 外部连接统计(TOP 10):"
echo "----------------------"
netstat -ant | awk 'NR>2 && $6=="ESTABLISHED" {
split($5, remote, ":")
print remote[1]
}' | sort | uniq -c | sort -nr | head -10
echo -e "\n5. 常见服务端口检查:"
echo "------------------"
common_ports="22 23 25 53 80 110 143 443 993 995 3306 5432 6379 27017"
for port in $common_ports; do
service=$(ss -tln | grep ":$port ")
if [ -n "$service" ]; then
process=$(ss -tlnp | grep ":$port " | awk '{print $6}' | cut -d, -f1)
echo "端口 $port: 使用中 ($process)"
else
echo "端口 $port: 未使用"
fi
done
实时端口监控
#!/bin/bash
# port_monitor.sh - 实时端口监控
LOG_FILE="/var/log/port_monitor.log"
CHECK_INTERVAL=60
monitor_ports() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 检查关键服务端口
critical_ports="22 80 443 3306"
for port in $critical_ports; do
if ss -tln | grep -q ":$port "; then
echo "[$timestamp] 端口 $port: 正常监听" >> $LOG_FILE
else
echo "[$timestamp] 警告: 端口 $port 未监听!" | tee -a $LOG_FILE
# 这里可以添加告警通知
fi
done
# 检查异常端口占用
new_ports=$(ss -tln | awk 'NR>1 {split($4,a,":"); print a[length(a)]}' | sort -n | uniq)
if [ -f /tmp/previous_ports.txt ]; then
diff_ports=$(comm -13 /tmp/previous_ports.txt <(echo "$new_ports"))
if [ -n "$diff_ports" ]; then
echo "[$timestamp] 发现新端口: $diff_ports" | tee -a $LOG_FILE
fi
fi
echo "$new_ports" > /tmp/previous_ports.txt
}
# 持续监控
while true; do
monitor_ports
sleep $CHECK_INTERVAL
done
端口安全分析
安全端口检查
#!/bin/bash
# security_port_check.sh - 端口安全检查
echo "端口安全检查报告"
echo "================"
echo "1. 危险端口检查:"
echo "---------------"
dangerous_ports="23 21 135 139 445 1433 3389 5900"
for port in $dangerous_ports; do
if ss -tln | grep -q ":$port "; then
echo "警告: 发现危险端口 $port 开放"
case $port in
23) echo " - Telnet服务,建议使用SSH替代" ;;
21) echo " - FTP服务,建议使用SFTP替代" ;;
135|139|445) echo " - Windows共享服务,检查是否必要" ;;
1433) echo " - SQL Server,确保访问控制" ;;
3389) echo " - RDP服务,确保强密码和访问限制" ;;
5900) echo " - VNC服务,确保认证配置" ;;
esac
fi
done
echo -e "\n2. 对外开放端口检查:"
echo "-------------------"
ss -tln | awk 'NR>1 && $4 !~ /127\.0\.0\.1/ && $4 !~ /::1/ {
split($4, addr, ":")
port = addr[length(addr)]
if (addr[1] == "0.0.0.0" || addr[1] == "::") {
print "端口 " port ": 对外开放"
}
}'
echo -e "\n3. 非标准端口服务:"
echo "-----------------"
ss -tlnp | awk 'NR>1 {
split($4, addr, ":")
port = addr[length(addr)]
if (port > 1024 && port < 65535) {
print "端口 " port ": " $6
}
}' | head -10
echo -e "\n4. 建议:"
echo "-------"
echo "- 关闭不必要的服务和端口"
echo "- 使用防火墙限制端口访问"
echo "- 定期审计端口开放状况"
echo "- 监控异常端口活动"
网络连接异常检测
#!/bin/bash
# network_anomaly_detect.sh
echo "网络连接异常检测"
echo "================"
# 检测大量连接的IP
echo "1. 连接数异常IP (>50个连接):"
netstat -ant | awk '$6=="ESTABLISHED" {
split($5, remote, ":")
count[remote[1]]++
}
END {
for (ip in count) {
if (count[ip] > 50) {
print ip ": " count[ip] " 连接"
}
}
}'
# 检测SYN_RECV状态过多
echo -e "\n2. SYN_RECV连接检查:"
syn_count=$(netstat -ant | grep SYN_RECV | wc -l)
if [ $syn_count -gt 100 ]; then
echo "警告: SYN_RECV连接过多 ($syn_count),可能遭受SYN攻击"
else
echo "SYN_RECV连接正常 ($syn_count)"
fi
# 检测TIME_WAIT状态
echo -e "\n3. TIME_WAIT连接检查:"
time_wait_count=$(netstat -ant | grep TIME_WAIT | wc -l)
if [ $time_wait_count -gt 1000 ]; then
echo "警告: TIME_WAIT连接过多 ($time_wait_count)"
echo "建议检查应用程序连接复用配置"
else
echo "TIME_WAIT连接正常 ($time_wait_count)"
fi
# 检测异常端口连接
echo -e "\n4. 异常高端口连接:"
netstat -ant | awk '$6=="ESTABLISHED" {
split($4, local, ":")
split($5, remote, ":")
if (remote[2] > 50000) {
print "本地端口 " local[2] " -> " $5
}
}' | head -5
防火墙集成
端口访问控制
#!/bin/bash
# port_firewall_manager.sh - 端口防火墙管理
PORT=$1
ACTION=$2
SOURCE_IP=$3
usage() {
echo "用法: $0 <端口> <动作> [源IP]"
echo "动作: open, close, allow, deny"
echo "示例: $0 80 open"
echo " $0 22 allow 192.168.1.100"
exit 1
}
if [ -z "$PORT" ] || [ -z "$ACTION" ]; then
usage
fi
case $ACTION in
"open")
echo "开放端口 $PORT"
iptables -A INPUT -p tcp --dport $PORT -j ACCEPT
;;
"close")
echo "关闭端口 $PORT"
iptables -D INPUT -p tcp --dport $PORT -j ACCEPT 2>/dev/null
iptables -A INPUT -p tcp --dport $PORT -j DROP
;;
"allow")
if [ -n "$SOURCE_IP" ]; then
echo "允许 $SOURCE_IP 访问端口 $PORT"
iptables -A INPUT -p tcp -s $SOURCE_IP --dport $PORT -j ACCEPT
else
echo "错误: 需要指定源IP"
exit 1
fi
;;
"deny")
if [ -n "$SOURCE_IP" ]; then
echo "拒绝 $SOURCE_IP 访问端口 $PORT"
iptables -A INPUT -p tcp -s $SOURCE_IP --dport $PORT -j DROP
else
echo "错误: 需要指定源IP"
exit 1
fi
;;
*)
echo "错误: 未知动作 $ACTION"
usage
;;
esac
# 保存防火墙规则
echo "保存防火墙规则..."
iptables-save > /etc/iptables/rules.v4
故障排查
端口无法绑定问题
# 检查端口占用情况
check_port_binding() {
local port=$1
echo "检查端口 $port 绑定情况:"
echo "======================="
# 检查是否被占用
if ss -tln | grep -q ":$port "; then
echo "端口 $port 已被占用"
# 显示占用进程
echo "占用进程:"
ss -tlnp | grep ":$port "
# 显示进程详细信息
pid=$(ss -tlnp | grep ":$port " | awk '{print $6}' | grep -o 'pid=[0-9]*' | cut -d= -f2)
if [ -n "$pid" ]; then
echo -e "\n进程详细信息:"
ps -fp $pid
fi
else
echo "端口 $port 未被占用"
# 检查防火墙
echo "检查防火墙规则:"
iptables -L INPUT | grep -i "$port"
fi
}
# 使用示例
# check_port_binding 80
网络服务诊断
#!/bin/bash
# network_service_diagnose.sh
SERVICE_PORT=$1
if [ -z "$SERVICE_PORT" ]; then
echo "用法: $0 <端口号>"
exit 1
fi
echo "网络服务诊断: 端口 $SERVICE_PORT"
echo "==============================="
# 1. 检查端口监听
echo "1. 端口监听状态:"
if ss -tln | grep -q ":$SERVICE_PORT "; then
echo " ✓ 端口正在监听"
ss -tlnp | grep ":$SERVICE_PORT "
else
echo " ✗ 端口未监听"
fi
# 2. 检查进程状态
echo -e "\n2. 服务进程状态:"
pid=$(ss -tlnp | grep ":$SERVICE_PORT " | awk '{print $6}' | grep -o 'pid=[0-9]*' | cut -d= -f2)
if [ -n "$pid" ]; then
echo " 进程ID: $pid"
echo " 进程状态: $(ps -o stat= -p $pid)"
echo " 启动时间: $(ps -o lstart= -p $pid)"
else
echo " 未找到监听进程"
fi
# 3. 检查网络连接
echo -e "\n3. 网络连接测试:"
echo " 本地连接测试:"
if timeout 3 bash -c "echo >/dev/tcp/localhost/$SERVICE_PORT" 2>/dev/null; then
echo " ✓ 本地连接成功"
else
echo " ✗ 本地连接失败"
fi
# 4. 检查防火墙
echo -e "\n4. 防火墙检查:"
if command -v iptables >/dev/null; then
fw_rules=$(iptables -L INPUT -n | grep -E ":$SERVICE_PORT |$SERVICE_PORT:")
if [ -n "$fw_rules" ]; then
echo " 防火墙规则:"
echo "$fw_rules"
else
echo " 未找到特定防火墙规则"
fi
fi
# 5. 日志检查
echo -e "\n5. 相关日志:"
echo " 最近的系统日志:"
journalctl --since "1 hour ago" | grep -i "$SERVICE_PORT" | tail -3
性能监控
端口性能统计
#!/bin/bash
# port_performance_stats.sh
echo "端口性能统计"
echo "============"
# 连接数统计
echo "1. 各端口连接数:"
netstat -ant | awk 'NR>2 && $6=="ESTABLISHED" {
split($4, local, ":")
count[local[2]]++
}
END {
for (port in count) {
print "端口 " port ": " count[port] " 个连接"
}
}' | sort -k3 -nr | head -10
# 网络I/O统计
echo -e "\n2. 网络接口统计:"
cat /proc/net/dev | awk 'NR>2 {
print $1 " 接收: " $2 " 字节, 发送: " $10 " 字节"
}' | head -5
# TCP状态分布
echo -e "\n3. TCP连接状态分布:"
netstat -ant | awk 'NR>2 {print $6}' | sort | uniq -c | sort -nr
注意事项和最佳实践
- 权限要求: 查看进程信息通常需要root权限
- 性能影响: 频繁的端口扫描可能影响系统性能
- 安全考虑:
- 定期审计开放端口
- 关闭不必要的服务
- 使用防火墙限制访问
- 监控建议:
- 建立端口基线
- 监控异常连接
- 定期安全检查
相关命令
netstat
- 网络连接统计ss
- 现代网络工具lsof
- 列出打开文件nmap
- 网络扫描工具iptables
- 防火墙配置tcpdump
- 网络抓包wireshark
- 网络协议分析
掌握端口管理技能对于Linux系统运维、安全管理和故障排查都至关重要。