# 防火墙与安全

URL: https://caijiao.org/rockylinux/firewall-and-security
Source: docs/rockylinux/firewall-and-security.md
Description: 详细介绍 Rocky Linux 中的防火墙配置和系统安全加固措施，包括 firewalld 使用、安全策略设置等

在 Rocky Linux 系统中，防火墙和安全配置是保障系统安全的重要组成部分。本教程将详细介绍如何配置和管理 firewalld 防火墙，以及实施各种系统安全加固措施，保护您的服务器免受常见的安全威胁。

## 防火墙基础

### 什么是防火墙？

防火墙是一种网络安全设备或软件，用于监控和控制进出网络的流量，基于预定义的安全规则允许或阻止数据包通过。防火墙可以保护系统免受未授权访问、恶意攻击和其他网络威胁。

### Rocky Linux 中的防火墙

Rocky Linux 默认使用 firewalld 作为动态防火墙管理器，它提供了一个更灵活、更强大的方式来管理系统防火墙规则，相比传统的 iptables 有以下优势：

- 动态规则更新，无需重启防火墙服务
- 支持区域（zones）概念，允许不同网络接口应用不同的安全策略
- 支持服务和端口的简便管理
- 支持 IPv4 和 IPv6
- 提供丰富的命令行和图形界面配置工具

## firewalld 基本配置

### 安装 firewalld

```bash
# 检查 firewalld 是否已安装
rpm -q firewalld

# 安装 firewalld
sudo dnf install firewalld -y
```

### 启动和管理 firewalld 服务

```bash
# 启动 firewalld
sudo systemctl start firewalld

# 检查 firewalld 状态
sudo systemctl status firewalld

# 设置 firewalld 开机自启
sudo systemctl enable firewalld

# 停止 firewalld（不推荐，除非进行维护）
sudo systemctl stop firewalld

# 禁用 firewalld 开机自启（不推荐）
sudo systemctl disable firewalld
```

## 区域（Zones）管理

### 了解 firewalld 区域

区域是 firewalld 的核心概念，每个区域定义了一组规则，用于控制进出特定网络接口的流量。firewalld 提供了多个预定义区域：

- **drop**：最高安全级别，丢弃所有入站流量，不回应任何数据包
- **block**：拒绝所有入站流量，对连接请求发送拒绝消息
- **public**：公共区域，只允许选定的服务通过
- **external**：用于外部网络，通常配置为 NAT
- **dmz**：隔离区，用于放置公开可访问的服务
- **work**：工作网络，信任网络内的大多数计算机
- **home**：家庭网络，较高信任级别
- **internal**：内部网络，高信任级别
- **trusted**：最高信任级别，允许所有流量

### 查看和设置默认区域

```bash
# 查看默认区域
sudo firewall-cmd --get-default-zone

# 设置默认区域
sudo firewall-cmd --set-default-zone=public

# 查看所有可用区域
sudo firewall-cmd --get-zones

# 查看活动区域（已分配接口的区域）
sudo firewall-cmd --get-active-zones
```

### 为接口分配区域

```bash
# 将接口分配到特定区域
sudo firewall-cmd --zone=public --change-interface=eth0

# 移除接口的区域分配
sudo firewall-cmd --zone=public --remove-interface=eth0

# 查看特定区域的接口
sudo firewall-cmd --zone=public --list-interfaces
```

## 服务和端口管理

### 管理预定义服务

```bash
# 查看所有可用服务
sudo firewall-cmd --get-services

# 在默认区域永久添加服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh

# 在特定区域临时添加服务（重启后失效）
sudo firewall-cmd --zone=public --add-service=ftp

# 移除服务
sudo firewall-cmd --permanent --remove-service=ftp

# 查看默认区域中启用的服务
sudo firewall-cmd --list-services

# 查看特定区域中启用的服务
sudo firewall-cmd --zone=public --list-services
```

### 管理端口

```bash
# 在默认区域永久添加端口（TCP）
sudo firewall-cmd --permanent --add-port=8080/tcp

# 在默认区域永久添加端口范围
sudo firewall-cmd --permanent --add-port=8000-9000/tcp

# 添加 UDP 端口
sudo firewall-cmd --permanent --add-port=53/udp

# 移除端口
sudo firewall-cmd --permanent --remove-port=8080/tcp

# 查看默认区域中开放的端口
sudo firewall-cmd --list-ports

# 查看特定区域中开放的端口
sudo firewall-cmd --zone=public --list-ports
```

