为什么防火墙配置是第一优先级
新服务器上线后,如果不配防火墙,所有端口都是暴露在公网上的。我曾经有一台测试服务器没配防火墙,三天就被扫描到并植入了挖矿程序。从那以后,防火墙配置变成了我拿到服务器后做的第一件事。
Linux下有两个主流防火墙工具:UFW(简单易用)和iptables(灵活强大)。
UFW:简单好用的防火墙
UFW(Uncomplicated Firewall)是Ubuntu默认的防火墙管理工具,语法简洁,新手友好。
安装与启用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Ubuntu通常已预装,如果没有:
$ sudo apt install -y ufw
# 启用前先允许SSH,否则会把自己锁在外面!
$ sudo ufw allow ssh
Rules updated
Rules updated (v6)
# 如果SSH用了非标准端口
$ sudo ufw allow 2222/tcp
# 启用防火墙
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
|
警告:启用UFW前一定要先允许SSH端口!否则你会被锁在外面,只能通过VPS控制面板的VNC来修复。
常用操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| # 查看当前规则
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
# 允许特定端口
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
# 允许端口范围
$ sudo ufw allow 8000:8100/tcp
# 允许特定IP
$ sudo ufw allow from 192.168.1.100
# 允许特定IP访问特定端口
$ sudo ufw allow from 192.168.1.100 to any port 3306
# 拒绝特定IP
$ sudo ufw deny from 203.0.113.50
# 删除规则
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
$ sudo ufw delete 2
|
常用端口配置清单
| 服务 | 端口 | 命令 |
|---|
| SSH | 22 | ufw allow 22/tcp |
| HTTP | 80 | ufw allow 80/tcp |
| HTTPS | 443 | ufw allow 443/tcp |
| MySQL(仅本地) | 3306 | ufw allow from 127.0.0.1 to any port 3306 |
| Redis(仅本地) | 6379 | ufw allow from 127.0.0.1 to any port 6379 |
Web服务器典型配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| # 重置所有规则
$ sudo ufw reset
# 默认拒绝所有入站
$ sudo ufw default deny incoming
# 允许所有出站
$ sudo ufw default allow outgoing
# 允许SSH
$ sudo ufw allow ssh
# 允许HTTP和HTTPS
$ sudo ufw allow 'Nginx Full'
# 或者
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
# 启用
$ sudo ufw enable
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
|
iptables:精细控制
iptables更强大但语法更复杂,适合需要精细控制的场景。
基本概念
| 概念 | 说明 |
|---|
| Chain(链) | INPUT(入站)、OUTPUT(出站)、FORWARD(转发) |
| Target(动作) | ACCEPT(允许)、DROP(丢弃)、REJECT(拒绝) |
| Rule(规则) | 按顺序匹配,匹配到就执行对应动作 |
查看当前规则
1
2
3
4
5
6
7
| $ sudo iptables -L -n -v --line-numbers
Chain INPUT (policy ACCEPT)
num pkts bytes target prot opt in out source destination
1 1234 56789 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
2 5678 12345 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 234 5678 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
4 567 8901 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
|
常用规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # 允许回环接口
$ sudo iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
$ sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许SSH
$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许HTTP/HTTPS
$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允许ping
$ sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 默认拒绝所有入站(放在最后)
$ sudo iptables -P INPUT DROP
# 限制SSH连接频率(防暴力破解)
$ sudo iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
$ sudo iptables -A INPUT -p tcp --dport 22 -m recent --set --name ssh
$ sudo iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name ssh -j DROP
|
保存iptables规则
iptables的规则重启后会丢失,需要持久化:
1
2
3
4
5
6
7
8
| # Ubuntu/Debian
$ sudo apt install -y iptables-persistent
$ sudo netfilter-persistent save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables save
# 手动保存
$ sudo iptables-save > /etc/iptables/rules.v4
|
UFW vs iptables 对比
| 特性 | UFW | iptables |
|---|
| 易用性 | 简单 | 复杂 |
| 灵活性 | 中等 | 非常高 |
| 学习曲线 | 低 | 陡峭 |
| 适用场景 | Web服务器、VPS | 网关、复杂网络 |
| 底层实现 | 基于iptables | 原生 |
我的建议:单台Web服务器用UFW完全够了;如果做网关或者需要NAT转发,再用iptables。
常见问题
把自己锁在外面了
如果你不小心把SSH端口封了:
- 登录VPS控制面板
- 使用VNC/Console连接
- 执行
sudo ufw disable 或 sudo iptables -F
防火墙规则不生效
1
2
3
4
5
6
7
8
| # 确认UFW是否启用
$ sudo ufw status
Status: inactive # 没启用!
$ sudo ufw enable
# 确认规则顺序(iptables按顺序匹配)
$ sudo iptables -L -n --line-numbers
|
关于SSH安全配置的更多建议,可以看SSH远程连接完全指南。服务器安全不仅仅是防火墙,用户权限管理也很重要,推荐阅读Linux用户与权限管理。