← 回目录
18 Week 04 · 网络排查

防火墙 firewalld

今天回答一道标准面试题:「本机能访问,外面访问不了,怎么办?」——能三层一起答出来,这题就赢了。

基本操作

六条够用
查看
$ sudo firewall-cmd --state              # 防火墙开着没
running

$ sudo firewall-cmd --list-all           # 当前放行了什么 ← 最常用
public (active)
  interfaces: enp0s5
  services: dhcpv6-client ssh
  ports:
  ...
放行
# 按「服务名」放行(推荐,firewalld 知道 http 就是 80)
$ sudo firewall-cmd --add-service=http --permanent

# 按「端口」放行
$ sudo firewall-cmd --add-port=8080/tcp --permanent

# 必须 reload 才生效!
$ sudo firewall-cmd --reload

--permanent--reload

今天最容易踩的坑
两个参数配合的四种情况
不加 --permanent
立刻生效,但重启后消失。改的是"运行时"配置。
加了 --permanent
写进配置文件永久保存,但当下不生效。改的是"永久"配置。
加了 --permanent 但忘了 reload
最常见的坑:你以为放行了,实际当下还是不通,要等下次重启才生效。
正确做法
--permanent 改完,紧跟一条 --reload两条要当成一条来记。
一个安全的验证技巧

不确定规则对不对时,先不加 --permanent 试一次——万一配错把自己 SSH 关在外面了,重启机器就恢复了。

确认规则没问题,再加 --permanent 正式写进去。这个习惯救过很多远程运维的命。

zone 是什么

知道有这回事就行

firewalld 把网卡分到不同的「区域」,每个区域一套规则。默认都在 public,日常运维基本不用动它。

看一眼
$ firewall-cmd --get-default-zone
public

$ firewall-cmd --get-active-zones
public
  interfaces: enp0s5

常见的几个:public(默认,不信任)、trusted(全放行)、internal(内网)。面试时能说出"firewalld 是基于 zone 的,默认 public"就够了。

那道标准面试题

今天的核心

「服务在本机 curl 得通,从别的机器就是访问不了。」

这题几乎每个运维面试都会问。标准答案是三层,而且要按顺序说。

三层排查,由内向外
第一层 · 服务监听地址
sudo ss -tunlp | grep 端口——确认监听的是 0.0.0.0 而不是 127.0.0.1。是 127.0.0.1 的话,外面永远连不上,改服务配置即可,跟防火墙无关。(昨天学的)
第二层 · 系统防火墙
sudo firewall-cmd --list-all——看这个端口/服务在不在放行列表里。不在就 --add-port 加上,别忘了 --reload
第三层 · 云平台安全组
阿里云、腾讯云、AWS 都有自己的安全组,那是在你机器之外的一层防火墙。系统里全放开了也可能被它拦住。
为什么这个答案值钱

大部分候选人只会答"看防火墙"。能一口气说出三层、并且说清楚每层怎么查,说明你真在生产环境排过这个问题。

顺序也重要:从最靠近服务的一层开始查,比东一榔头西一棒子高效得多。

动手验证一遍

在你的虚拟机上真做
① 先制造"外面访问不了"
# 在虚拟机上确认 nginx 在跑、监听 0.0.0.0
$ sudo ss -tunlp | grep :80
$ curl -I http://127.0.0.1        # 本机通 → 200 OK

# 确认防火墙没放行 http
$ sudo firewall-cmd --list-all | grep services
② 从 Mac 上访问(应该不通)
# 在你 Mac 的终端里
$ curl -m 5 -I http://虚拟机IP
curl: (28) Connection timed out
     ↑ 超时,典型的被防火墙拦掉的表现
③ 放行后再试
# 回到虚拟机
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --reload

# 再从 Mac 上访问
$ curl -I http://虚拟机IP
HTTP/1.1 200 OK
拒绝和超时不一样

Connection refused(立刻拒绝)→ 端口是通的,但没有程序在监听。服务没起来。

Connection timed out(等半天没反应)→ 包被防火墙丢掉了。防火墙或安全组的问题。

能凭这两种报错分辨方向,排查速度快一倍。

几个实用补充

移除规则、临时关闭
$ sudo firewall-cmd --remove-service=http --permanent
$ sudo firewall-cmd --reload

# 临时停掉防火墙(排障时用来快速确认是不是它的问题)
$ sudo systemctl stop firewalld
# 测完记得起回来!
$ sudo systemctl start firewalld
面试时别说"我一般直接关防火墙"

临时 stop 来定位问题是可以的,但不能作为解决方案

正确说法:「我会临时停一下确认是不是防火墙的问题,确认了就精确放行对应端口,然后把防火墙起回来。」

今天的面试点

「本机能访问,外面访问不了,怎么办?」

我分三层查:

ss -tunlp 看服务监听的是 0.0.0.0 还是 127.0.0.1——如果是后者,外面永远连不上,得改服务配置。」

firewall-cmd --list-all 看防火墙放行没,注意 --permanent 之后要 --reload。」

是云平台的安全组,那层在系统之外,本地全放开也可能被它拦。」

「connection refused 和 timeout 有什么区别?」

refused 说明包到了,但没有程序监听那个端口——服务没起来。timeout 说明包被中途丢了——防火墙或安全组拦的。」

这题能答对,排查方向立刻就对了。

今天的练习

敲完再走 · 约 15 分钟
  • sudo firewall-cmd --state--list-all,看当前放行了什么
  • 完整走一遍上面的三步实验:本机 curl 通 → Mac 上 curl 超时 → 放行后 Mac 上通
  • 体会 --permanent 忘了 --reload 的效果:加规则后先别 reload,立刻 --list-all 看变没变
  • 练一次移除:--remove-service=http --permanent 然后 --reload,再从 Mac 测(应该又不通了)
  • 最后把 http 重新放行回来
  • 说出声:把三层排查法完整讲一遍,就当在面试
明天预告

Day 19 讲 SELinux——红帽系的特色,Ubuntu 出身的候选人答不上来的题

今天的三层排查还漏了一种情况:监听对了、防火墙也放行了,就是访问不了。那多半就是 SELinux 在拦。