## 防火墙规则管理

### 重新加载防火墙规则

```bash
# 重新加载防火墙规则以应用永久更改
sudo firewall-cmd --reload

# 完全重启防火墙（会中断现有连接）
sudo firewall-cmd --complete-reload
```

### 创建和管理富规则（Rich Rules）

富规则提供了更复杂和细粒度的访问控制：

```bash
# 允许来自特定 IP 的 SSH 访问
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'

# 拒绝来自特定网段的访问
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" reject'

# 限制访问频率（每分钟最多6个新连接）
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept limit value="6/m"'

# 记录匹配规则的连接
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" log prefix="HTTP-ACCESS: " level="info" accept'

# 移除富规则
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'

# 查看当前富规则
sudo firewall-cmd --list-rich-rules
```

### 端口转发

```bash
# 将端口 80 转发到 8080
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080

# 将流量转发到另一台服务器
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100

# 将流量转发到另一台服务器的特定端口
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080

# 移除端口转发规则
sudo firewall-cmd --permanent --remove-forward-port=port=80:proto=tcp:toport=8080
```

## 系统安全加固

### SSH 安全加固

1. **修改默认 SSH 端口**：

```bash
# 编辑 SSH 配置文件
sudo vim /etc/ssh/sshd_config
```

修改以下行：

```
Port 2222  # 更改默认端口 22 为其他端口
```

2. **禁用 root 远程登录**：

```
PermitRootLogin no
```

3. **限制允许登录的用户**：

```
AllowUsers user1 user2
# 或
AllowGroups admin
```

4. **使用密钥认证代替密码认证**：

```
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys
```

5. **重启 SSH 服务**：

```bash
sudo systemctl restart sshd
```

6. **更新防火墙规则以允许新的 SSH 端口**：

```bash
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
```

### 密码策略加强

1. **安装密码强度检查工具**：

```bash
sudo dnf install libpwquality -y
```

2. **编辑密码质量配置**：

```bash
sudo vim /etc/security/pwquality.conf
```

添加或修改以下配置：

```
# 最小密码长度
minlen = 12

# 最少包含的大写字母数
ucredit = -1

# 最少包含的小写字母数
lcredit = -1

# 最少包含的数字数
dcredit = -1

# 最少包含的特殊字符数
ocredit = -1

# 禁止包含用户名字符
reject_username

# 最少字符类数量（大写、小写、数字、特殊字符）
minclass = 4

# 历史记录的密码数量（防止重复使用）
remember = 5
```

3. **设置密码过期策略**：

```bash
sudo vim /etc/login.defs
```

修改以下配置：

```
# 密码最长使用天数
PASS_MAX_DAYS   90

# 密码最短使用天数
PASS_MIN_DAYS   1

# 密码过期前的警告天数
PASS_WARN_AGE   7
```

4. **为现有用户设置密码过期策略**：

```bash
# 设置密码最长使用天数
sudo chage -M 90 username

# 设置密码过期前的警告天数
sudo chage -W 7 username

# 强制用户下次登录时更改密码
sudo chage -d 0 username
```

### 禁用不必要的服务

```bash
# 查看当前运行的服务
sudo systemctl list-units --type=service --state=running

# 停止并禁用不必要的服务
sudo systemctl stop service_name
sudo systemctl disable service_name
```

常见的可考虑禁用的服务（根据实际需求）：

- `avahi-daemon`：网络发现服务
- `cups`：打印服务
- `dhcpcd`：如果使用静态 IP
- `telnet`：不安全的远程访问协议
- `ftp`：如果不需要

### 安装入侵检测系统（Fail2ban）

Fail2ban 可以监控日志文件并自动阻止可疑的 IP 地址：

1. **安装 Fail2ban**：

```bash
# 安装 EPEL 仓库（如果尚未安装）
sudo dnf install epel-release -y

# 安装 Fail2ban
sudo dnf install fail2ban fail2ban-systemd -y
```

2. **创建配置文件**：

```bash
# 复制默认配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# 编辑配置文件
sudo vim /etc/fail2ban/jail.local
```

3. **配置 SSH 保护**：

```ini
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
bantime = 3600
```

参数解释：

