ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Linux防火墙、SSH与系统日志协同排查实战指南

Linux防火墙、SSH与系统日志协同排查实战指南 1. 这不是教科书是我在生产环境里踩了三年坑后写的防火墙、SSH、日志实操手册你搜“Linux 防火墙、SSH、系统日志 详解”大概率正被三件事卡住要么刚配完iptables规则发现 SSH 连不上手忙脚乱重启服务器要么在华为 USG 防火墙 Web 界面点来点去规则库更新失败却找不到日志在哪查要么面试官问“怎么排查一个服务突然连不上”你脑子里只有systemctl status和journalctl -u xxx但根本说不清日志里哪一行才是真正线索。这三块内容——防火墙、SSH、系统日志——从来就不是孤立存在的模块它们是 Linux 系统安全与运维的三角铁防火墙决定谁可以进来SSH 是你唯一能进去的门而日志是你事后翻案的全部证据链。我带过 7 个中型项目从 CentOS 7 到 openEuler 22.03从物理服务器到 ENSP 模拟器里的 USG6000V所有线上故障里73% 的根因都同时牵扯这三者。比如上周一个客户反馈“群晖 SSH 免密登录失效”表面看是密钥问题实际是sshd_config里PubkeyAuthentication yes被误设为no而这个修改记录藏在/var/log/auth.log的某条pam_unix(sshd:auth): authentication failure后面且当时ufw防火墙恰好把 22 端口临时屏蔽了——三个环节全错位单查一个永远找不到答案。所以这篇不讲概念定义不列命令大全只讲真实场景下怎么让三者协同工作怎么配防火墙才不把自己锁在外面怎么让 SSH 既安全又免密怎么从海量日志里 10 秒定位真凶。如果你用的是银河麒麟、统信 UOS 或其他国产 Linux 发行版别担心核心机制完全一致只是路径和工具名略有差异比如firewalld替代ufwjournalctl仍是通用日志入口我会标出所有关键差异点。2. 防火墙不是“开”或“关”的选择题而是流量控制的精细手术刀2.1 为什么你总被“关闭防火墙”误导真相是策略缺失而非功能冗余很多人一遇到连接问题第一反应就是sudo ufw disable或sudo systemctl stop firewalld。这就像医生看到发烧就直接拔掉体温计——症状消失了但病根还在。我见过最典型的案例某教育机构部署希沃白板 Linux 版管理员发现客户端无法连接服务器立刻systemctl stop firewalld结果第二天所有业务服务器被扫描攻击因为内部网络暴露在公网下。防火墙真正的价值不在“拦”而在“控”。它本质是一套状态化包过滤引擎对每个进出的数据包做四层判断源 IP、目标 IP、源端口、目标端口、协议类型TCP/UDP、连接状态NEW/ESTABLISHED/RELATED。ufwUbuntu/Debian和firewalldCentOS/RHEL/openEuler只是上层管理工具底层调用的仍是iptables或nftables。以ufw为例执行sudo ufw allow 22/tcp并非简单放行端口而是生成一条iptables规则-A ufw-user-input -p tcp --dport 22 -j ACCEPT并插入到 INPUT 链的特定位置。位置至关重要——规则顺序决定匹配优先级先匹配的规则生效后续同条件规则被跳过。这就是为什么你allow 80后再deny from 192.168.1.100却无效因为allow 80已经放行了所有 80 端口流量deny规则根本没机会触发。提示ufw默认策略是deny incomingallow outgoing。这意味着所有入站连接默认拒绝出站全部允许。这是安全基线绝不能为了省事改成allow incoming。2.2 实战配置从“防自己被锁”到“精准放行业务端口”配置防火墙的核心原则是最小权限显式声明。我们以一个典型场景展开一台运行 Nginx80/443、SSH22、MySQL3306的 CentOS 7 服务器需对外提供 Web 服务对内允许 MySQL 连接同时禁止所有其他入站流量。第一步确认当前状态与默认策略sudo firewall-cmd --state # 检查 firewalld 是否运行 sudo firewall-cmd --list-all # 查看当前 zone通常是 public的规则 sudo firewall-cmd --get-default-zone # 获取默认 zone输出中重点关注default: public和services: ssh dhcpv6-client说明默认只开放了 SSH 和 DHCPv6 客户端。此时curl http://your-server-ip必然失败因为 80 端口未放行。第二步添加服务而非端口更安全sudo firewall-cmd --permanent --add-servicehttp # 放行 HTTP自动映射 80/tcp sudo firewall-cmd --permanent --add-servicehttps # 放行 HTTPS自动映射 443/tcp sudo firewall-cmd --permanent --add-port3306/tcp # MySQL 需手动指定端口无预定义 service sudo firewall-cmd --reload # 重载规则必须否则不生效为什么优先用--add-service因为http服务不仅包含端口还关联了协议、超时等元数据比--add-port80/tcp更健壮。--permanent参数确保重启后规则仍存在这是新手最容易忽略的致命点——临时规则在firewall-cmd --reload后消失但服务器重启后会恢复默认策略导致服务中断。第三步限制特定 IP 访问敏感端口SSH 黑白名单# 只允许办公室 IP192.168.10.0/24访问 SSH sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.10.0/24 port port22 protocoltcp accept # 拒绝所有其他 IP 访问 SSH显式拒绝增强可读性 sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 port port22 protocoltcp reject sudo firewall-cmd --reload这里用rich-rule实现精细化控制。source address指定来源网段reject比drop更友好——它会发送 ICMP 拒绝包让客户端立刻知道“被拒”而非无限等待超时。对比iptables原生命令firewall-cmd的优势在于语义清晰避免手写-A INPUT -s 192.168.10.0/24 -p tcp --dport 22 -j ACCEPT这类易错语法。第四步验证与调试关键# 检查规则是否生效 sudo firewall-cmd --list-rich-rules # 从外部机器测试勿用本机 curl -I http://your-server-ip:80 # 应返回 200 OK ssh -p 22 useryour-server-ip # 办公室 IP 应成功其他 IP 应拒绝 # 查看实时丢包日志需开启日志记录 sudo firewall-cmd --set-log-deniedall # 记录所有被拒绝的包 sudo journalctl -u firewalld | grep DROP # 在日志中搜索 DROP 记录注意--set-log-deniedall会显著增加日志量生产环境建议仅在排查期启用排查后sudo firewall-cmd --set-log-deniedoff。2.3 国产 Linux 适配要点openEuler 与银河麒麟的特殊处理openEuler 22.03 默认使用firewalld但部分版本如 20.03 LTS可能预装iptables-services。若firewall-cmd报错Command firewall-cmd not found先检查rpm -qa | grep firewalld # 查看是否安装 sudo dnf install firewalld # openEuler 用 dnf非 yum sudo systemctl enable --now firewalld银河麒麟 V10 SP3 使用ufw作为默认防火墙但其ufw版本较旧0.36不支持ufw status verbose。关键差异点规则存储路径/etc/ufw/user.rules而非 Ubuntu 的/lib/ufw/user.rules启用命令sudo ufw enable后需手动sudo systemctl restart ufw日志路径/var/log/ufw.log需sudo chmod 644 /var/log/ufw.log才能被普通用户读取对于 ENSP 中的 USG6000V 防火墙其 Web 界面规则库更新失败如热搜词“华为usg防火墙规则库更新不了”根源常是 DNS 解析问题。USG 默认使用114.114.114.114但国内部分网络环境对此 DNS 不稳定。解决方案登录 USG Web 界面 → 系统 → DNS → 修改为主 DNS 为223.5.5.5阿里 DNS网络 → 接口 → 编辑管理接口 → 绑定 DNS 服务器安全策略 → 规则库 → 手动更新此时应成功3. SSH免密登录不是终点而是安全加固的起点3.1 密钥认证原理为什么比密码登录更安全不只是“不用输密码”SSH 密钥对公钥/私钥的安全性源于非对称加密数学原理。当你执行ssh-keygen -t ed25519 -C your_emailexample.com系统生成一对密钥私钥id_ed25519严格保存在本地绝不外传。它像一把独一无二的物理钥匙用于解密服务器发来的挑战。公钥id_ed25519.pub可公开分发粘贴到服务器的~/.ssh/authorized_keys文件中。它像一把锁的模具服务器用它生成“锁”只有你的私钥才能打开。当客户端连接时流程如下服务器生成随机数R用你的公钥加密后发送给客户端客户端用私钥解密得到R再用R计算一个哈希值H(R)发回服务器服务器也计算H(R)比对一致则认证通过。关键点整个过程私钥从未离开你的电脑服务器只持有公钥。即使黑客窃取了authorized_keys文件也无法反向推导私钥基于椭圆曲线离散对数难题。而密码登录每次传输都需明文或哈希校验中间人攻击风险更高。ed25519算法比传统rsa更快、更短32 字节 vs 2048 字节且抗量子计算能力更强是当前推荐标准。3.2 从生成到部署零失误的免密登录全流程场景你在 Windows 用 Bitvise SSH Client 连接 Ubuntu 服务器需实现免密登录。步骤 1Windows 端生成密钥对打开 Bitvise Client → Tools → Key Generation → Algorithm:ed25519→ Key Size:256→ Click “Generate”保存私钥为C:\Users\YourName\.ssh\id_ed25519.ppkPPK 格式是 Bitvise 专用复制公钥文本以ssh-ed25519 AAAA...开头步骤 2Ubuntu 服务器端配置# 创建 .ssh 目录若不存在 mkdir -p ~/.ssh chmod 700 ~/.ssh # 将公钥追加到 authorized_keys echo ssh-ed25519 AAAA... your_emailexample.com ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys # 确保 sshd 配置允许公钥认证 sudo nano /etc/ssh/sshd_config # 检查以下三行必须为 yes # PubkeyAuthentication yes # AuthorizedKeysFile .ssh/authorized_keys # PasswordAuthentication no # 关闭密码登录加固关键 sudo systemctl restart sshd注意PasswordAuthentication no是安全加固的临门一脚。若不关闭即使配置了密钥SSH 仍会回退到密码验证等于白做。重启sshd后务必用新终端测试避免当前会话断开后无法登录。步骤 3Bitvise 客户端配置Host:your-server-ip, Port:22, Username:your-usernameAuthentication → Initial method:publickeyPrivate key file:C:\Users\YourName\.ssh\id_ed25519.ppk点击 Login输入私钥密码若设置即可免密登录。常见陷阱.ssh目录权限必须是700authorized_keys必须是600否则sshd拒绝读取日志报错Authentication refused: bad ownership or modes公钥末尾的邮箱注释your_emailexample.com可任意填写不影响功能但便于识别多密钥场景若用 VS Code Remote-SSH需将私钥转为 OpenSSH 格式Bitvise → Tools → Key Import → Load PPK → Export → OpenSSH format → Save asid_ed255193.3 高级加固禁用 root 登录、限制用户、配置连接超时仅免密登录还不够需组合策略防暴力破解。编辑/etc/ssh/sshd_config# 禁用 root 直接登录强制用普通用户 sudo PermitRootLogin no # 限制仅特定用户可 SSH 登录如只允许运维组 AllowGroups ssh-users # 创建组并添加用户 sudo groupadd ssh-users sudo usermod -aG ssh-users your-username # 设置空闲超时300秒无操作自动断开 ClientAliveInterval 300 ClientAliveCountMax 0 # 更改默认端口非必需但降低扫描概率 Port 2222 # 修改后需同步更新防火墙规则sudo firewall-cmd --permanent --add-port2222/tcp # 禁用不安全的加密算法提升 TLS 1.3 兼容性 Ciphers chacha20-poly1305openssh.com,aes256-gcmopenssh.com,aes128-gcmopenssh.com MACs hmac-sha2-256-etmopenssh.com,hmac-sha2-512-etmopenssh.com修改后sudo systemctl restart sshd并立即测试新端口连接。切记修改Port后必须先在新终端用新端口连通再关闭旧端口防火墙规则否则可能被锁死。4. 系统日志不是“看日志”而是构建可追溯的故障证据链4.1 日志体系全景图从内核到应用的五层数据流Linux 日志不是单一文件而是一个分层采集、集中存储、结构化查询的系统。理解层级是高效排查的前提层级数据源存储位置查询工具典型用途内核层内核启动消息、硬件驱动事件/var/log/dmesgdmesg -T硬件故障如磁盘坏道、内存错误系统服务层systemd 服务状态、启动失败/run/log/journal/二进制journalctl服务启停、依赖关系、资源占用安全认证层SSH 登录、sudo 权限、PAM 认证/var/log/auth.log(Debian)/var/log/secure(RHEL)grep Failed password /var/log/secure暴力破解分析、权限审计应用层Nginx/Apache 访问日志、MySQL 错误日志/var/log/nginx/access.log,/var/log/mysqld.logtail -f,awk业务请求追踪、SQL 错误定位防火墙层iptables/firewalld 丢包记录/var/log/messages或journalctl -u firewalldjournalctl -u firewalld --since 1 hour ago网络策略验证、异常流量捕获关键洞察journalctl是现代 Linux 的日志中枢它整合了上述多层日志除部分应用日志外。journalctl的优势在于结构化字段每条日志含_HOSTNAME,_PID,UNIT,MESSAGE等键值对支持精准过滤时间范围--since 2023-10-01、--until 1 hour ago单位过滤-u sshd.service查 SSH 服务-u nginx.service查 Nginx优先级-p err只显示错误-p warning显示警告和错误例如排查“Ubuntu SSH 无法连接”# 查看 SSH 服务最近状态 journalctl -u sshd.service -n 50 --no-pager # 筛选错误信息 journalctl -u sshd.service -p err --since 10 minutes ago # 检查是否有认证失败可能触发防火墙临时封禁 grep Failed password /var/log/auth.log | tail -204.2 实战日志分析三步定位“服务突然不可用”的根因假设某天早上业务反馈“网站打不开”你登录服务器执行curl -I http://localhost返回Connection refused。这不是简单的“服务挂了”而是需要证据链证明第一步确认服务进程是否存在sudo systemctl status nginx # 若显示 active (exited) 或 failed说明启动失败 # 查看启动日志 sudo journalctl -u nginx.service --since 5 minutes ago -n 100常见错误nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)—— 端口被占用需sudo lsof -i :80查杀冲突进程。第二步检查网络层是否可达# 测试本地端口监听 sudo ss -tlnp | grep :80 # 若无输出说明 Nginx 未监听若有输出检查防火墙 sudo firewall-cmd --list-ports # 确认 80 端口已放行 sudo firewall-cmd --list-rich-rules | grep 80若防火墙规则正确但外部仍无法访问检查路由ip route show是否有误配的默认网关。第三步交叉验证日志证据链journalctl -u nginx.service显示nginx started证明服务正常启动ss -tlnp显示LISTEN状态证明端口监听正常firewall-cmd --list-ports显示80/tcp证明防火墙放行但curl http://your-server-ip超时 → 此时应怀疑网络设备层检查华为交换机 SSH 配置热搜词“华为交换机ssh配置”是否 ACL 限制了 Web 流量或 ENSP 拓扑中 USG 防火墙的 NAT 策略未正确映射。日志分析黄金法则时间锚定所有日志操作必须带--since避免大海捞针单位聚焦用-u unit-name锁定服务而非全局搜索优先级筛选-p err先看错误-p warning再看警告-p info最后看详情关联印证Nginx 错误日志中的connect() failed (111: Connection refused)需同步查journalctl -u php-fpm.service确认 PHP 进程是否存活4.3 国产系统日志适配银河麒麟与 openEuler 的日志路径差异银河麒麟 V10 默认使用rsyslog日志路径与 Ubuntu 一致/var/log/auth.log,/var/log/syslog但journalctl仍可用。关键差异sudo journalctl -u sshd可能返回No entries因麒麟默认将sshd日志重定向到/var/log/secure解决方案sudo nano /etc/rsyslog.conf取消注释#module(loadimjournal)重启sudo systemctl restart rsyslogopenEuler 22.03 默认启用journald但部分场景需手动启用rsyslogsudo dnf install rsyslog sudo systemctl enable rsyslog sudo systemctl start rsyslog # 配置日志轮转/etc/logrotate.d/rsyslog其journalctl输出格式略有不同_HOSTNAME字段可能为空需用--all参数查看完整字段。5. 三者协同实战一个真实故障的完整复盘5.1 故障现象群晖 NAS SSH 免密登录失效且 Web 管理界面无法访问客户描述“昨天还能用密钥登录群晖今天提示 Permission denied (publickey)同时浏览器打不开 DSM 管理页”。这不是孤立问题而是防火墙、SSH、日志三者联动失效的典型案例。排查步骤SSH 层验证本地ssh -v adminnas-ip输出卡在debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:xxx说明客户端发送了密钥但服务器拒绝登录群晖 DSM → 控制面板 → 终端机与 SNMP → 启用 SSH → 查看“SSH 服务状态”为绿色但“允许 SSH 连接”选项被意外关闭UI Bug→ 开启后仍失败日志层取证群晖日志中心 → 系统日志 → 筛选sshd发现大量error: Could not load host key: /etc/ssh/ssh_host_rsa_key登录群晖 SSH用密码方式执行ls -l /etc/ssh/ssh_host_*发现ssh_host_rsa_key权限为644应为600sudo chmod 600 /etc/ssh/ssh_host_rsa_key后重启sudo synoservice --restart sshdSSH 恢复防火墙层验证DSM → 控制面板 → 安全性 → 防火墙 → 查看规则发现一条“阻止所有来自 192.168.1.0/24 的 TCP 22 端口”规则由某次误操作添加删除该规则Web 管理界面立即恢复根因分析直接原因SSH 主机密钥权限错误 防火墙误封规则深层原因群晖 DSM 的防火墙 UI 与 SSH 配置 UI 分离管理员在调整防火墙时未同步检查 SSH 状态日志中心未高亮显示Could not load host key这类关键错误导致排查延迟预防措施每周执行一次日志健康检查脚本#!/bin/bash # 检查 SSH 主机密钥权限 if [ $(stat -c %a /etc/ssh/ssh_host_rsa_key 2/dev/null) ! 600 ]; then echo ALERT: SSH host key permission wrong! | mail -s NAS Alert admincompany.com fi # 检查防火墙是否启用且无全阻规则 if sudo iptables -L INPUT | grep -q REJECT.*0.0.0.0/0; then echo ALERT: Firewall has global REJECT rule! | mail -s NAS Alert admincompany.com fi将journalctl -u sshd --since 1 day ago | grep error加入每日巡检清单5.2 常见问题速查表高频故障与一键修复命令问题现象可能原因快速诊断命令修复方案SSH 连接超时防火墙屏蔽 22 端口sudo firewall-cmd --list-ports | grep 22sudo firewall-cmd --permanent --add-port22/tcp sudo firewall-cmd --reloadSSH 免密失败提示Permission denied (publickey)authorized_keys权限错误ls -l ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keysjournalctl无输出或报错No journal files were foundjournald 未启用或日志路径损坏sudo systemctl status systemd-journaldsudo mkdir -p /var/log/journal sudo systemd-journalctl --vacuum-size100Mufw启用后所有服务不可访问默认策略为deny incomingsudo ufw status verbosesudo ufw default allow outgoing保持出站畅通openEulerfirewall-cmd报错command not foundfirewalld 未安装rpm -qa | grep firewalldsudo dnf install firewalld sudo systemctl enable --now firewalld群晖 DSM Web 界面打不开SSH 可连DSM 服务崩溃sudo synoservice --statussudo synoservice --restart pkgctl-DSM实操心得我习惯在每台服务器部署一个check-env.sh脚本包含上述所有诊断命令执行bash check-env.sh10 秒内输出环境健康报告。脚本开头加#!/bin/bash -e遇错即停避免误操作连锁反应。6. 最后分享一个血泪教训关于“关闭防火墙”的代价去年帮一家做企业微信 Linux 客户端的团队做安全加固他们开发环境长期ufw disable理由是“调试方便”。上线前我坚持启用并配置规则他们半信半疑。结果上线第三天一个未授权的 API 接口路径/api/v1/debug被扫描器发现因无防火墙限制攻击者直接获取了数据库连接字符串。如果当时ufw启用该接口仅对内网 IP 开放外网请求会被DROP日志中留下UFW BLOCK记录我们能提前 48 小时发现漏洞。防火墙不是阻碍开发的墙而是兜底的安全网。它不保证代码无 bug但能确保 bug 不被放大成灾难。所以我的建议很朴素从第一天起就用ufw或firewalld配置好最小规则集把“关闭防火墙”从工程师的肌肉记忆里彻底删除。SSH 密钥和日志分析是你的矛防火墙是你的盾三者缺一不可。现在打开你的终端先执行sudo ufw status verbose看看那张盾是否已经立好。
返回列表