- `maxretry`：允许的失败尝试次数
- `findtime`：在这个时间窗口内（秒）
- `bantime`：禁止访问的时间（秒）

4. **启动并启用 Fail2ban**：

```bash
sudo systemctl enable --now fail2ban
```

5. **查看 Fail2ban 状态**：

```bash
sudo fail2ban-client status
sudo fail2ban-client status sshd
```

### 定期更新系统

设置自动更新可以确保您的系统及时获得安全补丁：

```bash
# 安装自动更新工具
sudo dnf install dnf-automatic -y

# 配置自动更新
sudo vim /etc/dnf/automatic.conf
```

修改配置：

```ini
[commands]
automatic_type = security  # 只自动更新安全补丁
apply_updates = yes        # 自动应用更新

[emitters]
emit_via = email          # 通过邮件发送通知

[email]
email_from = root@example.com
email_to = admin@example.com
email_server = localhost
```

启用自动更新服务：

```bash
sudo systemctl enable --now dnf-automatic.timer
```

## 安全监控

### 查看系统日志

```bash
# 查看认证日志
sudo journalctl -u sshd

# 查看系统日志中的错误
sudo journalctl -p err..emerg

# 实时监控日志
sudo journalctl -f
```

### 审计系统活动（auditd）

auditd 可以帮助您监控和记录系统活动，特别适用于安全审计：

1. **安装 auditd**：

```bash
sudo dnf install audit audit-libs -y
```

2. **启动并启用 auditd**：

```bash
sudo systemctl enable --now auditd
```

3. **创建审计规则**：

```bash
# 编辑审计规则文件
sudo vim /etc/audit/rules.d/audit.rules
```

添加常见的审计规则：

```
# 监控系统关键文件
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/sudoers -p wa -k sudoers_changes

# 监控登录活动
-w /var/log/lastlog -p wa -k user_login

# 监控防火墙规则更改
-w /etc/firewalld/ -p wa -k firewall_changes
```

4. **重新加载审计规则**：

```bash
sudo augenrules --load
```

5. **查看审计日志**：

```bash
sudo ausearch -k passwd_changes
sudo aureport
```

## 安全最佳实践

1. **最小权限原则**：只授予用户和服务完成任务所需的最小权限
2. **定期备份**：定期备份关键数据和配置文件
3. **使用加密通信**：对所有远程连接使用加密协议（SSH、HTTPS 等）
4. **禁用不必要的网络服务**：只启用必需的服务
5. **定期安全审计**：定期检查系统配置、用户账户和权限设置
6. **使用强密码**：实施强密码策略并定期更改密码
7. **限制远程访问**：限制可以远程访问系统的 IP 地址和用户
8. **监控系统活动**：设置日志监控和入侵检测系统

## 常见问题与解决方案

### 防火墙阻止了合法访问

- **问题**：防火墙规则阻止了合法的服务访问
- **解决方案**：
  - 检查防火墙规则：`sudo firewall-cmd --list-all`
  - 添加必要的服务或端口：`sudo firewall-cmd --permanent --add-service=http`
  - 重新加载防火墙：`sudo firewall-cmd --reload`

### SSH 连接被拒绝

- **问题**：无法通过 SSH 连接到服务器
- **解决方案**：
  - 检查 SSH 服务是否运行：`sudo systemctl status sshd`
  - 检查防火墙是否允许 SSH：`sudo firewall-cmd --list-services`
  - 检查 SSH 配置：`sudo vim /etc/ssh/sshd_config`
  - 检查是否被 Fail2ban 阻止：`sudo fail2ban-client status sshd`

### 密码太弱无法更改

- **问题**：系统拒绝设置新密码，提示密码太弱
- **解决方案**：
  - 检查密码策略配置：`sudo vim /etc/security/pwquality.conf`
  - 使用更复杂的密码，包含大小写字母、数字和特殊字符
  - 临时放宽密码策略（不推荐）：修改 `minlen` 和 `minclass` 等参数

## 总结

防火墙和安全配置是 Rocky Linux 系统管理中的重要部分。通过本文介绍的方法，您可以配置 firewalld 防火墙以保护系统免受网络攻击，同时实施各种安全加固措施来提高系统的整体安全性。

记住，安全是一个持续的过程，需要定期更新系统、审查安全配置、监控系统活动，并及时响应安全威胁。遵循安全最佳实践，可以大大降低系统被攻击的风险。
