安全网络
对红帽文档提供反馈 复制链接链接已复制到粘贴板!
我们感谢您对我们文档的反馈。让我们了解如何改进它。
通过 Jira 提交反馈(需要帐户)
- 登录到 Jira 网站。
- 单击顶部导航栏中的 Create。
- 在 Summary 字段中输入描述性标题。
- 在 Description 字段中输入您对改进的建议。包括文档相关部分的链接。
- 点对话框底部的 Create。
第 1 章 使用 OpenSSH 的两个系统间使用安全通讯 复制链接链接已复制到粘贴板!
SSH(Secure Shell)是一种协议,它使用客户端-服务器架构在两个系统之间提供安全通信,并允许用户远程登录到服务器主机系统。与其他远程通信协议(如 FTP 或 Telnet )不同,SSH 会加密登录会话,这可防止入侵者从连接中收集未加密的密码。
1.1. SSH 和 OpenSSH 复制链接链接已复制到粘贴板!
SSH(安全 Shell)是一个登录远程机器并在该机器上执行命令的程序。SSH 协议通过不安全的网络在两个不可信主机间提供安全加密的通讯。您还可以通过安全频道转发 X11 连接和任意 TCP/IP 端口。
当使用 SSH 协议进行远程 shell 登录或文件复制时,SSH 协议可以缓解威胁,例如,拦截两个系统之间的通信和模拟特定主机。这是因为 SSH 客户端和服务器使用数字签名来验证其身份。另外,所有客户端和服务器系统之间的沟通都是加密的。
主机密钥验证使用 SSH 协议的主机。当 OpenSSH 首次启动或当主机首次引导时,主机密钥是自动生成的加密密钥。
OpenSSH 是 Linux、UNIX 和类似操作系统支持的 SSH 协议的实现。它包括 OpenSSH 客户端和服务器需要的核心文件。OpenSSH 组件由以下用户空间工具组成:
-
ssh
是一个远程登录程序(SSH 客户端). -
sshd
是一个 OpenSSH SSH 守护进程。 -
scp
是一个安全的远程文件复制程序。 -
sftp
是一个安全的文件传输程序。 -
ssh-agent
是用于缓存私钥的身份验证代理。 -
ssh-add
为ssh-agent
添加私钥身份。 -
ssh-keygen
生成、管理并转换ssh
验证密钥。 -
ssh-copy-id
是一个将本地公钥添加到远程 SSH 服务器上的authorized_keys
文件中的脚本。 -
ssh-keyscan
可以收集 SSH 公共主机密钥。
RHEL 中的 OpenSSH 套件仅支持 SSH 版本 2。它有一个增强的密钥交换算法,其不会受到旧版本 1 中已知漏洞的攻击。
Red Hat Enterprise Linux 包括以下 OpenSSH
软件包:常规 openssh
软件包、openssh-server
软件包和 openssh-clients
软件包。OpenSSH
软件包需要 OpenSSL
软件包 openssl-libs
,它会安装几个重要的使 OpenSSH
可以提供加密通信的加密库。
OpenSSH 作为 RHEL 的核心加密子系统之一,使用系统范围的加密策略。这样可确保在默认配置中禁用弱密码套件和加密算法。要修改策略,管理员必须使用 update-crypto-policies
命令来调整设置,或者手动选择不使用系统范围的加密策略。如需更多信息,请参阅 从以下系统范围加密策略中排除一个应用程序 部分。
OpenSSH 套件使用两组配置文件:一个用于客户端程序(即 ssh
、scp
和 sftp
),另一个用于服务器( sshd
守护进程)。
系统范围的 SSH 配置信息保存在 /etc/ssh/
目录中。/etc/ssh/ssh_config
文件包含客户端配置,/etc/ssh/sshd_config
文件是默认的 OpenSSH 服务器配置文件。
用户特定的 SSH 配置信息保存在用户主目录中的 ~/.ssh/
中。有关 OpenSSH 配置文件的详细的列表,请查看您系统上 sshd (8)
手册页中的 FILES
部分。
1.2. 生成 SSH 密钥对 复制链接链接已复制到粘贴板!
您可以使用在本地系统上生成的 SSH 密钥对,并将生成的公钥复制到 OpenSSH 服务器来在不输入密码的情况下登录到 OpenSSH 服务器。每个要创建密钥的用户都必须运行此流程。
要在重新安装系统后保留之前生成的密钥对,请在创建新密钥前备份 ~/.ssh/
目录。重新安装后,将其复制到主目录中。您可以为系统中的所有用户(包括 root
用户)进行此操作。
先决条件
- 您已经以希望使用密钥连接到 OpenSSH 服务器的用户的身份登录了。
- OpenSSH 服务器被配置为允许基于密钥的身份验证。
流程
生成一个 ECDSA 密钥对:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您还可以使用没有任何参数的
ssh-keygen
命令生成一个 RSA 密钥对,或通过输入ssh-keygen -t ed25519
命令生成一个 Ed25519 密钥对。请注意,Ed25519 算法不符合 FIPS-140,OpenSSH 在 FIPS 模式下无法使用 Ed25519 密钥。将公钥复制到远程机器上:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
<username>@<ssh-server-example.com>
替换为您的凭证。如果您没有在会话中使用
ssh-agent
程序,上一个命令会复制最新修改的~/.ssh/id*.pub
公钥。要指定另一个公钥文件,或在ssh-agent
内存中缓存的密钥优先选择文件中的密钥,使用带有-i
选项的ssh-copy-id
命令。
验证
使用密钥文件登录到 OpenSSH 服务器:
ssh -o PreferredAuthentications=publickey <username>@<ssh-server-example.com>
$ ssh -o PreferredAuthentications=publickey <username>@<ssh-server-example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3. 将基于密钥的身份验证设置为 OpenSSH 服务器的唯一方法 复制链接链接已复制到粘贴板!
要提高系统安全性,通过在 OpenSSH 服务器上禁用密码身份验证来强制进行基于密钥的身份验证。
先决条件
-
已安装
openssh-server
软件包。 -
sshd
守护进程正在服务器中运行。 您已使用密钥连接到 OpenSSH 服务器。
详情请参阅 生成 SSH 密钥对 部分。
流程
在文本编辑器中打开
/etc/ssh/sshd_config
配置,例如:vi /etc/ssh/sshd_config
# vi /etc/ssh/sshd_config
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
PasswordAuthentication
选项改为no
:PasswordAuthentication no
PasswordAuthentication no
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
在不是新默认安装的系统上,检查是否设置了
PubkeyAuthentication
参数,或是否设置为yes
。 将
ChallengeResponseAuthentication
指令设置为no
。请注意,相应的条目在配置文件中已被注释掉,默认值为
yes
。要在 NFS 挂载的主目录中使用基于密钥的验证,启用
use_nfs_home_dirs
SELinux 布尔值:setsebool -P use_nfs_home_dirs 1
# setsebool -P use_nfs_home_dirs 1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 如果您要进行远程连接,而不使用控制台或带外访问,在禁用密码验证前测试基于密钥的登录过程。
重新载入
sshd
守护进程以应用更改:systemctl reload sshd
# systemctl reload sshd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.4. 使用 ssh-agent 缓存 SSH 凭证 复制链接链接已复制到粘贴板!
为了避免在每次发起 SSH 连接时输入密码短语,您可以使用 ssh-agent
工具为登录会话缓存 SSH 私钥。如果代理正在运行,并且您的密钥已解锁,您可以使用这些密钥登录到 SSH 服务器,但不必再次输入密钥的密码。确保私钥和密语安全。
先决条件
- 您有一个运行了 SSH 守护进程的远程主机,并可通过网络访问。
- 您知道登录到远程主机的 IP 地址或者主机名以及凭证。
您已用密码生成了 SSH 密钥对,并将公钥传送到远程机器。
详情请参阅 生成 SSH 密钥对 部分。
流程
将在您的会话中自动启动
ssh-agent
的命令添加到~/.bashrc
文件中:在您选择的文本编辑器中打开
~/.bashrc
,例如:vi ~/.bashrc
$ vi ~/.bashrc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在文件中添加以下行:
eval $(ssh-agent)
eval $(ssh-agent)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 保存更改,退出编辑器。
在
~/.ssh/config
文件中添加以下行:AddKeysToAgent yes
AddKeysToAgent yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用此选项并在会话中启动了
ssh-agent
,代理仅在您第一次连接到主机时提示输入密码。
验证
登录到使用代理中缓存的私钥的对应的公钥的主机,例如:
ssh <example.user>@<ssh-server@example.com>
$ ssh <example.user>@<ssh-server@example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意您不必输入密码短语。
1.5. 通过保存在智能卡上的 SSH 密钥进行身份验证 复制链接链接已复制到粘贴板!
您可以在智能卡上创建并存储 ECDSA 和 RSA 密钥,并通过 OpenSSH 客户端上的智能卡进行身份验证。智能卡验证替换了默认密码验证。
先决条件
-
在客户端中安装了
opensc
软件包,pcscd
服务正在运行。
流程
列出所有由 OpenSC PKCS #11 模块提供的密钥,包括其 PKCS #11 URIs,并将输出保存到
key.pub
文件:ssh-keygen -D pkcs11: > keys.pub
$ ssh-keygen -D pkcs11: > keys.pub
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将公钥传送到远程服务器。使用
ssh-copy-id
命令和上一步中创建的keys.pub
文件:ssh-copy-id -f -i keys.pub <username@ssh-server-example.com>
$ ssh-copy-id -f -i keys.pub <username@ssh-server-example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 ECDSA 密钥连接到 <ssh-server-example.com>。您可以只使用 URI 的子集,它唯一引用您的密钥,例如:
ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" <ssh-server-example.com>
$ ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 因为 OpenSSH 使用
p11-kit-proxy
包装器,且 OpenSC PKCS #11 模块已注册到p11-kit
工具,因此您可以简化上一个命令:ssh -i "pkcs11:id=%01" <ssh-server-example.com>
$ ssh -i "pkcs11:id=%01" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您跳过 PKCS #11 URI 的
id=
部分,则 OpenSSH 会加载代理模块中可用的所有密钥。这可减少输入所需的数量:ssh -i pkcs11: <ssh-server-example.com>
$ ssh -i pkcs11: <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:您可以在
~/.ssh/config
文件中使用同样的 URI 字符串来使配置持久:cat ~/.ssh/config IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" ssh <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
$ cat ~/.ssh/config IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" $ ssh <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ssh
客户端工具现在自动使用此 URI 和智能卡中的密钥。
1.6. 使 OpenSSH 更安全 复制链接链接已复制到粘贴板!
在使用 OpenSSH 时,您可以调整系统以提高安全性。
请注意,/etc/ssh/sshd_config
OpenSSH 服务器配置文件中的更改需要重新载入 sshd
守护进程才能生效:
systemctl reload sshd
# systemctl reload sshd
大多数安全强化配置更改会降低与不支持最新算法或密码套件的客户端的兼容性。
- 禁用不安全的连接协议
- 要使 SSH 生效,防止使用由 OpenSSH 套件替代的不安全连接协议。否则,用户的密码可能只会在一个会话中被 SSH 保护,可能会在以后使用 Telnet 登录时被捕获。
- 禁用基于密码的身份验证
- 禁用密码进行身份验证,并只允许密钥,以减少攻击面。如需更多信息,请参阅 将基于密钥的身份验证设置为 OpenSSH 服务器上的唯一方法 部分。
- 更强大的密钥类型
虽然
ssh-keygen
命令默认生成一对 RSA 密钥,但您可以使用-t
选项指示它生成 Elliptic Curve Digital Signature Algorithm (ECDSA)或 Edwards-Curve 25519 (Ed25519)密钥。同等对称密钥强度下,ECDSA 提供了比 RSA 更好的性能。它还会生成较短的密钥。Ed25519 公钥算法是 一种变形的 Edwards 曲线的实现,其比 RSA、DSA 和 ECDSA 更安全,也更快。如果没有这些密钥,OpenSSH 会自动创建 RSA、ECDSA 和 Ed25519 服务器主机密钥。要在 RHEL 中配置主机密钥创建,请使用
sshd-keygen@.service
实例化服务。例如,禁用自动创建 RSA 密钥类型:systemctl mask sshd-keygen@rsa.service rm -f /etc/ssh/ssh_host_rsa_key* systemctl restart sshd
# systemctl mask sshd-keygen@rsa.service # rm -f /etc/ssh/ssh_host_rsa_key* # systemctl restart sshd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意在启用了
cloud-init
方法的镜像中,ssh-keygen
单元被自动禁用。这是因为ssh-keygen template
服务可能会干扰cloud-init
工具,导致主机密钥生成出现问题。要防止这些问题,etc/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
置入配置文件禁用了ssh-keygen
单元(如果cloud-init
正在运行)。要只允许特定的密钥类型用于 SSH 连接,请删除
/etc/ssh/sshd_config
中相关行开头的注释,并重新加载sshd
服务。例如,要只允许 Ed25519 主机密钥,则相应的行必须如下所示:HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key
# HostKey /etc/ssh/ssh_host_rsa_key # HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要Ed25519 算法与 FIPS-140 不兼容,OpenSSH 在 FIPS 模式下无法与 Ed25519 密钥一起工作。
- 非默认端口
默认情况下,
sshd
守护进程侦听 TCP 端口 22。更改端口可降低系统暴露给基于自动网络扫描的攻击,从而通过隐蔽性提高了安全性。您可以使用/etc/ssh/sshd_config
配置文件中的Port
指令指定端口。您还必须更新默认 SELinux 策略以允许使用非默认端口。要做到这一点,使用
policycoreutils-python-utils
软件包中的semanage
工具:semanage port -a -t ssh_port_t -p tcp <port-number>
# semanage port -a -t ssh_port_t -p tcp <port-number>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 另外,更新
firewalld
配置:firewall-cmd --add-port <port-number>/tcp firewall-cmd --remove-port=22/tcp firewall-cmd --runtime-to-permanent
# firewall-cmd --add-port <port-number>/tcp # firewall-cmd --remove-port=22/tcp # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在前面的命令中,将 <port-number> 替换为使用
Port
指令指定的新端口号。- 没有 root 登录
如果您的特定用例不需要以 root 用户身份登录,您可以在
/etc/ssh/sshd_config
文件中将PermitRootLogin
配置指令设置为no
。通过禁止以 root 用户身份登录,管理员可以审核哪些用户在以普通用户身份登录后运行了哪些特权命令,然后获得了 root 权限。或者,将
PermitRootLogin
设置为prohibit-password
:PermitRootLogin prohibit-password
PermitRootLogin prohibit-password
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这强制使用基于密钥的身份验证,而不是使用密码以 root 身份登录,并通过防止暴力攻击来降低风险。
- 使用 X 安全性扩展
Red Hat Enterprise Linux 客户端中的 X 服务器不提供 X 安全性扩展。因此,当连接到带有 X11 转发的不可信 SSH 服务器时,客户端无法请求另一个安全层。大多数应用程序都无法在启用此扩展时运行。
默认情况下,
/etc/ssh/ssh_config.d/05-redhat.conf
文件中的ForwardX 11Trusted
选项被设置为yes
,且ssh -X remote_machine
(不信任主机)和ssh -Y remote_machine
(可信主机)命令之间没有区别。如果您的场景根本不需要 X11 转发功能,请将
/etc/ssh/sshd_config
配置文件中的X11Forwarding
指令设置为no
。- 限制 SSH 对特定用户、组或 IP 范围的访问
/etc/ssh/sshd_config
配置文件服务器中的AllowUsers
和AllowGroups
指令可让您只允许某些用户、域或组连接到您的 OpenSSH 服务器。您可以组合AllowUsers
和Allow Groups
来更准确地限制访问,例如:AllowUsers *@192.168.1.* *@10.0.0.* !*@192.168.1.2 AllowGroups example-group
AllowUsers *@192.168.1.* *@10.0.0.* !*@192.168.1.2 AllowGroups example-group
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此配置只在所有以下条件都满足时才允许连接:
- 连接的源 IP 在 192.168.1.0/24 或 10.0.0.0/24 子网中。
- 源 IP 不是 192.168.1.2。
- 用户是 example-group 组的成员。
OpenSSH 服务器仅允许
/etc/ssh/sshd_config
中通过所有 Allow 和 Deny 指令的连接。例如,如果AllowUsers
指令列出的用户不是AllowGroups
指令中列出的组的一部分,则用户无法登录。请注意,使用允许列表(以 Allow 开头的指令)比使用阻止列表(以 Deny 开始的选项)更安全,因为允许列表也会阻止新的未授权的用户或组。
- 更改系统范围的加密策略
OpenSSH 使用 RHEL 系统范围的加密策略,默认的系统范围的加密策略级别为当前威胁模型提供了安全设置。要使您的加密设置更严格,请更改当前的策略级别:
update-crypto-policies --set FUTURE
# update-crypto-policies --set FUTURE Setting system policy to FUTURE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 警告如果您的系统与旧系统进行通信,您可能会由于严格的
FUTURE
策略的设置而遇到互操作性问题。
您还可以通过系统范围的加密策略只为 SSH 协议禁用特定的密码。如需更多信息,请参阅安全强化文档中的 自定义带有子策略的系统范围的加密策略 部分。
- 选择不使用系统范围的加密策略
要为您的 OpenSSH 服务器选择不使用系统范围的加密策略,请在
/etc/sysconfig/sshd
文件中取消具有CRYPTO_POLICY=
变量的行的注释。更改后,您在/etc/ssh/sshd_config
文件中的Ciphers
、MAC
、KexAlgoritms
和GSSAPIKexAlgorithms
部分指定的值不会被覆盖。详情请查看
sshd_config(5)
手册页。要为您的 OpenSSH 客户端选择不使用系统范围的加密策略,请执行以下任务之一:
-
对于给定的用户,使用
~/.ssh/config
文件中特定于用户的配置覆盖全局ssh_config
。 -
对于整个系统,在
/etc/ssh/ssh_config.d/
目录中的置入配置文件中指定加密策略,使用小于 5 的两位数字前缀,以便其在字典顺序上位于05-redhat.conf
文件之前,并带有.conf
后缀,例如04-crypto-policy-override.conf
。
-
对于给定的用户,使用
1.7. 通过 SSH 跳板机连接到远程服务器 复制链接链接已复制到粘贴板!
您可以通过中间服务器(也称为跳板机)从本地系统连接到远程服务器。跳板服务器连接来自不同安全区域的主机,并可以管理多个客户端-服务器连接。
先决条件
- 跳过主机接受来自本地系统的 SSH 连接。
- 远程服务器接受来自跳板机的 SSH 连接。
流程
如果您一次通过跳板服务器或多个中间服务器进行连接,请使用
ssh -J
命令,并直接指定跳板服务器,例如:ssh -J <jump-1.example.com>,<jump-2.example.com>,<jump-3.example.com> <target-server-1.example.com>
$ ssh -J <jump-1.example.com>,<jump-2.example.com>,<jump-3.example.com> <target-server-1.example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果跳板服务器上的用户名或 SSH 端口与远程服务器上的用户名和端口不同,请只修改上一命令中的主机名表示法,例如:
ssh -J <example.user.1>@<jump-1.example.com>:<75>,<example.user.2>@<jump-2.example.com>:<75>,<example.user.3>@<jump-3.example.com>:<75> <example.user.f>@<target-server-1.example.com>:<220>
$ ssh -J <example.user.1>@<jump-1.example.com>:<75>,<example.user.2>@<jump-2.example.com>:<75>,<example.user.3>@<jump-3.example.com>:<75> <example.user.f>@<target-server-1.example.com>:<220>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您定期通过跳板服务器连接到远程服务器,请在 SSH 配置文件中存储 jump-server 配置:
通过编辑本地系统中的
~/.ssh/config
文件来定义跳板主机,例如:Host <jump-server-1> HostName <jump-1.example.com>
Host <jump-server-1> HostName <jump-1.example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Host
参数定义您可以在ssh
命令中使用的主机的名称或别名。该值可以匹配真实的主机名,但也可以是任意字符串。 -
HostName
参数设置跳过主机的实际主机名或 IP 地址。
-
使用
ProxyJump
指令将远程服务器跳板配置添加到本地系统上的~/.ssh/config
文件中,例如:Host <remote-server-1> HostName <target-server-1.example.com> ProxyJump <jump-server-1>
Host <remote-server-1> HostName <target-server-1.example.com> ProxyJump <jump-server-1>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用您的本地系统通过跳过服务器连接到远程服务器:
ssh <remote-server-1>
$ ssh <remote-server-1>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果省略之前的配置步骤,此命令等同于
ssh -J jump-server1 remote-server
命令。
1.8. 使用 ssh 系统角色配置安全通信 复制链接链接已复制到粘贴板!
作为管理员,您可以使用 sshd
系统角色配置 SSH 服务器,并使用 ssh
系统角色,通过使用 Red Hat Ansible Automation Platform 同时在任意数量的 RHEL 系统上配置 SSH 客户端。
1.8.1. sshd RHEL 系统角色如何将 playbook 中的设置映射到配置文件 复制链接链接已复制到粘贴板!
在 sshd
RHEL 系统角色 playbook 中,您可以为服务器 SSH 配置文件定义参数。
如果没有指定这些设置,角色会生成一个与 RHEL 默认值匹配的 sshd_config
文件。
在所有情况下,布尔值会在受管节点上的最终配置中正确呈现为 yes
和 no
。您可以使用列表来定义多行配置项。例如:
sshd_ListenAddress: - 0.0.0.0 - '::'
sshd_ListenAddress:
- 0.0.0.0
- '::'
呈现为:
ListenAddress 0.0.0.0 ListenAddress ::
ListenAddress 0.0.0.0
ListenAddress ::
1.8.2. 使用 sshd RHEL 系统角色配置 OpenSSH 服务器 复制链接链接已复制到粘贴板!
您可以使用 sshd
RHEL 系统角色配置多个 OpenSSH 服务器。这些措施通过以下方式来确保远程用户的安全通信环境:
- 管理来自远程客户端的传入 SSH 连接
- 凭证验证
- 保护数据传输和命令执行
您可以将 sshd
RHEL 系统角色与其他更改 SSHD 配置的 RHEL 系统角色(如 Identity Management RHEL 系统角色)一起使用。要防止配置被覆盖,请确保 sshd
RHEL 系统角色使用命名空间(RHEL 8 及更早版本)或置入目录(RHEL 9)。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
PasswordAuthentication: yes|no
-
控制 OpenSSH 服务器(
sshd
)是否接受来自使用用户名和密码组合的客户端的身份验证。 Match:
-
匹配块只允许使用来自子网
192.0.2.0/24
的使用密码的root
用户登录。
有关 playbook 中使用的角色变量和 OpenSSH 配置选项的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.sshd/README.md
文件和sshd_config (5)
手册页。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
登录到 SSH 服务器:
ssh <username>@<ssh_server>
$ ssh <username>@<ssh_server>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 验证 SSH 服务器上
sshd_config
文件的内容:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 检查您是否可以以 root 用户身份从
192.0.2.0/24
子网连接到服务器:确定您的 IP 地址:
hostname -I
$ hostname -I 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果 IP 地址在
192.0.2.1
-192.0.2.254
范围内,您可以连接到服务器。以
root
用户身份连接到服务器:ssh root@<ssh_server>
$ ssh root@<ssh_server>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.8.3. ssh RHEL 系统角色如何将 playbook 中的设置映射到配置文件 复制链接链接已复制到粘贴板!
在 ssh
RHEL 系统角色 playbook 中,您可以为客户端 SSH 配置文件定义参数。
如果没有指定这些设置,角色会生成一个与 RHEL 默认值匹配的全局 ssh_config
文件。
在所有情况下,布尔值在受管节点上的最终配置中正确呈现为 yes
或 no
。您可以使用列表来定义多行配置项。例如:
LocalForward: - 22 localhost:2222 - 403 localhost:4003
LocalForward:
- 22 localhost:2222
- 403 localhost:4003
呈现为:
LocalForward 22 localhost:2222 LocalForward 403 localhost:4003
LocalForward 22 localhost:2222
LocalForward 403 localhost:4003
配置选项区分大小写。
1.8.4. 使用 ssh RHEL 系统角色配置 OpenSSH 客户端 复制链接链接已复制到粘贴板!
您可以使用 ssh
RHEL 系统角色配置多个 OpenSSH 客户端。这些措施可通过确保以下内容让本地用户与远程 OpenSSH 服务器建立一个安全连接:
- 安全连接启动
- 凭证置备
- 与 OpenSSH 服务器协商有关用于安全通信渠道的加密方法
- 能够安全地向和从 OpenSSH 服务器发送文件
您可以将 ssh
RHEL 系统角色与更改 SSH 配置的其他系统角色(如 Identity Management RHEL 系统角色)一起使用。要防止配置被覆盖,请确保 ssh
RHEL 系统角色使用置入目录(RHEL 8 及更高版本中的默认设置)。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
ssh_user: root
-
使用特定配置在受管节点上配置
root
用户的 SSH 客户端首选项。 Compression: true
- 压缩被启用。
ControlMaster: auto
-
ControlMaster 多路复用设置为
auto
。 Host
-
创建别名
example
,来以名为user1
的用户身份连接到server.example.com
主机。 ssh_ForwardX11: no
- X11 转发被禁用。
有关 playbook 中使用的角色变量和 OpenSSH 配置选项的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.ssh/README.md
文件和ssh_config (5)
手册页。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
通过显示 SSH 配置文件来验证受管节点是否有正确的配置:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.8.5. 将 sshd RHEL 系统角色用于非独占配置 复制链接链接已复制到粘贴板!
默认情况下,应用 sshd
RHEL 系统角色会覆盖整个配置。如果您之前调整了配置,例如使用不同的 RHEL 系统角色或 playbook,则这可能会出现问题。要只对所选配置选项应用 sshd
RHEL 系统角色,同时保留其他选项,您可以使用非独占配置。
您可以应用非独占配置:
- 在 RHEL 8 及更早版本中使用配置片段。
-
在 RHEL 9 及更高版本中使用置入目录中的文件。默认配置文件已放入随时可访问的目录中,存为
/etc/ssh/sshd_config.d/00-ansible_system_role.conf
。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:对于运行 RHEL 8 或更早版本的受管节点:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对于运行 RHEL 9 或更高版本的受管节点:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括以下内容:
sshd_config_namespace: <my-application>
- 角色将您在 playbook 中指定的配置放在给定命名空间下的现有配置文件中的配置片段中。当从不同上下文运行角色时,您需要选择一个不同的命名空间。
sshd_config_file: /etc/ssh/sshd_config.d/<42-my-application>.conf
-
在
sshd_config_file
变量中,定义sshd
系统角色将配置选项写入其中的.conf
文件。使用两位前缀,例如42-
来指定应用配置文件的顺序。 AcceptEnv:
控制 OpenSSH 服务器(
sshd
)将接受来自客户端的哪些环境变量:-
LANG
:定义语言和区域设置。 -
LS_COLORS
:定义终端中ls
命令的显示颜色方案。 -
EDITOR
: 指定需要打开编辑器的命令行程序的默认文本编辑器。
-
有关 playbook 中使用的角色变量和 OpenSSH 配置选项的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.sshd/README.md
文件和sshd_config (5)
手册页。
验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证 SSH 服务器上的配置:
对于运行 RHEL 8 或更早版本的受管节点:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对于运行 RHEL 9 或更高版本的受管节点:
cat /etc/ssh/sshd_config.d/42-my-application.conf Ansible managed # AcceptEnv LANG LS_COLORS EDITOR
# cat /etc/ssh/sshd_config.d/42-my-application.conf # Ansible managed # AcceptEnv LANG LS_COLORS EDITOR
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
第 2 章 创建并管理 TLS 密钥和证书 复制链接链接已复制到粘贴板!
您可以使用 TLS (传输层安全)协议加密在两个系统间传输的通信。此标准将非对称加密与私钥和公钥、数字签名和证书一起使用。
2.1. TLS 证书 复制链接链接已复制到粘贴板!
TLS (传输层安全)是一种协议,它允许客户端-服务器应用程序安全地传递信息。TLS 使用公钥和私钥对系统来加密在客户端和服务器间传输的通信。TLS 是到 SSL (安全套接字层)的后继协议。
TLS 使用 X.509 证书将主机名或机构等身份绑定到使用数字签名的公共密钥。X.509 是一个定义公钥证书格式的标准。
安全应用程序的身份验证取决于应用证书中公钥值的完整性。如果攻击者用自己的公钥替换了公钥,则它可以模拟真正的应用程序,并获得对安全数据的访问权限。为防止此类攻击,所有证书都必须由证书颁发机构(CA)签名。CA 是一个可信节点,用于确认证书中公钥值的完整性。
CA 通过添加公钥签名并发布证书来签署公钥。数字签名是用 CA 的私钥编码的一条消息。通过分发 CA 的证书,CA 的公钥可供应用程序使用。应用程序使用 CA 的公钥解码 CA 的数字签名来验证证书是否为有效签名。
要让证书由 CA 签名,您必须生成一个公钥,并将其发送给 CA 进行签名。这称为证书签名请求(CSR)。CSR 也包含证书的可分辨名称(DN)。您可以为任一证书提供的 DN 信息可以包括您所在国家的两字母国家代码、州或省、城市或乡镇的全名,您机构的名称、电子邮件地址,也可以为空。许多当前商业 CA 首选 Subject Alternative Name 扩展,并在 CSR 中忽略 DN。
RHEL 为使用 TLS 证书提供了两个主要工具包:GnuTLS 和 OpenSSL。您可以使用 openssl
软件包中的 openssl
工具创建、读取、签名和验证证书。gnutls-utils
软件包提供的 certtool
工具可以使用不同的语法以及后端中的所有不同库的集合执行相同的操作。
2.2. 使用 OpenSSL 创建私有 CA 复制链接链接已复制到粘贴板!
当您的情况需要在您的内部网络内验证实体时,私有证书颁发机构(CA)非常有用。例如,当使用基于您控制下的 CA 签名的证书的身份验证创建 VPN 网关时,或者您不想支付商业 CA 时,请使用私有 CA。要在这样的用例中签名证书,私有 CA 使用自签名证书。
前提条件
-
您有
root
权限或使用sudo
输入管理命令的权限。需要此类权限的命令标记为#
。
流程
为您的 CA 生成私钥。例如,以下命令会创建一个 256 位 Elliptic Curve Digital Signature Algorithm(ECDSA)密钥:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <ca.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 密钥生成过程的时间取决于主机的硬件和熵、所选算法以及密钥长度。
使用上一个命令生成的私钥创建证书:
openssl req -key <ca.key> -new -x509 -days 3650 -addext keyUsage=critical,keyCertSign,cRLSign -subj "/CN=<Example_CA>" -out <ca.crt>
$ openssl req -key <ca.key> -new -x509 -days 3650 -addext keyUsage=critical,keyCertSign,cRLSign -subj "/CN=<Example_CA>" -out <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 生成的
ca.crt
文件是一个自签名 CA 证书,可用来为其他证书签名 10 年。对于私有 CA,您可以将 < Example_CA> 替换为作为通用名称(CN)的任何字符串。对 CA 的私钥设置安全权限,例如:
chown <root>:<root> <ca.key> chmod 600 <ca.key>
# chown <root>:<root> <ca.key> # chmod 600 <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
要将自签名 CA 证书用作客户端系统上的信任锚,请将 CA 证书复制到客户端,并以
root
用户身份将其添加到客户端的系统范围信任存储中:trust anchor <ca.crt>
# trust anchor <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请参阅 第 3 章 使用共享的系统证书 了解更多信息。
验证
创建证书签名请求(CSR),并使用您的 CA 为请求签名。CA 必须成功创建一个基于 CSR 的证书,例如:
openssl x509 -req -in <client-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <client-cert> -out <client-cert.crt>
$ openssl x509 -req -in <client-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <client-cert> -out <client-cert.crt> Signature ok subject=C = US, O = Example Organization, CN = server.example.com Getting CA Private Key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请参阅 第 2.5 节 “使用私有 CA 使用 OpenSSL 为 CSR 发布证书” 了解更多信息。
显示有关自签名 CA 的基本信息:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 验证私钥的一致性:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3. 使用 OpenSSL 为 TLS 服务器证书创建私钥和 CSR 复制链接链接已复制到粘贴板!
您只有有了来自证书颁发机构(CA)的有效 TLS 证书时才可以使用 TLS 加密的通信频道。要获取证书,您必须首先为您的服务器创建私钥和证书签名请求(CSR)。
流程
在服务器系统上生成私钥,例如:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <server-private.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <server-private.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:使用您选择的文本编辑器,来准备一个简化创建 CSR 的配置文件,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow extendedKeyUsage = serverAuth
选项限制证书的使用。使用之前创建的私钥创建 CSR:
openssl req -key <server-private.key> -config <example_server.cnf> -new -out <server-cert.csr>
$ openssl req -key <server-private.key> -config <example_server.cnf> -new -out <server-cert.csr>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果省略了
-config
选项,req
工具会提示您额外的信息,例如:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
- 将 CSR 提交给您选择的 CA 进行签名。或者,对于可信网络中的内部使用场景,请使用您的私有 CA 进行签名。请参阅 第 2.5 节 “使用私有 CA 使用 OpenSSL 为 CSR 发布证书” 了解更多信息。
验证
从 CA 获取请求的证书后,检查证书的人类可读部分是否与您的要求匹配,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4. 使用 OpenSSL 为 TLS 客户端证书创建私钥和 CSR 复制链接链接已复制到粘贴板!
您只有有了来自证书颁发机构(CA)的有效 TLS 证书时才可以使用 TLS 加密的通信频道。要获取证书,您必须首先为您的客户端创建私钥和证书签名请求(CSR)。
流程
在客户端系统上生成私钥,例如:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <client-private.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <client-private.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:使用您选择的文本编辑器,来准备一个简化创建 CSR 的配置文件,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow extendedKeyUsage = clientAuth
选项限制证书的使用。使用之前创建的私钥创建 CSR:
openssl req -key <client-private.key> -config <example_client.cnf> -new -out <client-cert.csr>
$ openssl req -key <client-private.key> -config <example_client.cnf> -new -out <client-cert.csr>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果省略了
-config
选项,req
工具会提示您额外的信息,例如:You are about to be asked to enter information that will be incorporated into your certificate request. … Common Name (eg, your name or your server's hostname) []: <client.example.com> Email Address []: <client@example.com>
You are about to be asked to enter information that will be incorporated into your certificate request. … Common Name (eg, your name or your server's hostname) []: <client.example.com> Email Address []: <client@example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
- 将 CSR 提交给您选择的 CA 进行签名。或者,对于可信网络中的内部使用场景,请使用您的私有 CA 进行签名。请参阅 第 2.5 节 “使用私有 CA 使用 OpenSSL 为 CSR 发布证书” 了解更多信息。
验证
检查证书的人类可读部分是否与您的要求匹配,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.5. 使用私有 CA 使用 OpenSSL 为 CSR 发布证书 复制链接链接已复制到粘贴板!
要让系统建立一条 TLS 加密的通信频道,证书颁发机构(CA)必须为它们提供有效的证书。如果您有私有 CA,您可以通过从系统签署证书签名请求(CSR)来创建请求的证书。
前提条件
- 您已配置了私有 CA。如需更多信息,请参阅使用 OpenSSL 创建私有 CA 部分。
- 您有一个包含 CSR 的文件。您可以在 第 2.3 节 “使用 OpenSSL 为 TLS 服务器证书创建私钥和 CSR” 部分找到创建 CSR 的示例。
流程
可选:使用您选择的文本编辑器,来准备一个 OpenSSL 配置文件,以便向证书添加扩展,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,上例仅演示了原则,且
openssl
不会将所有扩展自动添加到证书中。您必须将所需的扩展添加到 CNF 文件中,或者将它们附加到openssl
命令的参数中。使用
x509
工具创建基于 CSR 的证书,例如:openssl x509 -req -in <server-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <server-cert> -out <server-cert.crt>
$ openssl x509 -req -in <server-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <server-cert> -out <server-cert.crt> Signature ok subject=C = US, O = Example Organization, CN = server.example.com Getting CA Private Key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要提高安全性,请在从 CSR 创建另一个证书前删除序列号文件。这样,您确保序列号始终是随机的。如果您省略了指定自定义文件名的
CAserial
选项,则序列号文件名与证书的文件名相同,但其扩展名被.srl
扩展名替换(上例中的server-cert.srl
)。
2.6. 使用 GnuTLS 创建私有 CA 复制链接链接已复制到粘贴板!
当您的情况需要在您的内部网络内验证实体时,私有证书颁发机构(CA)非常有用。例如,当使用基于您控制下的 CA 签名的证书的身份验证创建 VPN 网关时,或者您不想支付商业 CA 时,请使用私有 CA。要在这样的用例中签名证书,私有 CA 使用自签名证书。
前提条件
-
您有
root
权限或使用sudo
输入管理命令的权限。需要此类权限的命令标记为#
。 您已在系统上安装了 GnuTLS。如果没有,您可以使用这个命令:
yum install gnutls-utils
$ yum install gnutls-utils
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
流程
为您的 CA 生成私钥。例如,以下命令会创建一个 256 位 ECDSA (Elliptic Curve Digital Signature Algorithm)密钥:
certtool --generate-privkey --sec-param High --key-type=ecdsa --outfile <ca.key>
$ certtool --generate-privkey --sec-param High --key-type=ecdsa --outfile <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 密钥生成过程的时间取决于主机的硬件和熵、所选算法以及密钥长度。
为证书创建一个模板文件。
使用您选择的文本编辑器创建一个文件,例如:
vi <ca.cfg>
$ vi <ca.cfg>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 编辑文件以包含必要的认证详情:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
使用在第 1 步中生成的私钥创建一个签名的证书:
生成的 <ca.crt> 文件是一个自签名 CA 证书,可用于为其他证书签名一年。<ca.crt> 文件是公钥(证书)。加载的文件 <ca.key> 是私钥。您应该将此文件保存在安全的地方。
certtool --generate-self-signed --load-privkey <ca.key> --template <ca.cfg> --outfile <ca.crt>
$ certtool --generate-self-signed --load-privkey <ca.key> --template <ca.cfg> --outfile <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对 CA 的私钥设置安全权限,例如:
chown <root>:<root> <ca.key> chmod 600 <ca.key>
# chown <root>:<root> <ca.key> # chmod 600 <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
要将自签名 CA 证书用作客户端系统上的信任锚,请将 CA 证书复制到客户端,并以
root
用户身份将其添加到客户端的系统范围信任存储中:trust anchor <ca.crt>
# trust anchor <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请参阅 第 3 章 使用共享的系统证书 了解更多信息。
验证
显示有关自签名 CA 的基本信息:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建证书签名请求(CSR),并使用您的 CA 为请求签名。CA 必须成功创建一个基于 CSR 的证书,例如:
为您的 CA 生成一个私钥:
certtool --generate-privkey --outfile <example-server.key>
$ certtool --generate-privkey --outfile <example-server.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在您选择的文本编辑器中打开一个新配置文件,例如:
vi <example-server.cfg>
$ vi <example-server.cfg>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 编辑文件以包含必要的认证详情:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用之前创建的私钥生成一个请求:
certtool --generate-request --load-privkey <example-server.key> --template <example-server.cfg> --outfile <example-server.crq>
$ certtool --generate-request --load-privkey <example-server.key> --template <example-server.cfg> --outfile <example-server.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 生成证书并使用 CA 的私钥对其签名:
certtool --generate-certificate --load-request <example-server.crq> --load-ca-certificate <ca.crt> --load-ca-privkey <ca.key> --outfile <example-server.crt>
$ certtool --generate-certificate --load-request <example-server.crq> --load-ca-certificate <ca.crt> --load-ca-privkey <ca.key> --outfile <example-server.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.7. 使用 GnuTLS 为 TLS 服务器证书创建私钥和 CSR 复制链接链接已复制到粘贴板!
要获取证书,您必须首先为您的服务器创建私钥和证书签名请求(CSR)。
流程
在服务器系统上生成私钥,例如:
certtool --generate-privkey --sec-param High --outfile <example-server.key>
$ certtool --generate-privkey --sec-param High --outfile <example-server.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:使用您选择的文本编辑器,来准备一个简化创建 CSR 的配置文件,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用之前创建的私钥创建 CSR:
certtool --generate-request --template <example-server.cfg> --load-privkey <example-server.key> --outfile <example-server.crq>
$ certtool --generate-request --template <example-server.cfg> --load-privkey <example-server.key> --outfile <example-server.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果省略
--template
选项,certool
工具会提示您输入额外的信息,例如:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
- 将 CSR 提交给您选择的 CA 进行签名。或者,对于可信网络中的内部使用场景,请使用您的私有 CA 进行签名。如需更多信息,请参阅使用私有 CA 为带有 GnuTLS 的 CSR 发布证书 部分。
验证
从 CA 获取请求的证书后,检查证书的人类可读部分是否与您的要求匹配,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.8. 使用 GnuTLS 为 TLS 客户端证书创建私钥和 CSR 复制链接链接已复制到粘贴板!
要获取证书,您必须首先为您的客户端创建私钥和证书签名请求(CSR)。
流程
在客户端系统中生成私钥,例如:
certtool --generate-privkey --sec-param High --outfile <example-client.key>
$ certtool --generate-privkey --sec-param High --outfile <example-client.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:使用您选择的文本编辑器准备一个简化创建 CSR 的配置文件,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用之前创建的私钥创建 CSR:
certtool --generate-request --template <example-client.cfg> --load-privkey <example-client.key> --outfile <example-client.crq>
$ certtool --generate-request --template <example-client.cfg> --load-privkey <example-client.key> --outfile <example-client.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果省略
--template
选项certtool
工具会提示您输入额外的信息,例如:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
- 将 CSR 提交给您选择的 CA 以签名。或者,对于可信网络中的内部使用场景,请使用您的私有 CA 进行签名。请参阅 第 2.9 节 “使用私有 CA ,使用 GnuTLS 为 CSR 发布证书” 了解更多信息。
验证
检查证书人类可读的部分是否与您的要求匹配,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.9. 使用私有 CA ,使用 GnuTLS 为 CSR 发布证书 复制链接链接已复制到粘贴板!
要让系统建立 TLS 加密通信频道,证书颁发机构(CA)必须为它们提供有效的证书。如果您有私有 CA,您可以通过从系统签署证书签名请求(CSR)来创建请求的证书。
前提条件
- 您已配置了私有 CA。请参阅 第 2.6 节 “使用 GnuTLS 创建私有 CA” 了解更多信息。
- 您有一个包含 CSR 的文件。您可以在 第 2.7 节 “使用 GnuTLS 为 TLS 服务器证书创建私钥和 CSR” 中找到创建 CSR 的示例。
流程
可选:使用您选择的文本编辑器准备 GnuTLS 配置文件,来为证书添加扩展,例如:
vi <server-extensions.cfg>
$ vi <server-extensions.cfg> honor_crq_extensions ocsp_uri = "http://ocsp.example.com"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
certtool
工具创建基于 CSR 的证书,例如:certtool --generate-certificate --load-request <example-server.crq> --load-ca-privkey <ca.key> --load-ca-certificate <ca.crt> --template <server-extensions.cfg> --outfile <example-server.crt>
$ certtool --generate-certificate --load-request <example-server.crq> --load-ca-privkey <ca.key> --load-ca-certificate <ca.crt> --template <server-extensions.cfg> --outfile <example-server.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
第 4 章 计划并使用 TLS 复制链接链接已复制到粘贴板!
TLS(传输层安全)是用来保护网络通信的加密协议。在通过配置首选密钥交换协议、身份验证方法和加密算法来强化系统安全设置时,需要记住支持的客户端的范围越广,产生的安全性就越低。相反,严格的安全设置会导致与客户端的兼容性受限,这可能导致某些用户被锁定在系统之外。请确保以最严格的可用配置为目标,并且仅在出于兼容性原因需要时才放宽配置。
4.1. SSL 和 TLS 协议 复制链接链接已复制到粘贴板!
安全套接字层(SSL)协议最初使由 Netscape 公司开发的,以提供一种在互联网上进行安全通信的机制。因此,该协议被互联网工程任务组(IETF)采纳,并重命名为传输层安全(TLS)。
TLS 协议位于应用协议层和可靠的传输层之间,例如 TCP/IP。它独立于应用程序协议,因此可在很多不同的协议下分层,如 HTTP、FTP、SMTP 等等。
协议版本 | 用法建议 |
---|---|
SSL v2 | 不要使用。具有严重的安全漏洞。从 RHEL 7 开始从核心加密库中删除了。 |
SSL v3 | 不要使用。具有严重的安全漏洞。从 RHEL 8 开始从核心加密库中删除了。 |
TLS 1.0 |
不建议使用。已知的无法以保证互操作性方式缓解的问题,且不支持现代密码套件。在 RHEL 8 中,只在 |
TLS 1.1 |
在需要时用于互操作性.不支持现代加密套件。在 RHEL 8 中,只在 |
TLS 1.2 | 支持现代 AEAD 密码组合。此版本在所有系统范围的加密策略中启用,但此协议的可选部分包含漏洞,TLS 1.2 也允许过时的算法。 |
TLS 1.3 | 推荐的版本。TLS 1.3 删除了已知有问题的选项,通过加密更多协商握手来提供额外的隐私,由于使用了更有效的现代加密算法,所以可以更快。TLS 1.3 也在所有系统范围的加密策略中启用了。 |
4.2. RHEL 8 中 TLS 的安全注意事项 复制链接链接已复制到粘贴板!
在 RHEL 8 中,由于系统范围的加密策略,与加密相关的注意事项大大简化了。DEFAULT
加密策略只允许 TLS 1.2 和 1.3。要允许您的系统使用早期版本的 TLS 来协商连接,您需要选择不使用应用程序中的以下加密策略,或使用 update-crypto-policies
命令切换到 LEGACY
策略。如需更多信息,请参阅使用系统范围的加密策略。
RHEL 8 中包含的库提供的默认设置足以满足大多数部署的需要。TLS 实现尽可能使用安全算法,而不阻止来自或到旧客户端或服务器的连接。在具有严格安全要求的环境中应用强化设置,在这些环境中,不支持安全算法或协议的旧客户端或服务器不应连接或不允许连接。
强化 TLS 配置的最简单方法是使用 update-crypto-policies --set FUTURE
命令将系统范围的加密策略级别切换到 FUTURE
。
为 LEGACY
加密策略禁用的算法不符合红帽的 RHEL 8 安全愿景,其安全属性不可靠。考虑放弃使用这些算法,而不是重新启用它们。如果您确实决定重新启用它们(例如,为了与旧硬件的互操作性),请将它们视为不安全的,并应用额外的保护措施,例如将其网络交互隔离到单独的网络段。不要在公共网络中使用它们。
如果您决定不遵循 RHEL 系统范围的加密策略,或根据您的设置创建自定义的加密策略,请在自定义配置中对首选协议、密码套件和密钥长度使用以下建议:
4.2.1. 协议 复制链接链接已复制到粘贴板!
TLS 的最新版本提供了最佳安全机制。除非有充分的理由包含对旧版本的 TLS 的支持,否则请允许您的系统使用至少 TLS 版本 1.2 来协商连接。
请注意,尽管 RHEL 8 支持 TLS 版本 1.3,但 RHEL 8 组件并不完全支持这个协议的所有功能。例如,Apache Web 服务器尚不完全支持可降低连接延迟的 0-RTT(Zero R Trip Time)功能。
4.2.2. 密码套件 复制链接链接已复制到粘贴板!
现代、更安全的密码套件应该优先于旧的不安全密码套件。一直禁止 eNULL 和 aNULL 密码套件的使用,它们根本不提供任何加密或身份验证。如果有可能,基于 RC4 或 HMAC-MD5 的密码套件也必须被禁用。这同样适用于所谓的出口密码套件,它们被有意地弱化了,因此很容易被破解。
虽然不会立即变得不安全,但提供安全性少于 128 位的密码套件在它们的短使用期中不应该被考虑。使用 128 位或者更高安全性的算法可以预期在至少数年内不会被破坏,因此我们强烈推荐您使用此算法。请注意,虽然 3DES 密码公告使用 168 位但它们实际只提供了 112 位的安全性。
始终优先使用支持(完美)转发保密(PFS)的密码套件,这样可确保加密数据的机密性,以防服务器密钥被泄露。此规则排除了快速 RSA 密钥交换,但允许使用 ECDHE 和 DHE。在两者中,ECDHE 更快,因此是首选。
您还应该优先选择 AEAD 密码,如 AES-GCM,使用 CBC 模式密码,因为它们不容易受到 padding oracle 攻击的影响。此外,在很多情况下,在 CBC 模式下,AES-GCM 比 AES 快,特别是当硬件具有 AES 加密加速器时。
另请注意,在使用带有 ECDSA 证书的 ECDHE 密钥交换时,事务的速度甚至比纯 RSA 密钥交换要快。为了给旧客户端提供支持,您可以在服务器上安装两对证书和密钥:一对带有 ECDSA 密钥(用于新客户端),另一对带有 RSA 密钥(用于旧密钥)。
4.2.3. 公钥长度 复制链接链接已复制到粘贴板!
在使用 RSA 密钥时,总是首选使用至少由 SHA-256 签名的 3072 位的密钥长度,对于真实的 128 位安全性来说,这个值已经足够大。
您的系统安全性仅与链中最弱的连接相同。例如,只是一个强大的密码不能保证良好安全性。密钥和证书以及认证机构(CA)用来签署您的密钥的哈希功能和密钥同样重要。
4.3. 在应用程序中强化 TLS 配置 复制链接链接已复制到粘贴板!
在 RHEL 中,系统范围的加密策略 提供了一种便捷的方法,来确保您的使用加密库的应用程序不允许已知的不安全协议、密码或算法。
如果要使用自定义加密设置来强化与 TLS 相关的配置,您可以使用本节中描述的加密配置选项,并以最少的需求量覆盖系统范围的加密策略。
无论您选择使用什么配置,请始终确保您的服务器应用程序强制实施 服务器端密码顺序,以便使用的密码套件由您配置的顺序来决定。
4.3.1. 将 Apache HTTP 服务器配置为使用 TLS 复制链接链接已复制到粘贴板!
Apache HTTP 服务器
可以使用 OpenSSL
和 NSS
库来满足其 TLS 的需求。RHEL 8 通过 eponymous 软件包提供 mod_ssl
功能:
yum install mod_ssl
# yum install mod_ssl
mod_ssl
软件包将安装 /etc/httpd/conf.d/ssl.conf
配置文件,该文件可用来修改 Apache HTTP 服务器
与 TLS 相关的设置。
安装 httpd-manual
软件包以获取 Apache HTTP 服务器
的完整文档,包括 TLS 配置。/etc/httpd/conf.d/ssl.conf
配置文件中的指令在 /usr/share/httpd/manual/mod_ssl.html
文件中详细介绍。/usr/share/httpd/manual/ssl/ssl/ssl_howto.html
文件中描述了各种设置的示例。
修改 /etc/httpd/conf.d/ssl.conf
配置文件中的设置时,请确保至少考虑以下三个指令:
SSLProtocol
- 使用这个指令指定您要允许的 TLS 或者 SSL 版本。
SSLCipherSuite
- 使用这个指令来指定您首选的密码套件或禁用您要禁止的密码套件。
SSLHonorCipherOrder
-
取消注释并将此指令设置为
on
,以确保连接的客户端遵循您指定的密码顺序。
例如,只使用 TLS 1.2 和 1.3 协议:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
如需更多信息,请参阅 部署不同类型的服务器 文档中的 在 Apache HTTP 服务器上配置 TLS 加密 一章。
4.3.2. 将 Nginx HTTP 和代理服务器配置为使用 TLS 复制链接链接已复制到粘贴板!
要在 Nginx
中启用 TLS 1.3 支持,请将 TLSv1.3
值添加到 /etc/nginx/nginx.conf
配置文件的 server
部分的 ssl_protocols
选项:
如需更多信息,请参阅 部署不同类型的服务器 文档中的 向 Nginx web 服务器添加 TLS 加密 一章。
4.3.3. 将 Dovecot 邮件服务器配置为使用 TLS 复制链接链接已复制到粘贴板!
要将 Dovecot
邮件服务器的安装配置为使用 TLS,请修改 /etc/dovecot/conf.d/10-ssl.conf
配置文件。您可以在 /usr/share/doc/dovecot/wiki/SSL.DovecotConfiguration.txt
文件中找到一些基本配置指令的说明,该文件与 Dovecot
的标准安装一起安装。
修改 /etc/dovecot/conf.d/10-ssl.conf
配置文件中的设置时,请确保至少考虑以下三个指令:
ssl_protocols
- 使用这个指令指定您要允许或者禁用的 TLS 或者 SSL 版本。
ssl_cipher_list
- 使用这个指令指定您首选的密码套件或禁用您要禁止的密码套件。
ssl_prefer_server_ciphers
-
取消注释并将此指令设置为
yes
,以确保连接的客户端遵循您指定的密码顺序。
例如,/etc/dovecot/conf.d/10-ssl.conf
中的以下行只允许 TLS 1.1 及之后的版本:
ssl_protocols = !SSLv2 !SSLv3 !TLSv1
ssl_protocols = !SSLv2 !SSLv3 !TLSv1
第 5 章 设置 IPsec VPN 复制链接链接已复制到粘贴板!
虚拟专用网络(VPN)是一种通过互联网连接到本地网络的方法。Libreswan
提供的 IPsec
是创建 VPN 的首选方法。libreswan
是 VPN 的用户空间 IPsec
实现。VPN 通过在中间网络(如互联网)设置隧道来启用 LAN 和另一个远程 LAN 之间的通信。为了安全起见,VPN 隧道总是使用认证和加密。对于加密操作,Libreswan
使用 NSS
库。
5.1. libreswan 作为 IPsec VPN 的实现 复制链接链接已复制到粘贴板!
在 RHEL 中,您可以使用 Libreswan 应用程序支持的 IPsec 协议配置虚拟专用网络(VPN)。Libreswan 是 Openswan 应用程序的延续,Openswan 文档中的许多示例可以通过 Libreswan 交换。
VPN 的 IPsec 协议使用互联网密钥交换(IKE)协议进行配置。术语 IPsec 和 IKE 可互换使用。IPsec VPN 也称为 IKE VPN、IKEv2 VPN、XAUTH VPN、Cisco VPN 或 IKE/IPsec VPN。IPsec VPN 变体,它使用 Level 2 Tunneling Protocol(L2TP),被称为 L2TP/IPsec VPN,它需要 optional
软件仓库提供的 xl2tpd
软件包。
libreswan 是一个开源用户空间 IKE 实现。IKE v1 和 v2 作为用户级别的守护进程实现。IKE 协议也加密。IPsec 协议由 Linux 内核实现,Libreswan 配置内核以添加和删除 VPN 隧道配置。
IKE 协议使用 UDP 端口 500 和 4500。IPsec 协议由两个协议组成:
- 封装安全性 Payload(ESP),其协议号为 50。
- 经过身份验证的标头(AH),其协议号为 51。
不建议使用 AH 协议。建议将 AH 用户迁移到使用 null 加密的 ESP。
IPsec 协议提供两种操作模式:
- 隧道模式(默认)
- 传输模式
您可以用没有 IKE 的 IPsec 来配置内核。这称为 手动键控。您还可以使用 ip xfrm
命令来配置手动密钥,但为了安全起见,强烈建议您不要这样做。Libreswan 使用 Netlink 接口与 Linux 内核进行通信。内核执行数据包加密和解密。
Libreswan 使用网络安全服务 (NSS) 加密库。NSS 认证用于 联邦信息处理标准( FIPS)出版物 140-2。
IKE/IPsec VPN(由 Libreswan 和 Linux 内核实现)是 RHEL 中推荐的唯一 VPN 技术。在不了解这样做风险的情况下不要使用任何其他 VPN 技术。
在 RHEL 中,Libreswan 默认遵循系统范围的加密策略。这样可确保 Libreswan 将当前威胁模型包括(IKEv2)的安全设置用作默认协议。如需更多信息,请参阅 使用系统范围的加密策略。
Libreswan 没有使用术语"源(source)"和"目的地(destination)"或"服务器(server)"和"客户端(client)",因为 IKE/IPsec 使用对等(peer to peer)协议。相反,它使用术语"左"和"右"来指端点(主机)。这也允许您在大多数情况下在两个端点使用相同的配置。但是,管理员通常选择始终对本地主机使用"左",对远程主机使用"右"。
leftid
和 rightid
选项充当身份验证过程中相应主机的标识。详情请查看 ipsec.conf(5)
手册页。
5.2. Libreswan 中的身份验证方法 复制链接链接已复制到粘贴板!
Libreswan 支持多种身份验证方法,每种方法适合不同的场景。
预共享密钥(PSK)
预共享密钥 (PSK)是最简单的身份验证方法。出于安全考虑,请勿使用小于 64 个随机字符的 PSK。在 FIPS 模式中,PSK 必须符合最低强度要求,具体取决于所使用的完整性算法。您可以使用 authby=secret
连接来设置 PSK。
原始 RSA 密钥
原始 RSA 密钥 通常用于静态主机到主机或子网到子网 IPsec 配置。每个主机都使用所有其他主机的公共 RSA 密钥手动配置,Libreswan 在每对主机之间建立 IPsec 隧道。对于大量主机,这个方法不能很好地扩展。
您可以使用 ipsec newhostkey
命令在主机上生成原始 RSA 密钥。您可以使用 ipsec showhostkey
命令列出生成的密钥。使用 CKA ID 密钥的连接配置需要 leftrsasigkey=
行。原始 RSA 密钥使用 authby=rsasig
连接选项。
X.509 证书
X.509 证书 通常用于大规模部署连接到通用 IPsec 网关的主机。中心 证书颁发机构 (CA)为主机或用户签署 RSA 证书。此中央 CA 负责中继信任,包括单个主机或用户的撤销。
例如,您可以使用 openssl
命令和 NSS certutil
命令来生成 X.509 证书。因为 Libreswan 使用 leftcert=
配置选项中证书的昵称从 NSS 数据库读取用户证书,所以在创建证书时请提供昵称。
如果使用自定义 CA 证书,则必须将其导入到网络安全服务(NSS)数据库中。您可以使用 ipsec import
命令将 PKCS #12 格式的任何证书导入到 Libreswan NSS 数据库。
Libreswan 需要互联网密钥交换(IKE)对等 ID 作为每个对等证书的主题替代名称(SAN),如 RFC 4945 的 3.1 章节 所述。通过设置 require-id-on-certificate=no
连接选项禁用此检查,可能会使系统容易受到中间人攻击。
使用 authby=rsasig
连接选项,根据使用带 SHA-1 和 SHA-2 的 RSA 的 X.509 证书进行身份验证。您可以通过将 authby=
设为 ecdsa
,使用 SHA-2 ,以及使用通过 authby=rsa-sha2
的基于 SHA-2 的身份验证的 RSA 概率签名方案(RSASSA-PSS)数字签名来进一步限制 ECDSA 数字签名。默认值为 authby=rsasig,ecdsa
。
证书和 authby=
签名方法应匹配。这提高了互操作性,并在一个数字签名系统中保留身份验证。
NULL 身份验证
NULL 身份验证 用来在没有身份验证的情况下获得网状加密。它可防止被动攻击,但不能防止主动攻击。但是,因为 IKEv2 允许非对称身份验证方法,因此 NULL 身份验证也可用于互联网规模的机会主义 IPsec。在此模型中,客户端对服务器进行身份验证,但服务器不对客户端进行身份验证。此模型类似于使用 TLS 的安全网站。使用 authby=null
进行 NULL 身份验证。
保护量子计算机
除了上述身份验证方法外,您还可以使用 Post-quantum Pre-shared Key (PPK)方法来防止量子计算机可能的攻击。单个客户端或客户端组可以通过指定与带外配置的预共享密钥对应的 PPK ID 来使用它们自己的 PPK。
使用带有预共享密钥的 IKEv1 防止量子攻击者。重新设计 IKEv2 不会原生提供这种保护。Libreswan 提供使用 Post-quantum Pre-shared Key (PPK)来保护 IKEv2 连接免受量子攻击。
要启用可选的 PPK 支持,请在连接定义中添加 ppk=yes
。如需要 PPK,请添加 ppk=insist
。然后,可以给每个客户端一个带有 secret 值的 PPK ID ,该 secret 值在带外进行通信(最好是量子安全的)。PPK 应该具有很强的随机性,而不是基于字典中的单词。PPK ID 和 PPK 数据保存在 ipsec.secrets
文件中,例如:
@west @east : PPKS "user1" "thestringismeanttobearandomstr"
@west @east : PPKS "user1" "thestringismeanttobearandomstr"
PPKS
选项指的是静态 PPK。这个实验性功能使用基于一次性平板的动态 PPK。在每个连接中,一次性平板的一个新部件用作 PPK。当使用时,文件中动态 PPK 的那部分被零覆盖,以防止重复使用。如果没有剩下一次性资源,连接会失败。详情请查看 ipsec.secrets(5)
手册页。
动态 PPK 的实现是作为不受支持的技术预览提供的。请谨慎使用。
5.3. 安装 Libreswan 复制链接链接已复制到粘贴板!
在通过 Libreswan IPsec/IKE 实现设置 VPN 之前,您必须安装相应的软件包,启动 ipsec
服务,并在防火墙中允许服务。
先决条件
-
AppStream
存储库已启用。
流程
安装
libreswan
软件包:yum install libreswan
# yum install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果要重新安装 Libreswan,请删除其旧的数据库文件,并创建一个新的数据库:
systemctl stop ipsec rm /etc/ipsec.d/*db ipsec initnss
# systemctl stop ipsec # rm /etc/ipsec.d/*db # ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启动
ipsec
服务,并启用该服务,以便其在引导时自动启动:systemctl enable ipsec --now
# systemctl enable ipsec --now
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过添加
ipsec
服务,将防火墙配置为允许 IKE、ESP 和 AH 协议的 500 和 4500/UDP 端口:firewall-cmd --add-service="ipsec" firewall-cmd --runtime-to-permanent
# firewall-cmd --add-service="ipsec" # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.4. 创建主机到主机的 VPN 复制链接链接已复制到粘贴板!
您可以使用原始 RSA 密钥身份验证将 Libreswan 配置为在两个称为 left 和 right 的主机之间创建主机到主机的 IPsec VPN。
先决条件
-
Libreswan 已安装 ,并在每个节点上启动了
ipsec
服务。
流程
在每台主机上生成原始 RSA 密钥对:
ipsec newhostkey
# ipsec newhostkey
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 上一步返回生成的密钥的
ckaid
。在 左 主机上使用ckaid
和以下命令,例如:ipsec showhostkey --left --ckaid 2d3ea57b61c9419dfd6cf43a1eb6cb306c0e857d
# ipsec showhostkey --left --ckaid 2d3ea57b61c9419dfd6cf43a1eb6cb306c0e857d
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 上一命令的输出生成了配置所需的
leftrsasigkey=
行。在第二台主机(右)上执行相同的操作:ipsec showhostkey --right --ckaid a9e1f6ce9ecd3608c24e8f701318383f41798f03
# ipsec showhostkey --right --ckaid a9e1f6ce9ecd3608c24e8f701318383f41798f03
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
/etc/ipsec.d/
目录中,创建一个新的my_host-to-host.conf
文件。将上一步中ipsec showhostkey
命令的输出中的 RSA 主机密钥写入新文件。例如:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 导入密钥后,重启
ipsec
服务:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 加载连接:
ipsec auto --add mytunnel
# ipsec auto --add mytunnel
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 建立隧道:
ipsec auto --up mytunnel
# ipsec auto --up mytunnel
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要在
ipsec
服务启动时自动启动隧道,请在连接定义中添加以下行:auto=start
auto=start
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
5.5. 配置站点到站点的 VPN 复制链接链接已复制到粘贴板!
要创建站点到站点的 IPsec VPN,通过加入两个网络,在两个主机之间创建一个 IPsec 隧道。主机因此充当端点,它们配置为允许来自一个或多个子网的流量通过。因此您可以将主机视为到网络远程部分的网关。
站点到站点 VPN 的配置只能与主机到主机 VPN 不同,同时必须在配置文件中指定一个或多个网络或子网。
先决条件
- 已配置了主机到主机的 VPN。
流程
将带有主机到主机 VPN 配置的文件复制到新文件中,例如:
cp /etc/ipsec.d/my_host-to-host.conf /etc/ipsec.d/my_site-to-site.conf
# cp /etc/ipsec.d/my_host-to-host.conf /etc/ipsec.d/my_site-to-site.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在上一步创建的文件中添加子网配置,例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
5.6. 配置远程访问 VPN 复制链接链接已复制到粘贴板!
公路勇士是指拥有移动客户端和动态分配的 IP 地址的旅行用户。移动客户端使用 X.509 证书进行身份验证。
以下示例显示了 IKEv2
的配置,并且避免使用 IKEv1
XAUTH 协议。
在服务器中:
在移动客户端(即 road warrior 的设备)上,使用与之前配置稍有不同的配置:
如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
5.7. 配置网格 VPN 复制链接链接已复制到粘贴板!
网格 VPN 网络(也称为 any-to-any VPN ) 是一个所有节点都使用 IPsec 进行通信的网络。该配置可以对于无法使用 IPsec 的节点进行例外处理。可使用两种方式配置网格 VPN 网络:
- 需要 IPsec。
- 首选 IPsec,但允许回退到使用明文通信。
节点之间的身份验证可以基于 X.509 证书或 DNS 安全扩展(DNSSEC)。
您对 opportunistic IPsec 使用任何常规的 IKEv2 验证方法,因为这些连接是常规的 Libreswan 配置,除了由 right=%opportunisticgroup
条目定义的 opportunistic IPsec 之外。常见的身份验证方法是主机使用常用共享认证机构(CA)根据 X.509 证书进行互相验证。作为标准流程的一部分,云部署通常为云中的每个节点发布证书。
不要使用 PreSharedKey (PSK)身份验证,因为一个有危险的主机会导致组 PSK secret 也有危险。
您可以使用 NULL 身份验证在节点间部署加密,而无需认证,这只防止被动攻击者。
以下流程使用 X.509 证书。您可以使用任何类型的 CA 管理系统(如 Dogtag 证书系统)生成这些证书。Dogtag 假设每个节点的证书都以 PKCS #12 格式(.p12
文件)提供,其包含私钥、节点证书和用于验证其他节点的 X.509 证书的根 CA 证书。
每个节点的配置与其 X.509 证书不同。这允许在不重新配置网络中的任何现有节点的情况下添加新节点。PKCS #12 文件需要一个"友好名称",为此,我们使用名称"节点",这样引用友好名称的配置文件对所有节点都是相同的。
先决条件
-
Libreswan 已安装 ,并在每个节点上启动了
ipsec
服务。 一个新的 NSS 数据库已初始化。
如果您已经有一个旧的 NSS 数据库,请删除旧的数据库文件:
systemctl stop ipsec rm /etc/ipsec.d/*db
# systemctl stop ipsec # rm /etc/ipsec.d/*db
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您可以使用以下命令初始化新数据库:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
流程
在每个节点中导入 PKCS #12 文件。此步骤需要用于生成 PKCS #12 文件的密码:
ipsec import nodeXXX.p12
# ipsec import nodeXXX.p12
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为
IPsec 需要的
(专用)、IPsec 可选的
(private-or-clear)和No IPsec
(clear)配置文件创建以下三个连接定义:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
auto
变量有几个选项:您可以使用带有 opportunistic IPsec 的
ondemand
连接选项来启动 IPsec 连接,或者用于显式配置不需要一直激活的连接。这个选项在内核中建立一个陷阱 XFRM 策略,使 IPsec 连接在收到与该策略匹配的第一个数据包时开始。您可以使用以下选项有效地配置和管理 IPsec 连接,无论是使用 Opportunistic IPsec 还是明确配置的连接:
add
选项-
加载连接配置,并为响应远程启动做好准备。但是,连接不会自动从本地端启动。您可以使用
ipsec auto --up
命令手动启动 IPsec 连接。 start
选项- 加载连接配置,并为响应远程启动做好准备。此外,它会立即启动到远程对等点的连接。您可以将这个选项用于永久的和一直活跃的连接。
- 2
leftid
和rightid
变量标识 IPsec 隧道连接的右和左通道。如果您配置了证书,您可以使用这些变量来获取本地 IP 地址或本地证书的主题 DN 的值。- 3
leftcert
变量定义您要使用的 NSS 数据库的昵称。
将网络的 IP 地址添加到对应的类中。例如,如果所有节点都位于
10.15.0.0/16
网络中,则所有节点都必须使用 IPsec 加密:echo "10.15.0.0/16" >> /etc/ipsec.d/policies/private
# echo "10.15.0.0/16" >> /etc/ipsec.d/policies/private
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要允许某些节点(如
10.15.34.0/24
)使用或不使用 IPsec,请将这些节点添加到 private-or-clear 组中:echo "10.15.34.0/24" >> /etc/ipsec.d/policies/private-or-clear
# echo "10.15.34.0/24" >> /etc/ipsec.d/policies/private-or-clear
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要定义一个主机(如
10.15.1.2
),其不能将 IPsec 添加到 clear 组中,请使用:echo "10.15.1.2/32" >> /etc/ipsec.d/policies/clear
# echo "10.15.1.2/32" >> /etc/ipsec.d/policies/clear
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您可以在
/etc/ipsec.d/policies
目录中从每个新节点的模板创建文件,也可以使用 Puppet 或 Ansible 来置备它们。请注意,每个节点都有相同的异常列表或不同的流量预期。因此,两个节点可能无法通信,因为一个节点需要 IPsec,而另一个节点无法使用 IPsec。
重启节点将其添加到配置的网格中:
systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
验证
使用
ping
命令打开 IPsec 隧道:ping <nodeYYY>
# ping <nodeYYY>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示带有导入认证的 NSS 数据库:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 查看节点上哪个隧道打开了:
ipsec trafficstatus
# ipsec trafficstatus 006 #2: "private#10.15.0.0/16"[1] ...<nodeYYY>, type=ESP, add_time=1691399301, inBytes=512, outBytes=512, maxBytes=2^63B, id='C=US, ST=NC, O=Example Organization, CN=east'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.8. 部署符合 FIPS 的 IPsec VPN 复制链接链接已复制到粘贴板!
您可以使用 Libreswan 部署一个符合 FIPS 的 IPsec VPN 解决方案。为此,您可以识别哪些加密算法可用,且哪些在 FIPS 模式下对 Libreswan 禁用了。
先决条件
-
AppStream
存储库已启用。
流程
安装
libreswan
软件包:yum install libreswan
# yum install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您要重新安装 Libreswan,请删除其旧的 NSS 数据库:
systemctl stop ipsec rm /etc/ipsec.d/*db
# systemctl stop ipsec # rm /etc/ipsec.d/*db
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启动
ipsec
服务,并启用该服务,以便其在引导时自动启动:systemctl enable ipsec --now
# systemctl enable ipsec --now
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过添加
ipsec
服务,将防火墙配置为允许 IKE、ESP 和 AH 协议的500
和4500
UDP 端口:firewall-cmd --add-service="ipsec" firewall-cmd --runtime-to-permanent
# firewall-cmd --add-service="ipsec" # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将系统切换到 FIPS 模式:
fips-mode-setup --enable
# fips-mode-setup --enable
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重启您的系统以允许内核切换到 FIPS 模式:
reboot
# reboot
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
确认 Libreswan 是否在 FIPS 模式下运行:
ipsec whack --fipsstatus
# ipsec whack --fipsstatus 000 FIPS mode enabled
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 或者,检查
systemd
日志中的ipsec
单元条目:journalctl -u ipsec
$ journalctl -u ipsec ... Jan 22 11:26:50 localhost.localdomain pluto[3076]: FIPS Product: YES Jan 22 11:26:50 localhost.localdomain pluto[3076]: FIPS Kernel: YES Jan 22 11:26:50 localhost.localdomain pluto[3076]: FIPS Mode: YES
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 以 FIPS 模式查看可用算法:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 FIPS 模式查询禁用的算法:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 FIPS 模式中列出所有允许的算法和密码:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.9. 使用密码保护 IPsec NSS 数据库 复制链接链接已复制到粘贴板!
默认情况下,IPsec 服务在第一次启动时使用空密码创建其网络安全服务(NSS)数据库。要提高安全性,您可以添加密码保护。
在 RHEL 6.6 和之前的版本中,您必须使用一个密码来保护 IPsec NSS 数据库,以满足 FIPS 140-2 标准的要求,因为 NSS 加密库是针对 FIPS 140-2 Level 2 标准认证的。在 RHEL 8 中,NIS 将 NSS 认证为该标准级别 1,并且该状态不需要对数据库进行密码保护。
先决条件
-
/etc/ipsec.d/
目录包含 NSS 数据库文件。
流程
为 Libreswan 的
NSS
数据库启用密码保护:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建包含您在上一步中设置的密码的
/etc/ipsec.d/nsspassword
文件,例如:cat /etc/ipsec.d/nsspassword NSS Certificate DB:_<password>_
# cat /etc/ipsec.d/nsspassword NSS Certificate DB:_<password>_
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nsspassword
文件使用以下语法:<token_1>:<password1> <token_2>:<password2>
<token_1>:<password1> <token_2>:<password2>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 默认的 NSS 软件令牌是
NSS 证书 数据库
。如果您的系统以 FIPS 模式运行,则令牌的名称为NSS FIPS 140-2 证书数据库
。根据您的场景,在完成了
nsspassword
文件后,启动或重启ipsec
服务:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
在其 NSS 数据库中添加非空密码后,检查
ipsec
服务是否运行:systemctl status ipsec
# systemctl status ipsec ● ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec Loaded: loaded (/usr/lib/systemd/system/ipsec.service; enabled; vendor preset: disable> Active: active (running)...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 检查
Journal
日志是否包含确认成功初始化的条目:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.10. 配置 IPsec VPN 以使用 TCP 复制链接链接已复制到粘贴板!
Libreswan 支持 IKE 和 IPsec 数据包的 TCP 封装,如 RFC 8229 所述。有了这个功能,您可以在网络上建立 IPsec VPN,以防止通过 UDP 和封装安全负载(ESP)传输的流量。您可以将 VPN 服务器和客户端配置为使用 TCP 作为回退,或者作为主 VPN 传输协议。由于 TCP 封装的性能成本较高,因此只有在您的场景中需要永久阻止 UDP 时,才使用 TCP 作为主 VPN 协议。
先决条件
- 已配置了 远程访问 VPN。
流程
在
/etc/ipsec.conf
文件的config setup
部分中添加以下选项:listen-tcp=yes
listen-tcp=yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要在第一次尝试 UDP 失败时使用 TCP 封装作为回退选项,请在客户端的连接定义中添加以下两个选项:
enable-tcp=fallback tcp-remoteport=4500
enable-tcp=fallback tcp-remoteport=4500
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 另外,如果您知道 UDP 会被永久阻止,请在客户端的连接配置中使用以下选项:
enable-tcp=yes tcp-remoteport=4500
enable-tcp=yes tcp-remoteport=4500
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.11. 配置自动检测和使用 ESP 硬件卸载来加速 IPsec 连接 复制链接链接已复制到粘贴板!
卸载硬件的封装安全负载(ESP)来加速以太网上的 IPsec 连接。默认情况下,Libreswan 会检测硬件是否支持这个功能,并因此启用 ESP 硬件卸载。如果这个功能被禁用或被明确启用,您可以切回到自动检测。
先决条件
- 网卡支持 ESP 硬件卸载。
- 网络驱动程序支持 ESP 硬件卸载。
- IPsec 连接已配置且可以正常工作。
流程
-
编辑连接的
/etc/ipsec.d/
目录中的 Libreswan 配置文件,该文件应使用 ESP 硬件卸载支持的自动检测。 -
确保连接的设置中没有设置
nic-offload
参数。 如果您删除了
nic-offload
,请重启ipsec
服务:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
显示 IPsec 连接使用的以太网设备的
tx_ipsec
和rx_ipsec
计数器:ethtool -S enp1s0 | grep -E "_ipsec"
# ethtool -S enp1s0 | grep -E "_ipsec" tx_ipsec: 10 rx_ipsec: 10
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过 IPsec 隧道发送流量。例如,ping 远程 IP 地址:
ping -c 5 remote_ip_address
# ping -c 5 remote_ip_address
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 再次显示以太网设备的
tx_ipsec
和rx_ipsec
计数器:ethtool -S enp1s0 | grep -E "_ipsec"
# ethtool -S enp1s0 | grep -E "_ipsec" tx_ipsec: 15 rx_ipsec: 15
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果计数器值增加了,ESP 硬件卸载正常工作。
5.12. 在绑定中配置 ESP 硬件卸载以加快 IPsec 连接 复制链接链接已复制到粘贴板!
将封装安全负载(ESP)卸载到硬件可加速 IPsec 连接。如果出于故障转移原因而使用网络绑定,配置 ESP 硬件卸载的要求和流程与使用常规以太网设备的要求和流程不同。例如,在这种情况下,您可以对绑定启用卸载支持,内核会将设置应用到绑定的端口。
先决条件
-
绑定中的所有网卡都支持 ESP 硬件卸载。使用
ethtool -k <interface_name> | grep "esp-hw-offload"
命令验证每个绑定端口是否都支持此功能。 - 绑定已配置且可以正常工作。
-
该绑定使用
active-backup
模式。绑定驱动程序不支持此功能的任何其他模式。 - IPsec 连接已配置且可以正常工作。
流程
对网络绑定启用 ESP 硬件卸载支持:
nmcli connection modify bond0 ethtool.feature-esp-hw-offload on
# nmcli connection modify bond0 ethtool.feature-esp-hw-offload on
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这个命令在对
bond0
连接启用 ESP 硬件卸载支持。重新激活
bond0
连接:nmcli connection up bond0
# nmcli connection up bond0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 编辑应使用 ESP 硬件卸载的连接的
/etc/ipsec.d/
目录中的 Libreswan 配置文件,并将nic-offload=yes
语句附加到连接条目:conn example ... nic-offload=yes
conn example ... nic-offload=yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重启
ipsec
服务:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证方法取决于各种方面,如内核版本和驱动程序。例如,某些驱动程序提供计数器,但它们的名称可能会有所不同。详情请查看您的网络驱动程序的文档。
以下验证步骤适用于 Red Hat Enterprise Linux 8 上的 ixgbe
驱动程序:
显示绑定的活动端口:
grep "Currently Active Slave" /proc/net/bonding/bond0
# grep "Currently Active Slave" /proc/net/bonding/bond0 Currently Active Slave: enp1s0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示活动端口的
tx_ipsec
和rx_ipsec
计数器:ethtool -S enp1s0 | grep -E "_ipsec"
# ethtool -S enp1s0 | grep -E "_ipsec" tx_ipsec: 10 rx_ipsec: 10
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过 IPsec 隧道发送流量。例如,ping 远程 IP 地址:
ping -c 5 remote_ip_address
# ping -c 5 remote_ip_address
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 再次显示活动端口的
tx_ipsec
和rx_ipsec
计数器:ethtool -S enp1s0 | grep -E "_ipsec"
# ethtool -S enp1s0 | grep -E "_ipsec" tx_ipsec: 15 rx_ipsec: 15
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果计数器值增加了,ESP 硬件卸载正常工作。
5.13. 使用 RHEL 系统角色配置 IPsec VPN 连接 复制链接链接已复制到粘贴板!
您可以使用虚拟专用网络(VPN)通过不可信网络(如互联网)建立安全加密的隧道。此类隧道可确保传输中数据的保密性和完整性。常见用例包括将分支机构连接到总部。
通过使用 vpn
RHEL 系统角色,您可以自动创建 Libreswan IPsec VPN 配置的过程。
vpn
RHEL 系统角色只能创建使用预共享密钥(PSK)或证书的 VPN 配置来相互验证对等点。
5.13.1. 使用 vpn RHEL 系统角色配置具有 PSK 身份验证的 IPsec 主机到主机的 VPN 复制链接链接已复制到粘贴板!
主机到主机 VPN 在两个设备之间建立直接、安全和加密的连接,允许应用程序通过不安全的网络(如互联网)安全地进行通信。
为了进行身份验证,预共享密钥(PSK)是使用只给两个对等点已知的单一共享 secret 的直接方法。这种方法易于配置,非常适合易于部署是优先级的基本设置。但是,您必须严格保密密钥。可以访问该密钥的攻击者可能会破坏连接。
通过使用 vpn
RHEL 系统角色,您可以自动化创建带有 PSK 身份验证的 IPsec 主机到主机连接的过程。默认情况下,角色创建一个基于隧道的 VPN。
先决条件
- 您已准备好控制节点和受管节点。
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。
步骤
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括以下内容:
hosts: <list>
使用您要配置 VPN 的对等点定义 YAML 字典。如果条目不是一个 Ansible 管理的节点,则您必须在
hostname
参数中指定其完全限定域名(FQDN)或 IP 地址,例如:... - hosts: ... external-host.example.com: hostname: 192.0.2.1
... - hosts: ... external-host.example.com: hostname: 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 角色在每个受管节点上配置 VPN 连接。连接名为 <
peer_A>-to-<peer_B
>,例如managed-node-01.example.com-to-managed-node-02.example.com
。请注意,该角色无法在外部(未管理)节点上配置 Libreswan。您必须在这些对等点上手动创建配置。auth_method: psk
-
启用对等点之间的 PSK 身份验证。角色在控制节点上使用
openssl
来创建 PSK。 auto: <startup_method>
-
指定连接的启动方法。有效值是
add
、ondemand
、start
和ignore
。详情请查看安装了 Libreswan 的系统上的ipsec.conf (5)
手册页。此变量的默认值为 null,这意味着没有自动启动操作。 vpn_manage_firewall: true
-
定义角色在受管节点上的
firewalld
服务中打开所需的端口。 vpn_manage_selinux: true
- 定义角色在 IPsec 端口上设置所需的 SELinux 端口类型。
有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
文件。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不会防止错误但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
确认连接已成功启动,例如:
ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "managed-node-01.example.com-to-managed-node-02.example.com"'
# ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "managed-node-01.example.com-to-managed-node-02.example.com"' ... 006 #3: "managed-node-01.example.com-to-managed-node-02.example.com", type=ESP, add_time=1741857153, inBytes=38622, outBytes=324626, maxBytes=2^63B, id='@managed-node-02.example.com'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,只有在 VPN 连接活跃时,这个命令才会成功。如果将 playbook 中的
auto
变量设置为start
以外的值,您可能需要首先手动激活受管节点上的连接。
主机到主机 VPN 在两个设备之间建立直接、安全和加密的连接,允许应用程序通过不安全的网络(如互联网)安全地进行通信。
为了进行身份验证,预共享密钥(PSK)是使用只给两个对等点已知的单一共享 secret 的直接方法。这种方法易于配置,非常适合易于部署是优先级的基本设置。但是,您必须严格保密密钥。可以访问该密钥的攻击者可能会破坏连接。
例如,要通过最大程度减少被截获或破坏的控制消息的风险来增强安全性,您可以为数据流量和控制流量配置单独的连接。通过使用 vpn
RHEL 系统角色,您可以自动化创建带有单独的数据和控制平面及 PSK 身份验证的 IPsec 主机到主机连接的过程。
前提条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
hosts: < ;list>
定义一个 YAML 字典,其中包含您想要在它们之间配置 VPN 的主机。连接被命名为
<name>-<IP_address_A>-to-<IP_address_B>
,例如control_plane_vpn-203.0.113.1-to-198.51.100.2
。角色在每个受管节点上配置 VPN 连接。请注意,该角色无法在外部(未管理)节点上配置 Libreswan。您必须在这些主机上手动创建配置。
auth_method: psk
-
在主机之间启用 PSK 身份验证。角色在控制节点上使用
openssl
来创建预共享密钥。 auto: <startup_method>
-
指定连接的启动方法。有效值是
add
、ondemand
、start
和ignore
。详情请查看安装了 Libreswan 的系统上的ipsec.conf (5)
手册页。此变量的默认值为 null,这意味着没有自动启动操作。 vpn_manage_firewall: true
-
定义角色在受管节点上的
firewalld
服务中打开所需的端口。 vpn_manage_selinux: true
- 定义角色在 IPsec 端口上设置所需的 SELinux 端口类型。
有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
文件。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
确认连接已成功启动,例如:
ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "control_plane_vpn-203.0.113.1-to-198.51.100.2"'
# ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "control_plane_vpn-203.0.113.1-to-198.51.100.2"' ... 006 #3: "control_plane_vpn-203.0.113.1-to-198.51.100.2", type=ESP, add_time=1741860073, inBytes=0, outBytes=0, maxBytes=2^63B, id='198.51.100.2'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,只有在 VPN 连接活跃时,这个命令才会成功。如果将 playbook 中的
auto
变量设置为start
以外的值,您可能需要首先手动激活受管节点上的连接。
5.13.3. 使用 vpn RHEL 系统角色使用 PSK 身份验证配置 IPsec 站点到站点 VPN 复制链接链接已复制到粘贴板!
站点到站点的 VPN 在两个不同的网络之间建立一个安全、加密的隧道,在不安全的公共网络(如互联网)中无缝链接。例如,这可让分支机构中的设备访问公司总部中的资源,就如同它们都是同一本地网络的一部分一样。
为了进行身份验证,预共享密钥(PSK)是使用只给两个对等点已知的单一共享 secret 的直接方法。这种方法易于配置,非常适合易于部署是优先级的基本设置。但是,您必须严格保密密钥。可以访问该密钥的攻击者可能会破坏连接。
通过使用 vpn
RHEL 系统角色,您可以使用 PSK 身份验证自动创建 IPsec 站点到站点连接的过程。默认情况下,角色创建一个基于隧道的 VPN。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
hosts: < ;list>
使用您要配置 VPN 的网关定义 YAML 字典。如果条目不是 Ansible 管理的节点,您必须在
hostname
参数中指定其完全限定域名(FQDN)或 IP 地址,例如:... - hosts: ... external-host.example.com: hostname: 192.0.2.1
... - hosts: ... external-host.example.com: hostname: 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 角色在每个受管节点上配置 VPN 连接。连接名为
-to-
,例如managed-node-01.example.com-to-managed-node-02.example.com
。请注意,该角色无法在外部(未管理)节点上配置 Libreswan。您必须在这些对等点上手动创建配置。subnets: <yaml_list_of_subnets>
- 定义通过隧道连接的无类别域间路由(CIDR)格式的子网。
auth_method: psk
-
启用对等点之间的 PSK 身份验证。角色在控制节点上使用
openssl
来创建 PSK。 auto: <startup_method>
-
指定连接的启动方法。有效值是
add
、ondemand
、start
和ignore
。详情请查看安装了 Libreswan 的系统上的ipsec.conf (5)
手册页。此变量的默认值为 null,这意味着没有自动启动操作。 vpn_manage_firewall: true
-
定义角色在受管节点上的
firewalld
服务中打开所需的端口。 vpn_manage_selinux: true
- 定义角色在 IPsec 端口上设置所需的 SELinux 端口类型。
有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
文件。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
确认连接已成功启动,例如:
ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "managed-node-01.example.com-to-managed-node-02.example.com"'
# ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "managed-node-01.example.com-to-managed-node-02.example.com"' ... 006 #3: "managed-node-01.example.com-to-managed-node-02.example.com", type=ESP, add_time=1741857153, inBytes=38622, outBytes=324626, maxBytes=2^63B, id='@managed-node-02.example.com'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,只有在 VPN 连接活跃时,这个命令才会成功。如果将 playbook 中的
auto
变量设置为start
以外的值,您可能需要首先手动激活受管节点上的连接。
5.13.4. 使用 vpn RHEL 系统角色,配置具有基于证书身份验证的 IPsec 网状 VPN 复制链接链接已复制到粘贴板!
IPsec 网格会创建一个完全互连的网络,每个服务器都可以与所有其他服务器安全通信。这是涵盖多个数据中心或云供应商的分布式数据库集群或高可用性环境的理想选择。在每对服务器之间建立直接的加密隧道可确保安全通信,而无需中央瓶颈。
为进行身份验证,使用由证书颁发机构(CA)管理的数字证书,可提供高度安全、可扩展的解决方案。网格中的每个主机都提供由可信 CA 签名的证书。这个方法提供强大的、可靠的身份验证,并简化了用户管理。可以在 CA 中集中授予或撤销访问权限,Libreswan 通过针对证书撤销列表(CRL)检查每个证书来强制实施这个访问权限,如果证书出现在列表中,则拒绝访问。
通过使用 vpn
RHEL 系统角色,您可以在受管节点之间自动化配置带有基于证书的身份验证的 VPN 网格。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。 您可以为每个受管节点准备一个 PKCS #12 文件:
每个文件包含:
- 服务器的私钥
- 服务器证书
- CA 证书
- 如果需要,则中间证书
-
文件被命名为
<managed_node_name_as_in_the_inventory>.p12
。 - 文件存储在与 playbook 相同的目录中。
服务器证书包含以下字段:
-
扩展的密钥使用(EKU)设置为
TLS Web 服务器身份验证
。 - 通用名称(CN)或主题备用名称(SAN)被设置为主机的完全限定域名(FQDN)。
- X509v3 CRL 发行版点包含证书撤销列表(CRL)的 URL。
-
扩展的密钥使用(EKU)设置为
流程
编辑
~/inventory
文件,并附加cert_name
变量:managed-node-01.example.com cert_name=managed-node-01.example.com managed-node-02.example.com cert_name=managed-node-02.example.com managed-node-03.example.com cert_name=managed-node-03.example.com
managed-node-01.example.com cert_name=managed-node-01.example.com managed-node-02.example.com cert_name=managed-node-02.example.com managed-node-03.example.com cert_name=managed-node-03.example.com
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
cert_name
变量设置为每个主机的证书中使用的通用名称(CN)字段的值。通常,CN 字段被设置为完全限定域名(FQDN)。将敏感变量存储在加密的文件中:
创建 vault :
ansible-vault create ~/vault.yml
$ ansible-vault create ~/vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
ansible-vault create
命令打开编辑器后,以<key>: <value>
格式输入敏感数据:pkcs12_pwd: <password>
pkcs12_pwd: <password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 保存更改,并关闭编辑器。Ansible 加密 vault 中的数据。
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
opportunistic: true
-
在多个主机之间启用机会网格。
policies
变量定义必须或可以加密哪些子网和主机流量,并且哪些应该继续使用纯文本连接。 auth_method: cert
- 启用基于证书的身份验证。这要求您在清单中指定每个受管节点证书的 nickname。
policies: <list_of_policies>
以 YAML 列表格式定义 Libreswan 策略。
默认策略是
private-or-clear
。要将它改为private
,上面的 playbook 包含默认cidr
条目的一个相应策略。如果 Ansible 控制节点与受管节点在同一个 IP 子网中,要防止执行 playbook 期间丢失 SSH 连接,请为控制节点的 IP 地址添加一个
clear
策略。例如,如果应该为192.0.2.0/24
子网配置网格,并且控制节点使用 IP 地址192.0.2.1
,则您需要一个用于192.0.2.1/32
的clear
策略,如 playbook 中所示。有关策略的详情,请查看安装了 Libreswan 的系统上的
ipsec.conf (5)
手册页。vpn_manage_firewall: true
-
定义角色在受管节点上的
firewalld
服务中打开所需的端口。 vpn_manage_selinux: true
- 定义角色在 IPsec 端口上设置所需的 SELinux 端口类型。
有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
文件。验证 playbook 语法:
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
$ ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook --ask-vault-pass ~/playbook.yml
$ ansible-playbook --ask-vault-pass ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
在网格的一个节点上,ping 另一个节点来激活连接:
ping managed-node-02.example.com
[root@managed-node-01]# ping managed-node-02.example.com
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 确认连接处于活跃状态:
ipsec trafficstatus
[root@managed-node-01]# ipsec trafficstatus 006 #2: "private#192.0.2.0/24"[1] ...192.0.2.2, type=ESP, add_time=1741938929, inBytes=372408, outBytes=545728, maxBytes=2^63B, id='CN=managed-node-02.example.com'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.14. 配置选择不使用系统范围的加密策略的 IPsec 连接 复制链接链接已复制到粘贴板!
为连接覆盖系统范围的加密策略
RHEL 系统范围的加密策略会创建一个名为 %default
的特殊连接。此连接包含 ikev2
、esp
和 ike
选项的默认值。但是,您可以通过在连接配置文件中指定上述选项来覆盖默认值。
例如,以下配置允许使用带有 AES 和 SHA-1 或 SHA-2的 IKEv1 连接,以及带有 AES-GCM 或 AES-CBC 的 IPsec(ESP) 连接:
请注意,AES-GCM 可用于 IPsec(ESP)和 IKEv2,但不适用于 IKEv1。
为所有连接禁用系统范围的加密策略
要禁用所有 IPsec 连接的系统范围的加密策略,请在 /etc/ipsec.conf
文件中注释掉以下行:
include /etc/crypto-policies/back-ends/libreswan.config
include /etc/crypto-policies/back-ends/libreswan.config
然后将 ikev2=never
选项添加到连接配置文件。
5.15. IPsec VPN 配置故障排除 复制链接链接已复制到粘贴板!
与 IPsec VPN 配置相关的问题通常是由于几个主要原因造成的。如果您遇到此类问题,您可以检查问题的原因是否符合一下任何一种情况,并应用相应的解决方案。
基本连接故障排除
VPN 连接的大多数问题都发生在新部署中,管理员使用不匹配的配置选项配置了端点。此外,正常工作的配置可能会突然停止工作,通常是由于新引入的不兼容的值。这可能是管理员更改配置的结果。或者,管理员可能已安装了固件更新,或者使用某些选项的不同默认值(如加密算法)安装了软件包更新。
要确认已建立 IPsec VPN 连接:
ipsec trafficstatus
# ipsec trafficstatus
006 #8: "vpn.example.com"[1] 192.0.2.1, type=ESP, add_time=1595296930, inBytes=5999, outBytes=3231, id='@vpn.example.com', lease=100.64.13.5/32
如果输出为空或者没有显示具有连接名称的条目,则隧道将断开。
检查连接中的问题:
重新载入 vpn.example.com 连接:
ipsec auto --add vpn.example.com
# ipsec auto --add vpn.example.com 002 added connection description "vpn.example.com"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 下一步,启动 VPN 连接:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
与防火墙相关的问题
最常见的问题是,其中一个 IPsec 端点或端点之间路由器上的防火墙将所有互联网密钥交换(IKE)数据包丢弃。
对于 IKEv2,类似以下示例的输出说明防火墙出现问题:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对于 IKEv1,启动命令的输出如下:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
由于用于设置 IPsec 的 IKE 协议已经加密,因此您只能使用 tcpdump
工具排除一小部分问题。如果防火墙丢弃了 IKE 或 IPsec 数据包,您可以尝试使用 tcpdump
工具来查找原因。但是,tcpdump
无法诊断 IPsec VPN 连接的其他问题。
捕获
eth0
接口上的 VPN 协商以及所有加密数据:tcpdump -i eth0 -n -n esp or udp port 500 or udp port 4500 or tcp port 4500
# tcpdump -i eth0 -n -n esp or udp port 500 or udp port 4500 or tcp port 4500
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
不匹配的算法、协议和策略
VPN 连接要求端点具有匹配的 IKE 算法、IPsec 算法和 IP 地址范围。如果发生不匹配,连接会失败。如果您使用以下方法之一发现不匹配,请通过匹配算法、协议或策略来修复它。
如果远程端点没有运行 IKE/IPsec,您可以看到一个 ICMP 数据包来指示它。例如:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 000 "vpn.example.com"[1] 192.0.2.2 #16: ERROR: asynchronous network error report on wlp2s0 (192.0.2.2:500), complainant 198.51.100.1: Connection refused [errno 111, origin ICMP type 3 code 3 (not authenticated)] ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 不匹配 IKE 算法示例:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 003 "vpn.example.com"[1] 193.110.157.148 #3: dropping unexpected IKE_SA_INIT message containing NO_PROPOSAL_CHOSEN notification; message payloads: N; missing payloads: SA,KE,Ni
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 不匹配 IPsec 算法示例:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 182 "vpn.example.com"[1] 193.110.157.148 #5: STATE_PARENT_I2: sent v2I2, expected v2R2 {auth=IKEv2 cipher=AES_GCM_16_256 integ=n/a prf=HMAC_SHA2_256 group=MODP2048} 002 "vpn.example.com"[1] 193.110.157.148 #6: IKE_AUTH response contained the error notification NO_PROPOSAL_CHOSEN
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 不匹配的 IKE 版本还可导致远程端点在没有响应的情况下丢弃请求。这与丢弃所有 IKE 数据包的防火墙相同。
IKEv2 不匹配的 IP 地址范围示例(称为流量选择器 - TS):
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 1v2 "vpn.example.com" #1: STATE_PARENT_I2: sent v2I2, expected v2R2 {auth=IKEv2 cipher=AES_GCM_16_256 integ=n/a prf=HMAC_SHA2_512 group=MODP2048} 002 "vpn.example.com" #2: IKE_AUTH response contained the error notification TS_UNACCEPTABLE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow IKEv1 的不匹配 IP 地址范围示例:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 031 "vpn.example.com" #2: STATE_QUICK_I1: 60 second timeout exceeded after 0 retransmits. No acceptable response to our first Quick Mode message: perhaps peer likes no proposal
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 当在 IKEv1 中使用预共享密钥(PSK)时,如果双方没有放入相同的 PSK ,则整个 IKE 信息将无法读取:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 003 "vpn.example.com" #1: received Hash Payload does not match computed value 223 "vpn.example.com" #1: sending notification INVALID_HASH_INFORMATION to 192.0.2.23:500
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 IKEv2 中,不匹配-PSK 错误会导致 AUTHENTICATION_FAILED 信息:
ipsec auto --up vpn.example.com
# ipsec auto --up vpn.example.com ... 002 "vpn.example.com" #1: IKE SA authentication request rejected by peer: AUTHENTICATION_FAILED
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
最大传输单元
除防火墙阻止 IKE 或 IPsec 数据包外,网络问题的最常见原因与加密数据包的数据包大小增加有关。网络硬件对于大于最大传输单元(MTU)的数据包进行分片处理,例如 1500 字节。通常,片会丢失,数据包无法重新组装。当使用小数据包的 ping 测试可以正常工作,但其他流量失败时,这会导致间歇性故障。在这种情况下,您可以建立一个 SSH 会话,但是一使用它,终端就会冻结,例如,在远程主机上输入 'ls -al /usr' 命令。
要临时解决这个问题,请通过将 mtu=1400
选项添加到隧道配置文件中来减小 MTU 大小。
另外,对于 TCP 连接,启用更改 MSS 值的 iptables 规则:
iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
如果上一命令没有解决您场景中的问题,请在 set-mss
参数中直接指定较小的数值:
iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
# iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
网络地址转换(NAT)
当 IPsec 主机也充当 NAT 路由器时,可能会意外地重新映射数据包。以下示例配置演示了这个问题:
地址为 172.16.0.1 的系统有一个 NAT 规则:
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
如果地址为 10.0.2.33 的系统将数据包发送到 192.168.0.1,那么路由器会在应用 IPsec 加密前将源 10.0.2.33 转换为 172.16.0.1。
然后,源地址为 10.0.2.33 的数据包不再与 conn myvpn
配置匹配, IPsec 不会加密此数据包。
要解决这个问题,请在路由器上插入目标 IPsec 子网范围不包含 NAT 的规则,例如:
iptables -t nat -I POSTROUTING -s 10.0.2.0/24 -d 192.168.0.0/16 -j RETURN
iptables -t nat -I POSTROUTING -s 10.0.2.0/24 -d 192.168.0.0/16 -j RETURN
内核 IPsec 子系统错误
例如,当 bug 导致 IKE 用户空间和 IPsec 内核不同步时,内核 IPsec 子系统可能会失败。检查此问题:
cat /proc/net/xfrm_stat XfrmInError 0 XfrmInBufferError 0 ...
$ cat /proc/net/xfrm_stat
XfrmInError 0
XfrmInBufferError 0
...
上一命令输出中的任何非零值都表示有问题。如果您遇到这个问题,请开一个新的 支持问题单,并附上上一命令的输出与对应的 IKE 日志。
libreswan 日志
默认情况下,Libreswan 使用 syslog
协议的日志。您可以使用 journalctl
命令来查找与 IPsec 有关的日志条目。因为日志中相应的条目是由 pluto
IKE 守护进程发送的,因此请搜索 "pluto" 关键字,例如:
journalctl -b | grep pluto
$ journalctl -b | grep pluto
显示 ipsec
服务的实时日志:
journalctl -f -u ipsec
$ journalctl -f -u ipsec
如果默认日志记录级别没有显示您的配置问题,请将 plutodebug=all
选项添加到 /etc/ipsec.conf
文件的 config setup
部分来启用调试日志。
请注意,调试日志记录会生成大量的条目,journald
或 syslogd
服务的速率可能会抑制 syslog
消息。要确保您有完整的日志,请将日志记录重定向到文件中。编辑 /etc/ipsec.conf
,并在 config setup
部分中添加 logfile=/var/log/pluto.log
。
5.16. 使用 control-center 配置 VPN 连接 复制链接链接已复制到粘贴板!
如果使用带有图形界面的 Red Hat Enterprise Linux ,您可以在 GNOME control-center
中配置 VPN 连接。
先决条件
-
已安装
NetworkManager-libreswan-gnome
软件包。
流程
-
按 Super 键,输入
Settings
,然后按 Enter 键打开control-center
应用程序。 -
选择左侧的
Network
条目。 - 点 + 图标。
-
选择
VPN
。 选择
Identity
菜单项来查看基本配置选项:一般的
Gateway
- 远程 VPN 网关的名称或IP
地址。身份验证
Type
-
IKEv2(证书)
- 客户端通过证书进行身份验证。它更安全(默认)。 IKEv1(XAUTH)
- 客户端通过用户名和密码或预共享密钥(PSK)进行身份验证。以下配置设置在
高级
部分中提供:图 5.1. VPN 连接的高级选项
警告当使用
gnome-control-center
应用程序配置基于 IPsec 的 VPN 连接时,高级
对话框会显示配置,但它不允许任何更改。因此,用户无法更改任何高级 IPsec 选项。使用nm-connection-editor
或nmcli
工具来配置高级属性。识别
Domain
-如果需要,请输入域名。安全性
-
Phase1 Algorithms
- 对应于ike
Libreswan 参数 - 输入要用来验证的算法,并设置加密渠道。 Phase2 Algorithms
- 对应于esp
Libreswan 参数 - 输入用于IPsec
协商的算法。选择
Disable PFS
字段来关闭 Perfect Forward Secrecy(PFS),以确保与不支持 PFS 的旧服务器兼容。-
Phase1 Lifetime
- 对应于ikelifetime
Libreswan 参数 - 用于加密流量的密钥的有效期有多长。 Phase2 Lifetime
- 对应于salifetime
Libreswan 参数 - 连接的特定实例在过期前应持续多长时间。注意:为了安全起见,加密密钥应该不时地更改。
Remote network
- 对应于rightsubnet
Libreswan 参数 - 应该通过 VPN 访问的目标私有远程网络。检查
narrowing
字段以启用缩小。请注意,它只在 IKEv2 协商中有效。-
Enable fragmentation
- 对应于fragmentation
Libreswan 参数 - 是否允许 IKE 分片。有效值为yes
(默认)或no
。 -
Enable Mobike
- 对应于mobike
Libreswan 参数 - 是否允许移动和多宿主协议(MOBIKE、RFC 4555)启用连接来迁移其端点,而无需从头开始重启连接。这可用于在有线、无线或者移动数据连接之间进行切换的移动设备。值为no
(默认)或yes
。
-
选择
菜单条目:IPv4 方法
-
Automatic (DHCP)
- 如果您要连接的网络使用DHCP
服务器来分配动态IP
地址,请选择此选项。 -
Link-Local Only
- 如果您要连接的网络没有DHCP
服务器且您不想手动分配IP
地址,请选择此选项。随机地址将根据 RFC 3927 分配,带有前缀169.254/16
。 -
Manual
- 如果要手动分配IP
地址,请选择此选项。 Disable
- 对此连接禁用了IPv4
。DNS
在
DNS
部分,当Automatic
为ON
时,将其切换到OFF
以输入您要用逗号分开的 DNS 服务器的 IP 地址。Routes
请注意,在
Routes
部分,当Automatic
为ON
时,会使用 DHCP 的路由,但您也可以添加额外的静态路由。当OFF
时,只使用静态路由。-
address
- 输入远程网络或主机的IP
地址。 -
netmask
- 上面输入的IP
地址的子网掩码或前缀长度。 -
Gateway
- 到上面输入的远程网络或主机的网关的IP
地址。 Metric
- 网络成本,赋予此路由的首选值。数值越低,优先级越高。仅将此连接用于其网络上的资源
选择这个复选框以防止连接成为默认路由。选择这个选项意味着只有特别用于路由的流量才会通过连接自动获得,或者手动输入到连接上。
-
要在
VPN
连接中配置IPv6
设置,请选择 菜单条目:IPv6 方法
-
Automatic
选择此选项以使用IPv6
无状态地址自动配置(SLAAC),来根据硬件地址和路由器公告(RA)创建一个自动的、无状态的配置。 -
Automatic, DHCP only
- 选择此选项以便不使用 RA,但从DHCPv6
直接请求信息,以创建有状态的配置。 -
Link-Local Only
- 如果您要连接的网络没有DHCP
服务器且您不想手动分配IP
地址,请选择此选项。随机地址将根据 RFC 4862 分配,前缀为FE80::0
。 -
Manual
- 如果要手动分配IP
地址,请选择此选项。 Disable
- 对此连接禁用了IPv6
。请注意,
DNS
,Routes
,Use this connection only for resources on its network
项是IPv4
的常规设置。
-
-
编辑完
VPN
连接后,点 按钮自定义配置或 按钮为现有配置保存它。 -
将配置文件切换到
ON
以激活VPN
连接。 - 如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
5.17. 使用 nm-connection-editor 配置 VPN 连接 复制链接链接已复制到粘贴板!
如果使用带有图形界面的 Red Hat Enterprise Linux ,您可以在 nm-connection-editor
应用程序中配置 VPN 连接。
先决条件
-
已安装
NetworkManager-libreswan-gnome
软件包。 如果您配置了互联网密钥交换版本 2(IKEv2)连接:
- 证书导入到 IPsec 网络安全服务(NSS)数据库中。
- NSS 数据库中的证书 nickname 是已知的。
流程
打开终端窗口,输入:
nm-connection-editor
$ nm-connection-editor
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 点击 按钮来添加一个新的连接。
-
选择
IPsec based VPN
连接类型,然后点击 。 在
VPN
选项卡中:在
Gateway
字段中输入 VPN 网关的主机名或 IP 地址,然后选择验证类型。根据验证类型,您必须输入不同的额外信息:-
IKEv2(认证)
使用证书验证客户端,这会更安全。这个设置需要在 IPsec NSS 数据库中指定证书的 nickname IKEv1(XAUTH)
使用用户名和密码(预共享密钥)验证用户身份。此设置要求您输入以下值:- 用户名
- 密码
- 组名称
- Secret
-
如果远程服务器为 IKE 交换指定了本地标识符,在
Remote ID
字段中输入准确的字符串。在运行 Libreswan 的远程服务器中,这个值是在服务器的leftid
参数中设置的。可选:点
按钮来配置其他设置。您可以配置以下设置:识别
-
域
-如果需要,请输入域名。
-
安全性
-
Phase1 Algorithms
对应于 ikeLibreswan
参数。输入用来验证和设置加密频道的算法。 Phase2 Algorithms
对应于esp
Libreswan 参数。输入用于IPsec
协商的算法。选择
Disable PFS
字段来关闭 Perfect Forward Secrecy(PFS),以确保与不支持 PFS 的旧服务器兼容。-
Phase1 Lifetime
与ikelifetime
Libreswan 参数对应。此参数定义用于加密流量的密钥的有效期。 -
Phase2 Lifetime
与salifetime
Libreswan 参数对应。这个参数定义安全关联有效期。
-
连接性
远程网络
与rightsubnet
Libreswan 参数对应,并定义应通过 VPN 访问的目标专用远程网络。检查
缩减
字段以启用缩小字段。请注意,它只在 IKEv2 协商中有效。-
Enable fragmentation
与segmentation
Libreswan 参数对应,并定义是否允许 IKE 分段。有效值为yes
(默认)或no
。 -
Enable Mobike
与mobike
参数对应。参数定义是否允许移动和多宿主协议(MOBIKE) (RFC 4555)启用连接来迁移其端点,而无需从头开始重启连接。这可用于在有线、无线或者移动数据连接之间进行切换的移动设备。值为no
(默认)或yes
。
在
IPv4 Settings
选项卡中,选择 IP 分配方法,并可选择设置额外的静态地址、DNS 服务器、搜索域和路由。- 保存连接。
-
关闭
nm-connection-editor
。 - 如果您在具有 DHCP 或无状态地址自动配置(SLAAC)的网络中使用此主机,则连接可能容易被重定向。有关详情和缓解步骤,请参阅将 VPN 连接分配给专用路由表,以防止连接绕过隧道。
当您点 NetworkManager 会为那个连接创建新配置文件,然后打开同一个对话框来编辑现有连接。这两个对话框之间的区别在于现有连接配置集有详情菜单条目。
按钮添加新连接时,5.18. 将 VPN 连接分配给专用的路由表,以防止连接绕过隧道 复制链接链接已复制到粘贴板!
DHCP 服务器和无状态地址自动配置(SLAAC)都可以将路由添加到客户端的路由表中。例如,恶意的 DHCP 服务器可以使用此功能强制带有 VPN 连接的主机通过物理接口而不是 VPN 隧道重定向流量。此漏洞也称为 TunnelVision,并在 CVE-2024-3661 漏洞文章中进行了描述。
要缓解此漏洞,您可以将 VPN 连接分配给一个专用的路由表。这防止 DHCP 配置或 SLAAC 操纵用于 VPN 隧道的网络数据包的路由决策。
如果至少有一个条件适用您的环境,请按照以下步骤操作:
- 至少有一个网络接口使用 DHCP 或 SLAAC。
- 您的网络不使用阻止恶意 DHCP 服务器的机制,如 DHCP 侦听。
通过 VPN 路由整个流量可防止主机访问本地网络资源。
先决条件
- 您可以使用 NetworkManager 1.40.16-18 或更高版本。
流程
- 决定您要使用哪个路由表。以下步骤使用表 75。默认情况下,RHEL 不使用表 1-254,您可以使用其中任何一个。
配置 VPN 连接配置文件,来将 VPN 路由放在专用的路由表中:
nmcli connection modify <vpn_connection_profile> ipv4.route-table 75 ipv6.route-table 75
# nmcli connection modify <vpn_connection_profile> ipv4.route-table 75 ipv6.route-table 75
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为您在之前的命令中使用的表设置一个低优先级值:
nmcli connection modify <vpn_connection_profile> ipv4.routing-rules "priority 32345 from all table 75" ipv6.routing-rules "priority 32345 from all table 75"
# nmcli connection modify <vpn_connection_profile> ipv4.routing-rules "priority 32345 from all table 75" ipv6.routing-rules "priority 32345 from all table 75"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 优先级值可以是 1 到 32766 之间的任何值。值越低,优先级越高。
重新连接 VPN 连接:
nmcli connection down <vpn_connection_profile> nmcli connection up <vpn_connection_profile>
# nmcli connection down <vpn_connection_profile> # nmcli connection up <vpn_connection_profile>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
显示表 75 中的 IPv4 路由:
ip route show table 75
# ip route show table 75 ... 192.0.2.0/24 via 192.0.2.254 dev vpn_device proto static metric 50 default dev vpn_device proto static scope link metric 50
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出确认到远程网络和默认网关的路由被分配到路由表 75,因此所有流量都是通过隧道路由的。如果您在 VPN 连接配置文件中设置了
ipv4.never-default true
,则不会创建默认路由,因此在此输出中不可见。显示表 75 中的 IPv6 路由:
ip -6 route show table 75
# ip -6 route show table 75 ... 2001:db8:1::/64 dev vpn_device proto kernel metric 50 pref medium default dev vpn_device proto static metric 50 pref medium
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出确认到远程网络和默认网关的路由被分配到路由表 75,因此所有流量都是通过隧道路由的。如果您在 VPN 连接配置文件中设置了
ipv4.never-default true
,则不会创建默认路由,因此在此输出中不可见。
第 6 章 使用 MACsec 加密同一物理网络中的第 2 层流量 复制链接链接已复制到粘贴板!
您可以使用 MACsec 来保护两个设备(点到点)之间的通信。例如,您的分支办公室通过城际以太网与中心办公室连接,您可以在连接办公室的两个主机上配置 MACsec,以提高安全性。
6.1. MACsec 如何提高安全性 复制链接链接已复制到粘贴板!
介质访问控制安全(MACsec)是一种 2 层协议,它保护以太网链路上的不同流量类型,包括:
- 动态主机配置协议(DHCP)
- 地址解析协议(ARP)
- IPv4 和 IPv6 流量
- 任何通过 IP 的流量,如 TCP 或 UDP
MACsec 默认使用 GCM-AES-128 算法加密并验证 LAN 中的所有流量,并使用预共享密钥在参与的主机之间建立连接。要更改预共享密钥,您必须更新所有使用 MACsec 的网络主机上的 NM 配置。
MACsec 连接使用yige 以太网设备,如以太网网卡、VLAN 或隧道设备作为父设备。您只能在 MACsec 设备上设置 IP 配置,以便只使用加密连接与其他主机进行通信,或者在父设备上设置 IP 配置。在后者的情况下,您可以使用父设备使用未加密连接和 MACsec 设备加密连接与其他主机通信。
macsec 不需要任何特殊硬件。例如,您可以使用任何交换机,除非您只想在主机和交换机之间加密流量。在这种情况下,交换机还必须支持 MACsec。
换句话说,您可以为两种常见场景配置 MACsec:
- host-to-host
- host-to-switch 和 switch-to-other-hosts
您只能在位于同一物理或虚拟 LAN 的主机之间使用 MACsec。
使用 MACsec 安全标准保护链路层的通信,也称为 Open Systems Interconnection (OSI)模型的第 2 层,提供以下显著优点:
- 第 2 层的加密消除了在第 7 层加密单个服务的需要。这减少了管理与每个主机上每个端点的大量证书关联的开销。
- 直接连接的网络设备(如路由器和交换机)之间的点对点安全性。
- 不需要对应用程序和高层协议进行更改。
6.2. 使用 nmcli 配置 MACsec 连接 复制链接链接已复制到粘贴板!
您可以使用 nmcli
工具将以太网接口配置为使用 MACsec。例如,您可以在通过以太网连接的两个主机之间创建一个 MACsec 连接。
流程
在配置 MACsec 的第一个主机上:
为预共享密钥创建连接关联密钥(CAK)和连接关联密钥名称(CKN):
创建一个 16 字节的十六进制 CAK:
dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' 50b71a8ef0bd5751ea76de6d6c98c03a
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建一个 32 字节的十六进制 CKN:
dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
- 在您要通过 MACsec 连接连接的两个主机上:
创建 MACsec 连接:
nmcli connection add type macsec con-name macsec0 ifname macsec0 connection.autoconnect yes macsec.parent enp1s0 macsec.mode psk macsec.mka-cak 50b71a8ef0bd5751ea76de6d6c98c03a macsec.mka-ckn f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
# nmcli connection add type macsec con-name macsec0 ifname macsec0 connection.autoconnect yes macsec.parent enp1s0 macsec.mode psk macsec.mka-cak 50b71a8ef0bd5751ea76de6d6c98c03a macsec.mka-ckn f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
macsec.mka-cak
和macsec.mka-ckn
参数中使用上一步生成的 CAK 和 CKN。在 MACsec-protected 网络的每个主机上,这些值必须相同。配置 MACsec 连接中的 IP 设置。
配置
IPv4
设置。例如,要为macsec0
连接设置静态IPv4
地址、网络掩码、默认网关和 DNS 服务器,请输入:nmcli connection modify macsec0 ipv4.method manual ipv4.addresses '192.0.2.1/24' ipv4.gateway '192.0.2.254' ipv4.dns '192.0.2.253'
# nmcli connection modify macsec0 ipv4.method manual ipv4.addresses '192.0.2.1/24' ipv4.gateway '192.0.2.254' ipv4.dns '192.0.2.253'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 配置
IPv6
设置。例如,要为macsec0
连接设置静态IPv6
地址、网络掩码、默认网关和 DNS 服务器,请输入:nmcli connection modify macsec0 ipv6.method manual ipv6.addresses '2001:db8:1::1/32' ipv6.gateway '2001:db8:1::fffe' ipv6.dns '2001:db8:1::fffd'
# nmcli connection modify macsec0 ipv6.method manual ipv6.addresses '2001:db8:1::1/32' ipv6.gateway '2001:db8:1::fffe' ipv6.dns '2001:db8:1::fffd'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
激活连接:
nmcli connection up macsec0
# nmcli connection up macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证流量是否加密:
tcpdump -nn -i enp1s0
# tcpdump -nn -i enp1s0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:显示未加密的流量:
tcpdump -nn -i macsec0
# tcpdump -nn -i macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示 MACsec 统计信息:
ip macsec show
# ip macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示每种保护类型的单独的计数器:仅完整性(关闭加密)和加密(打开加密)
ip -s macsec show
# ip -s macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
第 7 章 使用和配置 firewalld 复制链接链接已复制到粘贴板!
防火墙是保护机器不受来自外部的、不需要的网络数据影响的一种方式。它允许用户通过定义一组防火墙规则 来控制主机上的入站网络流量。这些规则用于对传入流量进行排序,并阻止它或允许它通过。
firewalld
是一个防火墙服务守护进程,它通过 D-Bus 接口提供动态、可自定义的防火墙。如果是动态的,它会在每次更改规则时启用、修改和删除规则,而无需在每次更改规则时重启防火墙守护进程。
您可以使用 firewalld
来配置大多数典型情况所需的数据包过滤。如果 firewalld
不涵盖您的场景,或者您想要完全控制规则,请使用 nftables
框架。
firewalld
使用区、策略和服务的概念来简化流量管理。区域以逻辑方式分隔网络。网络接口和源可以分配给区。策略用于拒绝或允许区域间的流量流。防火墙服务是预定义的规则,覆盖了允许特定服务的传入流量的所有必要设置,并在区域内应用。
服务使用一个或多个端口或地址进行网络通信。防火墙会根据端口过滤通讯。要允许服务的网络流量,必须打开其端口。firewalld
会阻止未明确设置为开放的端口上的所有流量。一些区(如可信区)默认允许所有流量。
firewalld
维护单独的运行时和永久配置。这允许仅运行时的更改。firewalld
重新加载或重启后,运行时配置不会保留。在启动时,它会填充自永久配置。
请注意,带有 nftables
后端的 firewalld
不支持使用- direct
选项将自定义 nftables
规则传递给 firewalld
。
7.1. 使用 firewalld、nftables 或者 iptables 时 复制链接链接已复制到粘贴板!
在 RHEL 8 中,您可以根据您的情况使用以下数据包过滤工具:
-
firewalld
:firewalld
工具简化了常见用例的防火墙配置。 -
nftables
:使用nftables
工具来设置复杂和性能关键的防火墙,如用于整个网络。 -
iptables
:Red Hat Enterprise Linux 上的iptables
工具使用nf_tables
内核 API 而不是传统的
后端。nf_tables
API 提供了向后兼容性,以便使用iptables
命令的脚本仍可在 Red Hat Enterprise Linux 上工作。对于新的防火墙脚本,请使用nftables
。
要防止不同的与防火墙相关的服务(firewalld
、nftables
或 iptables
)相互影响,请在 RHEL 主机上仅运行其中一个服务,并禁用其他服务。
7.2. 防火墙区域 复制链接链接已复制到粘贴板!
您可以根据您在该网络中所具有的接口和流量的信任级别,使用 firewalld
工具将网络划分为不同的区域。连接只能是区域的一部分,但您可以对许多网络连接使用这个区域。
firewalld
在区域方面遵循严格的原则:
- 流量只流入一个区域。
- 流量只流出一个区域。
- 一个区域定义一个信任级别。
- 默认允许区域内流量(在同一区域内)。
- 默认拒绝区域内流量(从区域到区域)。
原则 4 和 5 是原则 3 的结果。
原则 4 可以通过区域选项 --remove-forward
进行配置。原则 5 可以通过添加新策略进行配置。
NetworkManager
通知接口区的 firewalld
。您可以使用以下工具将区域分配给接口:
-
NetworkManager
-
firewall-config
工具 -
firewall-cmd
工具 - RHEL web 控制台
RHEL web 控制台、firewall-config
和 firewall-cmd
只能编辑合适的 NetworkManager
配置文件。如果您使用 web 控制台、firewall-cmd
或 firewall-config
更改接口的区域,则请求被转发到 NetworkManager
,且不是由 firewalld
处理。
/usr/lib/firewalld/zones/
目录存储预定义的区域,您可以立即将它们应用到任何可用的网络接口。只有在修改后,这些文件才会被拷贝到 /etc/firewalld/zones/
目录中。预定义区的默认设置如下:
block
-
适合于:任何传入的网络连接都会被拒绝,并对
IPv4
显示 icmp-host-prohibited 消息,对IPv6
显示 icmp6-adm-prohibited 消息。 - 接受:只有从系统内启动的网络连接。
-
适合于:任何传入的网络连接都会被拒绝,并对
dmz
- 适用于:您的 DMZ 中可使用访问您的内部网的有限权限公开访问的计算机。
- 接受: 只有所选的传入连接。
drop
适合于:任何被丢失,但没有任何通知的传入网络数据包。
- 接受:只有传出的网络连接。
external
- 适用于:启用了伪装的外部网络,特别是路由器。不信任网络上其他计算机的情况。
- 接受: 只有所选的传入连接。
home
- 适用于:家庭环境,其中您基本上信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
internal
- 适用于:内部网络,其中您基本上信任网络上其他计算机的。
- 接受: 只有所选的传入连接。
public
- 适用于:公共区域,其中您不信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
trusted
- 接受:所有网络连接。
work
适用于:工作环境,其中您大多信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
这些区中的一个被设置为 default 区。当接口连接被添加到 NetworkManager
中时,它们会被分配到默认区。安装时,firewalld
中的默认区域是 public
区域。您可以更改默认区域。
使网络区域名称一目了然,以帮助用户快速理解它们。
要避免安全问题,请查看默认区配置并根据您的需要和风险禁用任何不必要的服务。
7.3. 防火墙策略 复制链接链接已复制到粘贴板!
防火墙策略指定网络所需的安全状态。它们概述了对不同类型的流量要采取的规则和操作。通常,策略包含以下类型流量的规则:
- 传入流量
- 传出流量
- 转发流量
- 特定服务和应用程序
- 网络地址转换(NAT)
防火墙策略使用防火墙区域的概念。每个区域都与一组特定的、决定允许的流量的防火墙规则相关联。策略以一种有状态的、单向的方式应用防火墙规则。这意味着您只考虑流量的一个方向。由于 firewalld
的有状态过滤,流量返回路径被隐式允许。
策略与入口区域和出口区域相关联。入口区域是流量起源(接收)的地方。出口区域是流量离开(发送)的地方。
策略中定义的防火墙规则可以引用防火墙区,以便在多个网络接口中应用一致的配置。
7.4. 防火墙规则 复制链接链接已复制到粘贴板!
您可以使用防火墙规则实现特定的配置,以允许或阻止网络流量。因此,您可以控制网络流量的流动,以防止系统受到安全威胁。
防火墙规则通常根据各种属性定义某些标准。属性可以是:
- 源 IP 地址
- 目标 IP 地址
- 传输协议(TCP、UDP、…)
- 端口
- 网络接口
firewalld
工具将防火墙规则组织到区域( 如 public
、internal
等)和策略。每个区域都有自己的一组规则,其决定与特定区域关联的网络接口的流量自由度的级别。
7.5. 防火墙直接规则 复制链接链接已复制到粘贴板!
firewalld
服务提供多种配置规则的方法,包括:
- 常规规则
- 直接规则
这两者的一个区别在于,每个方法与底层后端(iptables
或 nftables
)交互的方式。
直接规则是高级低级别规则,允许直接与 iptables
交互。它们绕过 firewalld
的结构化管理,为您提供更多控制。您可以使用原始 iptables
语法使用 firewall-cmd
命令手动定义直接规则。例如,firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 198.51.100.1 -j DROP
。此命令添加了一个 iptables
规则来丢弃来自 198.51.100.1 源 IP 地址的流量。
但是,使用直接规则也具有其缺点。特别是当 nftables
是您的主要防火墙后端时。例如:
-
直接规则很难维护,并可能会与基于
nftables
的firewalld
配置冲突。 -
直接规则不支持您可以在
nftables
中找到的高级功能,如原始表达式和有状态对象。 -
直接规则不永不。
iptables
组件已弃用,最终将从 RHEL 中删除。
因此,您可以考虑使用 nftables
替换 firewalld
直接规则。查看知识库解决方案 如何将 firewalld 直接规则替换为 nftables? 以查看更多详情。
7.6. 预定义的 firewalld 服务 复制链接链接已复制到粘贴板!
预定义的 firewalld
服务在低级防火墙规则中提供内置抽象层。它通过将常用的网络服务(如 SSH 或 HTTP)映射到其相应的端口和协议来实现。您可以引用一个命名的预定义服务,而不是每次手动指定它们。这使得防火墙管理变得更加简单、不易出错且更直观。
要查看可用的预定义服务:
firewall-cmd --get-services
# firewall-cmd --get-services RH-Satellite-6 RH-Satellite-6-capsule afp amanda-client amanda-k5-client amqp amqps apcupsd audit ausweisapp2 bacula bacula-client bareos-director bareos-filedaemon bareos-storage bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-exporter ceph-mon cfengine checkmk-agent cockpit collectd condor-collector cratedb ctdb dds...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要进一步检查特定的预定义服务:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例输出显示
RH-Satellite-6
预定义服务侦听端口 5000/tcp 5646-5647/tcp 5671/tcp 8000/tcp 8080/tcp 9090/tcp。另外,RH-Satellite-6
继承了其他预定义服务中的规则。在本例中为foreman。
每个预定义的服务都以同名的 XML 文件存储在 /usr/lib/firewalld/services/
目录中。
7.7. 使用 firewalld 区域 复制链接链接已复制到粘贴板!
zones 代表一种更透明管理传入流量的概念。这些区域连接到联网接口或者分配一系列源地址。您可以独立为每个区管理防火墙规则,这样就可以定义复杂的防火墙设置并将其应用到流量。
7.7.1. 为特定区域自定义防火墙设置来增强安全性 复制链接链接已复制到粘贴板!
您可以通过修改防火墙设置,并将特定的网络接口或连接与特定的防火墙区域关联来加强网络安全性。通过为一个区域定义细粒度规则和限制,您可以根据预期的安全级别控制入站和出站流量。
例如,您可以取得以下好处:
- 保护敏感数据
- 防止未授权访问
- 缓解潜在的网络威胁
先决条件
-
firewalld
服务在运行。
流程
列出可用的防火墙区域:
firewall-cmd --get-zones
# firewall-cmd --get-zones
Copy to Clipboard Copied! Toggle word wrap Toggle overflow firewall-cmd --get-zones
命令显示系统上所有可用的区,但不显示特定区的详情。要查看所有区域的详情,请使用firewall-cmd --list-all-zones
命令。- 选择您要用于此配置的区域。
修改所选区域的防火墙设置。例如,要允许
SSH
服务并删除ftp
服务:firewall-cmd --add-service=ssh --zone=<your_chosen_zone> firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>
# firewall-cmd --add-service=ssh --zone=<your_chosen_zone> # firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向防火墙区域分配一个网络接口:
列出可用的网络接口:
firewall-cmd --get-active-zones
# firewall-cmd --get-active-zones
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 区域的活动是由网络接口或匹配其配置的源地址范围的存在来确定的。默认区域对于未分类的流量是处于活跃状态的,但如果没有流量匹配其规则,则不总是处于活跃状态。
向所选区分配一个网络接口:
firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanent
# firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向区域分配一个网络接口更适合于将一致的防火墙设置应用到特定接口(物理的或虚拟的)上的所有流量。
当与
--permanent
选项一起使用时,firewall-cmd
命令通常涉及更新 NetworkManager 连接配置文件,以使对防火墙配置的更改永久。firewalld
和 NetworkManager 之间的这种集成确保一致的网络和防火墙设置。
验证
显示您选择的区域的更新设置:
firewall-cmd --zone=<your_chosen_zone> --list-all
# firewall-cmd --zone=<your_chosen_zone> --list-all
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令输出显示所有区域设置,包括分配的服务、网络接口和网络连接(源)。
7.7.2. 更改默认区 复制链接链接已复制到粘贴板!
系统管理员在其配置文件中为网络接口分配区域。如果接口没有被分配给指定区,它将被分配给默认区。每次重启 firewalld
服务后,firewalld
会加载默认区的设置,并使其处于活动状态。请注意,所有其他区域的设置都被保留,并可使用。
通常,区域会被 NetworkManager 按照 NetworkManager 连接配置文件中的 connection.zone
设置分配给接口。另外,重启后,NetworkManager 会管理“激活”这些区域的分配。
先决条件
-
firewalld
服务在运行。
流程
设置默认区:
显示当前的默认区:
firewall-cmd --get-default-zone
# firewall-cmd --get-default-zone
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 设置新的默认区:
firewall-cmd --set-default-zone <zone_name>
# firewall-cmd --set-default-zone <zone_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意按照此流程,设置是一个永久设置,即使没有
--permanent
选项。
7.7.3. 将网络接口分配给区 复制链接链接已复制到粘贴板!
可以为不同区定义不同的规则集,然后通过更改所使用的接口的区来快速改变设置。使用多个接口,可以为每个具体区设置一个区来区分通过它们的网络流量。
流程
要将区分配给特定的接口:
列出活跃区以及分配给它们的接口:
firewall-cmd --get-active-zones
# firewall-cmd --get-active-zones
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为不同的区分配接口:
firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
# firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.4. 添加源 复制链接链接已复制到粘贴板!
要将传入的流量路由到特定区,请将源添加到那个区。源可以是一个使用 CIDR 格式的 IP 地址或 IP 掩码。
如果您添加多个带有重叠网络范围的区域,则根据区名称排序,且只考虑第一个区。
在当前区中设置源:
firewall-cmd --add-source=<source>
# firewall-cmd --add-source=<source>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要为特定区设置源 IP 地址:
firewall-cmd --zone=zone-name --add-source=<source>
# firewall-cmd --zone=zone-name --add-source=<source>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
以下流程允许来自 受信任
区中 192.168.2.15 的所有传入的流量:
流程
列出所有可用区:
firewall-cmd --get-zones
# firewall-cmd --get-zones
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将源 IP 添加到持久性模式的信任区中:
firewall-cmd --zone=trusted --add-source=192.168.2.15
# firewall-cmd --zone=trusted --add-source=192.168.2.15
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使新设置具有持久性:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.5. 删除源 复制链接链接已复制到粘贴板!
当您从一个区域中删除源时,源自该源的流量不再通过为该源指定的规则进行引导。相反,流量会返回到与它源自的接口关联的区域的规则和设置,或转至默认区域。
流程
列出所需区的允许源:
firewall-cmd --zone=zone-name --list-sources
# firewall-cmd --zone=zone-name --list-sources
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 从区永久删除源:
firewall-cmd --zone=zone-name --remove-source=<source>
# firewall-cmd --zone=zone-name --remove-source=<source>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使新设置具有持久性:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.6. 使用 nmcli 为连接分配区域 复制链接链接已复制到粘贴板!
您可以使用 nmcli
工具将 firewalld
区域添加到 NetworkManager
连接。
流程
将区分配给
NetworkManager
连接配置文件:nmcli connection modify profile connection.zone zone_name
# nmcli connection modify profile connection.zone zone_name
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 激活连接:
nmcli connection up profile
# nmcli connection up profile
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.7. 在 ifcfg 文件中手动将区分配给网络连接 复制链接链接已复制到粘贴板!
当连接由 NetworkManager 管理时,必须了解它使用的区。对于每个网络连接配置文件,可以指定一个区域,其根据带有可移植设备的计算机的位置提供各种防火墙设置的灵活性。因此,可以为不同的位置(如公司或家)指定区域和设置。
流程
要为连接设置一个区,请编辑
/etc/sysconfig/network-scripts/ifcfg-connection_name
文件,并添加将区分配给这个连接的行:ZONE=zone_name
ZONE=zone_name
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.8. 创建一个新区 复制链接链接已复制到粘贴板!
要使用自定义区,创建一个新的区并使用它像预定义区一样。新区需要 --permanent
选项,否则命令无法工作。
先决条件
-
firewalld
服务在运行。
流程
创建一个新区:
firewall-cmd --permanent --new-zone=zone-name
# firewall-cmd --permanent --new-zone=zone-name
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使新区域可用:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令将最新的更改应用到防火墙配置,而不中断已在运行的网络服务。
验证
检查是否在您的永久设置中添加了新的区:
firewall-cmd --get-zones --permanent
# firewall-cmd --get-zones --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.9. 使用 Web 控制台启用区域 复制链接链接已复制到粘贴板!
您可以通过 RHEL web 控制台对特定接口或 IP 地址范围应用预定义和现有的防火墙区域。
先决条件
- 您已安装了 RHEL 8 web 控制台。
- 您已启用了 cockpit 服务。
您的用户帐户被允许登录到 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
流程
登录到 RHEL 8 web 控制台。
详情请参阅 登录到 web 控制台。
- 点 Networking。
点
按钮。如果没有看到
按钮,使用管理员权限登录到 web 控制台。- 在 Firewall 部分,点 Add new zone。
在 Add zone 对话框中,从信任级别选项选择一个区。
Web 控制台显示
firewalld
服务中预定义的所有区域。- 在接口部分,选择一个应用所选区的接口或接口。
在 Allowed Addresses 部分中,您可以选择是否应用该区:
- 整个子网
或者以以下格式表示的 IP 地址范围:
- 192.168.1.0
- 192.168.1.0/24
- 192.168.1.0/24, 192.168.1.0
点
按钮。
验证
检查 Firewall 部分中的配置:
7.7.10. 使用 Web 控制台禁用区域 复制链接链接已复制到粘贴板!
您可以使用 Web 控制台在防火墙配置中禁用一个防火墙区域。
先决条件
- 您已安装了 RHEL 8 web 控制台。
- 您已启用了 cockpit 服务。
您的用户帐户被允许登录到 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
流程
登录到 RHEL 8 web 控制台。
详情请参阅 登录到 web 控制台。
- 点 Networking。
点
按钮。如果没有看到
按钮,使用管理员权限登录到 web 控制台。点您要删除的区的 Options 图标。
- 点击 Delete。
区域现在被禁用,接口不包括在区域中配置的打开的服务和端口。
7.7.11. 使用区目标设定传入流量的默认行为 复制链接链接已复制到粘贴板!
对于每个区,您可以设置一种处理尚未进一步指定的传入流量的默认行为。此行为是通过设置区的目标来定义的。有四个选项:
-
ACCEPT
:接受所有传入的数据包,除了特定规则禁止的。 -
REJECT
:拒绝所有传入的数据包,除了特定规则允许的。当firewalld
拒绝数据包时,会告知源机器有关拒绝的信息。 -
DROP
:丢弃所有传入的数据包,除了特定规则允许的。当firewalld
丢弃数据包时,不会告知源机器有关丢弃数据包的信息。 -
default
:与REJECT
的行为类似,但在某些情况下具有特殊含义。
先决条件
-
firewalld
服务在运行。
流程
为区设置目标:
列出特定区的信息以查看默认目标:
firewall-cmd --zone=zone-name --list-all
# firewall-cmd --zone=zone-name --list-all
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在区中设置一个新目标:
firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
# firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.7.12. 使用 IP 集为允许列表配置动态更新 复制链接链接已复制到粘贴板!
您可以进行接近实时的更新,来灵活地允许 IP 集中特定的 IP 地址或范围,即使在无法预计的情况下也是如此。这些更新可以被各种事件触发,如检测安全威胁或更改网络行为。通常,此类解决方案利用自动化来减少手工工作,并通过快速响应情况来提高安全性。
先决条件
-
firewalld
服务在运行。
流程
创建一个有有意义名称的 IP 集:
firewall-cmd --permanent --new-ipset=allowlist --type=hash:ip
# firewall-cmd --permanent --new-ipset=allowlist --type=hash:ip
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 名为
allowlist
的新 IP 集包含您希望防火墙允许的 IP 地址。向 IP 集添加动态更新:
firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10
# firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此配置使用新添加的 IP 地址更新防火墙允许传输网络流量的
allowlist
IP 集。创建一个引用之前创建的 IP 集的防火墙规则:
firewall-cmd --permanent --zone=public --add-source=ipset:allowlist
# firewall-cmd --permanent --zone=public --add-source=ipset:allowlist
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 没有此规则,IP 集不会对网络流量有任何影响。默认防火墙策略将占先。
重新载入防火墙配置以应用更改:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
列出所有 IP 集:
firewall-cmd --get-ipsets
# firewall-cmd --get-ipsets allowlist
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 列出活跃的规则:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令行输出的
sources
部分提供了对哪些流量源(主机名、接口、IP 集、子网等)被允许或拒绝访问特定防火墙区域的见解。在这种情况下,包含在allowlist
IP 集中的 IP 地址被允许通过防火墙,为public
区域传输流量。探索 IP 集的内容:
cat /etc/firewalld/ipsets/allowlist.xml <?xml version="1.0" encoding="utf-8"?> <ipset type="hash:ip"> <entry>198.51.100.10</entry> </ipset>
# cat /etc/firewalld/ipsets/allowlist.xml <?xml version="1.0" encoding="utf-8"?> <ipset type="hash:ip"> <entry>198.51.100.10</entry> </ipset>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
后续步骤
-
使用脚本或安全工具获取您的威胁情报源,并以一种自动化的方式更新
allowlist
。
7.8. 使用 firewalld 控制网络流量 复制链接链接已复制到粘贴板!
firewalld
软件包安装了大量预定义的服务文件,您可以添加更多或自定义它们。然后,您可以使用这些服务定义为服务打开或关闭端口,而无需了解协议及它们使用的端口号。
7.8.1. 使用 CLI 控制预定义服务的流量 复制链接链接已复制到粘贴板!
控制流量的最简单的方法是在 firewalld
中添加预定义的服务。这会打开所有必需的端口并根据 服务定义文件 修改其他设置。
先决条件
-
firewalld
服务在运行。
流程
检查
firewalld
中的服务是否还没有被允许:firewall-cmd --list-services
# firewall-cmd --list-services ssh dhcpv6-client
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令列出在默认区域中启用的服务。
列出
firewalld
中所有预定义的服务:firewall-cmd --get-services
# firewall-cmd --get-services RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令显示默认区域的可用服务的列表。
将服务添加到
firewalld
允许的服务的列表中:firewall-cmd --add-service=<service_name>
# firewall-cmd --add-service=<service_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令将指定的服务添加到默认区域中。
使新设置具有持久性:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令将这些运行时更改应用到防火墙的永久配置中。默认情况下,它将这些更改应用到默认区域的配置中。
验证
列出所有永久的防火墙规则:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令显示默认防火墙区域(
public
)的永久防火墙规则的完整配置。检查
firewalld
服务的永久配置的有效性。firewall-cmd --check-config
# firewall-cmd --check-config success
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果永久配置是无效的,命令会返回一个错误及更多详情:
firewall-cmd --check-config
# firewall-cmd --check-config Error: INVALID_PROTOCOL: 'public.xml': 'tcpx' not from {'tcp'|'udp'|'sctp'|'dccp'}
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您也可以手动检查永久配置文件,以验证设置。主配置文件为
/etc/firewalld/firewalld.conf
。特定于区域的配置文件在/etc/firewalld/zones/
目录中,策略在/etc/firewalld/policies/
目录中。
7.8.2. 使用 Web 控制台在防火墙上启用服务 复制链接链接已复制到粘贴板!
默认情况下,服务添加到默认防火墙区域。如果在更多网络接口中使用更多防火墙区,您必须首先选择一个区域,然后添加带有端口的服务。
RHEL 8 web 控制台显示预定义的 firewalld
服务,您可以将其添加到活跃的防火墙区。
RHEL 8 web 控制台配置 firewalld 服务。
Web 控制台不允许没有在 web 控制台中列出的通用 firewalld
规则。
先决条件
- 您已安装了 RHEL 8 web 控制台。
- 您已启用了 cockpit 服务。
您的用户帐户被允许登录到 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
流程
登录到 RHEL 8 web 控制台。
详情请参阅 登录到 web 控制台。
- 点 Networking。
点
按钮。如果没有看到
按钮,使用管理员权限登录到 web 控制台。在 Firewall 部分,选择要添加该服务的区,然后点击 Add Services。
- 在 Add Services 对话框中,找到您要在防火墙中启用的服务。
根据您的场景启用服务:
- 点 Add Services。
此时,RHEL 8 web 控制台在区域的服务列表中显示该服务。
7.8.3. 使用 Web 控制台配置自定义端口 复制链接链接已复制到粘贴板!
您可以通过 RHEL web 控制台为服务配置自定义端口。
先决条件
- 您已安装了 RHEL 8 web 控制台。
- 您已启用了 cockpit 服务。
您的用户帐户被允许登录到 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
-
firewalld
服务在运行。
流程
登录到 RHEL 8 web 控制台。
详情请参阅 登录到 web 控制台。
- 点 Networking。
点
按钮。如果没有看到
按钮,使用管理员权限登录到 web 控制台。在 Firewall 部分,选择要配置自定义端口的区域,并点 Add Services。
- 在 Add services 对话框中,点 单选按钮。
在 TCP 和 UDP 字段中,根据示例添加端口。您可以使用以下格式添加端口:
- 端口号,如 22
- 端口号范围,如 5900-5910
- 别名,比如 nfs, rsync
注意您可以在每个字段中添加多个值。值必须用逗号分开,且没有空格,例如: 8080、8081、http
在 TCP 文件、UDP 文件或两者中添加端口号后,在 Name 字段中验证服务名称。
Name 字段显示保留此端口的服务名称。如果您确定这个端口可用,且不需要在该端口上通信,则可以重写名称。
- 在 Name 字段中,为服务添加一个名称,包括定义的端口。
点
按钮。
要验证设置,请进入防火墙页面,并在区域的服务列表中找到该服务。
7.9. 在区域间过滤转发的流量 复制链接链接已复制到粘贴板!
firewalld
可让您控制不同 firewalld
区域之间的网络数据流。通过定义规则和策略,您可以管理流量在这些区域之间移动时是如何被允许或被拒绝的。
策略对象功能在 firewalld
中提供转发和输出过滤。您可以使用 firewalld
过滤不同区域之间的流量,以允许访问本地托管的虚拟机来连接主机。
7.9.1. 策略对象和区域之间的关系 复制链接链接已复制到粘贴板!
策略对象允许用户将 firewalld 的原语(如服务、端口和富规则)附加到策略。您可以将策略对象应用到以有状态和单向的方式在区域间传输的流量上。
firewall-cmd --permanent --new-policy myOutputPolicy firewall-cmd --permanent --policy myOutputPolicy --add-ingress-zone HOST firewall-cmd --permanent --policy myOutputPolicy --add-egress-zone ANY
# firewall-cmd --permanent --new-policy myOutputPolicy
# firewall-cmd --permanent --policy myOutputPolicy --add-ingress-zone HOST
# firewall-cmd --permanent --policy myOutputPolicy --add-egress-zone ANY
HOST
和 ANY
是 ingress 和 egress 区域列表中使用的符号区域。
-
HOST
符号区域对于来自运行 firewalld 的主机的流量,或具有到运行 firewalld 的主机的流量允许策略。 -
ANY
符号区对所有当前和将来的区域应用策略。ANY
符号区域充当所有区域的通配符。
7.9.2. 使用优先级对策略进行排序 复制链接链接已复制到粘贴板!
多个策略可以应用到同一组流量,因此应使用优先级为可能应用的策略创建优先级顺序。
要设置优先级来对策略进行排序:
firewall-cmd --permanent --policy mypolicy --set-priority -500
# firewall-cmd --permanent --policy mypolicy --set-priority -500
在上例中,-500 是较低的优先级值,但具有较高的优先级。因此,-500 将在 -100 之前执行。
较低数字的优先级值具有较高的优先级,被首先应用。
7.9.3. 使用策略对象过滤本地托管的容器和物理连接到主机的网络之间的流量 复制链接链接已复制到粘贴板!
策略对象功能允许用户过滤 Podman 和 firewalld 区域之间的流量。
红帽建议默认阻止所有流量,并打开 Podman 工具所需的可选择的服务。
流程
创建一个新的防火墙策略:
firewall-cmd --permanent --new-policy podmanToAny
# firewall-cmd --permanent --new-policy podmanToAny
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 阻止从 Podman 到其它区域的所有流量,并只允许 Podman 上必要的服务:
firewall-cmd --permanent --policy podmanToAny --set-target REJECT firewall-cmd --permanent --policy podmanToAny --add-service dhcp firewall-cmd --permanent --policy podmanToAny --add-service dns firewall-cmd --permanent --policy podmanToAny --add-service https
# firewall-cmd --permanent --policy podmanToAny --set-target REJECT # firewall-cmd --permanent --policy podmanToAny --add-service dhcp # firewall-cmd --permanent --policy podmanToAny --add-service dns # firewall-cmd --permanent --policy podmanToAny --add-service https
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建一个新的 Podman 区域:
firewall-cmd --permanent --new-zone=podman
# firewall-cmd --permanent --new-zone=podman
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为策略定义 ingress 区域:
firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podman
# firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podman
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为所有其他区域定义 egress 区域:
firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANY
# firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANY
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将 egress 区域设置为 ANY 意味着您可以从 Podman 过滤到其他区域。如果要过滤到主机,请将 egress 区域设置为 HOST。
重启 firewalld 服务:
systemctl restart firewalld
# systemctl restart firewalld
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证到其他区域的 Podman 防火墙策略:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.9.4. 设置策略对象的默认目标 复制链接链接已复制到粘贴板!
您可以为策略指定 --set-target 选项。可用的目标如下:
-
ACCEPT
- 接受数据包 -
DROP
- 丢弃不需要的数据包 -
REJECT
- 拒绝不需要的数据包,并带有 ICMP 回复 CONTINUE
(默认)- 数据包将遵循以下策略和区域中的规则。firewall-cmd --permanent --policy mypolicy --set-target CONTINUE
# firewall-cmd --permanent --policy mypolicy --set-target CONTINUE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证有关策略的信息
firewall-cmd --info-policy mypolicy
# firewall-cmd --info-policy mypolicy
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.10. 使用 firewalld 配置 NAT 复制链接链接已复制到粘贴板!
使用 firewalld
,您可以配置以下网络地址转换(NAT)类型:
- 伪装
- 目标 NAT(DNAT)
- 重定向
7.10.1. 网络地址转换类型 复制链接链接已复制到粘贴板!
这些是不同的网络地址转换(NAT)类型:
- 伪装
使用以上 NAT 类型之一更改数据包的源 IP 地址。例如,互联网服务提供商(ISP)不会路由私有 IP 范围,如
10.0.0.0/8
。如果您在网络中使用私有 IP 范围,用户应该能够访问互联网上的服务器,请将来自这些范围的数据包的源 IP 地址映射为公共 IP 地址。伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装。
- 目标 NAT(DNAT)
- 使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果您的 Web 服务器使用来自私有 IP 范围的 IP 地址,因此无法直接从互联网访问,您可以在路由器上设置 DNAT 规则,来将传入的流量重定向到此服务器。
- 重定向
- 这个类型是 DNAT 的一种特殊情况,其将数据包重定向到本地计算机上的不同端口。例如,如果服务运行在与其标准端口不同的端口上,您可以将传入的流量从标准端口重定向到此特定端口。
7.10.2. 配置 IP 地址伪装 复制链接链接已复制到粘贴板!
您可以在系统上启用 IP 伪装。在访问互联网时,IP 伪装会隐藏网关后面的单个机器。
流程
要检查是否启用了 IP 伪装(例如,对于
external
区),以root
用户身份输入以下命令:firewall-cmd --zone=external --query-masquerade
# firewall-cmd --zone=external --query-masquerade
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果已启用,命令将会打印
yes
,且退出状态为0
。否则,将打印no
,且退出状态为1
。如果省略了zone
,则将使用默认区。要启用 IP 伪装,请以
root
用户身份输入以下命令:firewall-cmd --zone=external --add-masquerade
# firewall-cmd --zone=external --add-masquerade
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
要使此设置持久,请将
--permanent
选项传给命令。 要禁用 IP 伪装,请以
root
身份输入以下命令:firewall-cmd --zone=external --remove-masquerade
# firewall-cmd --zone=external --remove-masquerade
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要使此设置永久生效,请将
--permanent
选项传给命令。
7.10.3. 使用 DNAT 转发传入的 HTTP 流量 复制链接链接已复制到粘贴板!
您可以使用目标网络地址转换(DNAT)将传入的流量从一个目标地址和端口定向到另一个目标地址和端口。通常,这对于将来自外部网络接口的传入请求重定向到特定的内部服务器或服务非常有用。
前提条件
-
firewalld
服务正在运行。
流程
转发传入的 HTTP 流量:
firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanent
# firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 之前的命令使用以下设置定义 DNAT 规则:
-
--zone=public
- 您为其配置 DNAT 规则的防火墙区域。您可以将其调整到您需要的任何区域。 -
--add-forward-port
- 指示您正在添加端口转发规则的选项。 -
port=80
- 外部目标端口。 -
proto=tcp
- 表示您转发 TCP 流量的协议。 -
toaddr=198.51.100.10
- 目标 IP 地址。 -
toport=8080
- 内部服务器的目标端口。 -
--permanent
- 使 DNAT 规则在重启后保持不变的选项。
-
重新载入防火墙配置以应用更改:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证您使用的用于防火墙区域的 DNAT 规则:
firewall-cmd --list-forward-ports --zone=public
# firewall-cmd --list-forward-ports --zone=public port=80:proto=tcp:toport=8080:toaddr=198.51.100.10
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 或者,查看相应的 XML 配置文件:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.10.4. 将来自非标准端口的流量重定向,以使 Web 服务在标准端口上可访问 复制链接链接已复制到粘贴板!
您可以使用重定向机制使在非标准端口上内部运行的 Web 服务可访问,而无需用户在 URL 中指定端口。因此,URL 更简单,并提供更好的浏览体验,而非标准端口仍在内部或用于特定的要求。
前提条件
-
firewalld
服务正在运行。
流程
创建 NAT 重定向规则:
firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanent
# firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 之前的命令使用以下设置定义 NAT 重定向规则:
-
--zone=public
- 您为其配置规则的防火墙区域。您可以将其调整到您需要的任何区域。 -
--add-forward-port=port=<non_standard_port>
- 指示您正在使用最初接收传入流量的源端口添加端口转发(重定向)规则。 -
proto=tcp
- 表示您重定向 TCP 流量的协议。 -
toport=<standard_port>
- 目标端口,在源端口上收到传入流量后,应将其重定向到的端口。 -
--permanent
- 使规则在重启后保持不变的选项。
-
重新载入防火墙配置以应用更改:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
验证您使用的防火墙区域的重定向规则:
firewall-cmd --list-forward-ports
# firewall-cmd --list-forward-ports port=8080:proto=tcp:toport=80:toaddr=
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 或者,查看相应的 XML 配置文件:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.11. 丰富规则的优先级 复制链接链接已复制到粘贴板!
富规则提供了一种更高级且更灵活的方法来定义防火墙规则。富规则特别有用,其中服务、端口等服务不足以表达复杂的防火墙规则。
富规则背后的概念:
- 粒度和灵活性
- 您可以根据更为具体的标准为网络流量定义详细条件。
- 规则结构
富规则由家族(IPv4 或 IPv6)组成,后跟条件和操作。
rule family="ipv4|ipv6" [conditions] [actions]
rule family="ipv4|ipv6" [conditions] [actions]
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - conditions
- 它们允许富规则仅在符合特定条件时才适用。
- 操作
- 您可以定义与条件匹配的网络流量发生的情况。
- 组合多个条件
- 您可以创建更为具体的和复杂的过滤。
- 分层控制和可重复利用
- 您可以将丰富的规则与其他防火墙机制(如区域或服务)相结合。
默认情况下,富规则是根据其规则操作进行组织的。例如,deny
规则优先于 allow
规则。富规则中的 priority
参数可让管理员对富规则及其执行顺序进行精细的控制。在使用 priority
参数时,规则首先按其优先级值以升序排序。当更多的规则有同样的 优先级
时,其顺序是由规则行动决定的,如果行动也相同,则顺序可以是未定义。
7.11.1. priority 参数如何将规则组织到不同的链 复制链接链接已复制到粘贴板!
您可以在富规则中将 priority
参数设置为 -32768
和 32767
之间的任意数,较低的数值具有较高的优先级。
firewalld
服务根据优先级值将规则组织到不同的链中:
-
优先级低于 0:规则被重定向到带有
_pre
后缀的链中。 -
优先级高于 0:规则被重定向到带有
_post
后缀的链中。 -
优先级等于 0:根据操作,规则会被重定向到带有
_log
、_deny
或_allow
操作的链中。
在这些子链中,firewalld
根据其优先级值对规则进行排序。
7.11.2. 设置丰富的规则的优先级 复制链接链接已复制到粘贴板!
以下是如何创建富规则的示例,该规则使用 priority
参数来记录其他规则不允许或拒绝的所有流量。您可以使用此规则标记意非预期的流量。
流程
添加一个带有非常低优先级的丰富规则来记录未由其他规则匹配的所有流量:
firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"'
# firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这个命令还将日志条目数量限制为每分钟
5
条。
验证
显示命令在上一步中创建的
nftables
规则:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.12. 启用 firewalld 区域中不同接口或源之间的流量转发 复制链接链接已复制到粘贴板!
区内转发是 firewalld
的一种功能,它允许 firewalld
区域内接口或源之间的流量转发。
7.12.1. 区内转发与默认目标设置为 ACCEPT 的区域之间的区别 复制链接链接已复制到粘贴板!
启用区域内转发后,单个 firewalld
区域中的流量可以从一个接口或源流到另一个接口或源。区指定接口和源的信任级别。如果信任级别相同,流量会保持在同一区域内。
在 firewalld
的默认区域中启用区域内转发仅适用于添加到当前默认区域的接口和源。
firewalld
使用不同的区域管理传入和传出流量。每个区域都有自己的一组规则和行为。例如,trusted
区域默认允许所有转发的流量。
其他区域可以有不同的默认行为。在标准区域中,当区域的目标被设置为 default
时,转发的流量通常默认被丢弃。
要控制流量如何在区域内的不同接口或源之间转发,请确保您理解并相应地配置了区域的目标。
7.12.2. 使用区内转发来在以太网和 Wi-Fi 网络间转发流量 复制链接链接已复制到粘贴板!
您可以使用区内转发来在同一 firewalld
区内的接口和源之间转发流量。此功能带来以下好处:
-
有线设备和无线设备间的无缝连接(您可以在连接到
enp1s0
的以太网网络和连接到wlp0s20
的 Wi-Fi 网络之间转发流量) - 支持灵活的工作环境
- 可被网络中的多个设备或用户访问和使用的共享资源(如打印机、数据库、网络连接的存储等)
- 高效的内部网络(如顺畅通信、减少的延迟、资源可访问性等)
您可以为单个 firewalld
区域启用此功能。
流程
在内核中启用数据包转发:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 确保您要在其间启用区域内转发的接口只分配到
internal
区域:firewall-cmd --get-active-zones
# firewall-cmd --get-active-zones
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果接口当前被分配给了不是
internal
的区,请重新分配它:firewall-cmd --zone=internal --change-interface=interface_name --permanent
# firewall-cmd --zone=internal --change-interface=interface_name --permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
enp1s0
和wlp0s20
接口添加到internal
区:firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20
# firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启用区域内部转发:
firewall-cmd --zone=internal --add-forward
# firewall-cmd --zone=internal --add-forward
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
以下验证要求 nmap-ncat
软件包已安装在两个主机上。
-
登录到与您启用了区域转发的主机的
enp1s0
接口位于同一网络的主机。 使用
ncat
启动 echo 服务来测试连接:ncat -e /usr/bin/cat -l 12345
# ncat -e /usr/bin/cat -l 12345
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
登录到与
wlp0s20
接口在同一网络的主机。 连接到在与
enp1s0
在同一网络的主机上运行的 echo 服务器:ncat <other_host> 12345
# ncat <other_host> 12345
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 输入一些内容并按 。验证文本是否被发送回来。
7.13. 使用 RHEL 系统角色配置 firewalld 复制链接链接已复制到粘贴板!
RHEL 系统角色是 Ansible 自动化工具的一组内容。此内容与 Ansible 自动化工具一起提供一个一致的配置接口,来一次远程管理多个系统。
rhel-system-roles
软件包包含 rhel-system-roles.firewall
RHEL 系统角色。此角色是为了自动配置 firewalld
服务而引入的。
使用 firewall
RHEL 系统角色,您可以配置许多不同的 firewalld
参数,例如:
- 区域
- 应允许数据包的服务
- 授予、拒绝或丢弃访问端口的流量
- 区域的端口或端口范围的转发
7.13.1. 使用 firewall RHEL 系统角色重置 firewalld 设置 复制链接链接已复制到粘贴板!
随着时间的推移,对防火墙配置的更新可能会积累到一定程度,从而导致意外的安全风险。使用 firewall
RHEL 系统角色,您可以以一种自动的方式将 firewalld
设置重置为其默认状态。这样,您可以有效地删除任何无意的或不安全的防火墙规则,并简化其管理。
前提条件
- 您已准备好控制节点和受管节点。
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
previous: replaced
删除所有现有的用户定义的设置,并将
firewalld
设置重置为默认值。如果将previous:replaced
参数与其他设置相结合,则firewall
角色会在应用新设置前删除所有现有设置。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md
文件。
验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
在控制节点上运行这个命令,来远程检查受管节点上的所有防火墙配置是否被重置为其默认值:
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
您可以使用 firewall
RHEL 系统角色远程配置将传入流量从一个本地端口转发到另一个本地端口。
例如,如果您有一个环境,其中多个服务在同一台机器上共存,且需要同样的默认端口,则可能会出现端口冲突。这些冲突可能会破坏服务并导致停机。使用 firewall
RHEL 系统角色,您可以高效地将流量转发到替代端口,以确保您的服务可以同时运行,而无需修改其配置。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例 playbook 中指定的设置包括如下:
forward_port: 8080/tcp;443
- 使用 TCP 协议进入到本地端口 8080 的流量被转发到端口 443。
runtime: true
启用运行时配置中的更改。默认值被设置为
true
。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md
文件。
验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
在控制节点上,运行以下命令来远程检查受管节点上的转发端口:
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports'
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports' managed-node-01.example.com | CHANGED | rc=0 >> port=8080:proto=tcp:toport=443:toaddr=
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.13.3. 使用 firewall RHEL 系统角色配置 firewalld DMZ 区域 复制链接链接已复制到粘贴板!
作为系统管理员,您可以使用 firewall
RHEL 系统角色在 enp1s0 接口上配置 dmz
区域,以允许到区域的 HTTPS
流量。这样,您可以让外部用户访问您的 web 服务器。
先决条件
- 您已准备好控制节点和受管节点。
- 您以可在受管主机上运行 playbook 的用户身份登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md
文件。验证 playbook 语法:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
在控制节点上,运行以下命令来远程检查有关受管节点上
dmz
区域的信息:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
第 8 章 nftables 入门 复制链接链接已复制到粘贴板!
如果您的场景不在 firewalld
涵盖的典型数据包过滤情况中,或者您希望完全控制规则,您可以使用 nftables
框架。
nftables
框架对数据包进行分类,它是 iptables
、ip6tables
、arptables
、ebtables
和 ipset
工具的继承者。与之前的数据包过滤工具相比,它在方便、特性和性能方面提供了大量改进,最重要的是:
- 内置查找表而不是线性处理
-
IPv4
和IPv6
协议的单一框架 - 通过事务,而不是获取、更新和存储整个规则集来更新内核规则集
-
支持在规则集(
nftrace
)和监控追踪事件(nft
)中调试和追踪 - 更加一致和压缩的语法,没有特定协议的扩展
- 用于第三方应用程序的 Netlink API
nftables
框架使用表来存储链。链包含执行动作的独立规则。nft
工具替换了之前数据包过滤框架中的所有工具。您可以使用 libnftables
库,通过 libnftnl
库与 nftables
Netlink API 进行低级交互。
要显示规则集变化的影响,请使用 nft list ruleset
命令。要清除内核规则集,请使用 nft flush ruleset
命令。请注意,这也可能会影响 iptables-nft
命令安装的规则集,因为它使用了同样的内核基础架构。
8.1. 创建和管理 nftables 表、链和规则 复制链接链接已复制到粘贴板!
您可以显示 nftables
规则集并管理它们。
8.1.1. nftables 表的基础知识 复制链接链接已复制到粘贴板!
nftables
中的表是一个包含链、规则、集合和其他对象集合的名字空间。
每个表都必须分配一个地址系列。地址系列定义此表处理的数据包类型。在创建表时,您可以设置以下地址系列之一:
-
ip
:仅匹配 IPv4 数据包。如果没有指定地址系列,这是默认设置。 -
ip6
:仅匹配 IPv6 数据包。 -
inet
:匹配 IPv4 和 IPv6 数据包。 -
arp
:匹配 IPv4 地址解析协议(ARP)数据包。 -
bridge
:匹配通过网桥设备的数据包。 -
netdev
:匹配来自入口的数据包。
如果要添加表,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
table <table_address_family> <table_name> { }
table <table_address_family> <table_name> { }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 shell 脚本中,使用:
nft add table <table_address_family> <table_name>
nft add table <table_address_family> <table_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.1.2. nftables 链的基础知识 复制链接链接已复制到粘贴板!
表由链组成,链又是规则的容器。存在以下两种规则类型:
- Base chain :您可以使用基本链作为来自网络堆栈的数据包的入口点。
-
Regular chain :您可以使用常规链作为
jump
目标,来更好地组织规则。
如果要向表中添加基本链,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 shell 脚本中,使用:
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为了避免 shell 将分号解释为命令的结尾,请将
\
转义字符放在分号前面。
这两个示例都创建 基本链。要创建 常规链,请不要在大括号中设置任何参数。
链类型
以下是链类型以及您可以使用的地址系列和钩子的概述:
类型 | 地址系列 | Hook | 描述 |
---|---|---|---|
| all | all | 标准链类型 |
|
|
| 这个类型的链根据连接跟踪条目执行原生地址转换。只有第一个数据包会遍历此链类型。 |
|
|
| 如果 IP 头的相关部分已更改,则接受的遍历此链类型的数据包会导致新的路由查找。 |
链优先级
priority 参数指定数据包遍历具有相同 hook 值的链的顺序。您可以将此参数设为整数值,或使用标准优先级名称。
以下列表是标准优先级名称及其数字值的一个概述,以及您可以使用它们的哪个地址系列和钩子:
文本值 | 数字值 | 地址系列 | 钩子 |
---|---|---|---|
|
|
| all |
|
|
| all |
|
|
|
|
|
|
| |
|
|
| all |
|
| all | |
|
|
| all |
|
|
|
|
|
|
| |
|
|
|
|
链策略
如果此链中的规则没有指定任何操作,则链策略定义 nftables
是否应该接受或丢弃数据包。您可以在链中设置以下策略之一:
-
accept
(默认) -
drop
8.1.3. nftables 规则的基础知识 复制链接链接已复制到粘贴板!
规则定义对通过包含此规则的链的数据包执行的操作。如果规则还包含匹配表达式,则 nftables
仅在所有之前的表达式都应用时才执行操作。
如果要在链中添加一条规则,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 shell 脚本中,使用:
nft add rule <table_address_family> <table_name> <chain_name> <rule>
nft add rule <table_address_family> <table_name> <chain_name> <rule>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此 shell 命令在链的末尾附加新规则。如果要在链的开头添加一条规则,请使用
nft insert
命令而不是nft add
。
8.1.4. 使用 nft 命令管理表、链和规则 复制链接链接已复制到粘贴板!
要在命令行上或 shell 脚本中管理 nftables
防火墙,请使用 nft
工具。
此流程中的命令不代表典型的工作流,且没有被优化。此流程只演示了如何使用 nft
命令来管理表、链和规则。
流程
创建一个带有
inet
地址系列的名为nftables_svc
的表,以便表可以处理 IPv4 和 IPv6 数据包:nft add table inet nftables_svc
# nft add table inet nftables_svc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将处理传入网络流量的、名为
INPUT
的基本链添加到inet nftables_svc
表中:nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }
# nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为了避免 shell 将分号解释为命令的结尾,请使用
\
字符转义分号。向
INPUT
链添加规则。例如,允许端口 22 和 443 上的传入 TCP 流量,并作为INPUT
链的最后一条规则,拒绝其他传入的流量,并伴有互联网控制消息协议(ICMP)端口无法访问的消息:nft add rule inet nftables_svc INPUT tcp dport 22 accept nft add rule inet nftables_svc INPUT tcp dport 443 accept nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
# nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您输入
nft add rule
命令,则nft
会将按与运行命令相同的顺序将规则添加到链。显示包括句柄的当前规则集:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在句柄为 3 的现有规则前面插入一条规则。例如,要插入一个允许端口 636 上 TCP 流量的规则,请输入:
nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept
# nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在句柄为 3 的现有规则后面附加一条规则。例如,要插入一个允许端口 80 上 TCP 流量的规则,请输入:
nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept
# nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 再次显示带有 handle 的规则集。验证是否后添加的规则已添加到指定位置:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 删除 handle 为 6 的规则:
nft delete rule inet nftables_svc INPUT handle 6
# nft delete rule inet nftables_svc INPUT handle 6
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要删除规则,您必须指定 handle。
显示规则集,并验证删除的规则是否不再存在:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 从
INPUT
链中删除所有剩余的规则:nft flush chain inet nftables_svc INPUT
# nft flush chain inet nftables_svc INPUT
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示规则集,并验证
INPUT
链是否为空:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 删除
INPUT
链:nft delete chain inet nftables_svc INPUT
# nft delete chain inet nftables_svc INPUT
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您还可以使用此命令删除仍然包含规则的链。
显示规则集,并验证
INPUT
链是否已被删除:nft list table inet nftables_svc
# nft list table inet nftables_svc table inet nftables_svc { }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 删除
nftables_svc
表:nft delete table inet nftables_svc
# nft delete table inet nftables_svc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您还可以使用此命令删除仍然包含链的表。
注意要删除整个规则集,请使用
nft flush ruleset
命令,而不是在单独的命令中手动删除所有规则、链和表。
8.2. 从 iptables 迁移到 nftables 复制链接链接已复制到粘贴板!
如果您的防火墙配置仍然使用 iptables
规则,则您可以将 iptables
规则迁移到 nftables
。
8.2.1. 使用 firewalld、nftables 或者 iptables 时 复制链接链接已复制到粘贴板!
在 RHEL 8 中,您可以根据您的情况使用以下数据包过滤工具:
-
firewalld
:firewalld
工具简化了常见用例的防火墙配置。 -
nftables
:使用nftables
工具来设置复杂和性能关键的防火墙,如用于整个网络。 -
iptables
:Red Hat Enterprise Linux 上的iptables
工具使用nf_tables
内核 API 而不是传统的
后端。nf_tables
API 提供了向后兼容性,以便使用iptables
命令的脚本仍可在 Red Hat Enterprise Linux 上工作。对于新的防火墙脚本,请使用nftables
。
要防止不同的与防火墙相关的服务(firewalld
、nftables
或 iptables
)相互影响,请在 RHEL 主机上仅运行其中一个服务,并禁用其他服务。
8.2.2. nftables 框架中的概念 复制链接链接已复制到粘贴板!
与 iptables
框架相比,nftables
提供了更现代化、更高效且更灵活的替代方案。与 iptables
相比,nftables
框架提供了高级功能和改进,从而简化了规则管理,并增强了性能。这使得 nftables
成为复杂和高性能网络环境的一种现代替代方案。
- 表和命名空间
-
在
nftables
中,表代表组织单元或命名空间,其将相关的防火墙链、集合、流表和其他对象分组在一起。在nftables
中,表提供了一种更灵活的方法来构建防火墙规则和相关组件。在iptables
中,表被更严格地定义,并具有特定用途。 - 表系列
-
nftables
中的每个表都与特定的系列(ip
、ip6
、inet
、arp
、bridge
或netdev
)关联。此关联决定了表可以处理哪些数据包。例如,ip
系列中的一个表只处理 IPv4 数据包。另一方面,inet
是表系列的一个特例。它提供了一个跨协议的统一方法,因为 IPv4 数据包和 IPv6 数据包它都可以处理。特殊表系列的另一种情况是netdev
,因为它用于直接应用到网络设备的规则,从而在设备级别上启用过滤。 - 基本链
nftables
中的基本链是数据包处理管道中高度可配置的入口点,允许用户指定以下内容:- 链的类型,如 "filter"
- 数据包处理路径中的钩子点,例如 "input", "output", "forward"
- 链的优先级
通过这种灵活性,可以精确控制规则在通过网络堆栈时何时及如何应用到数据包。链的一种特殊情况是
route
链,其用于根据数据包头,影响内核所做的路由决策。- 用于规则处理的虚拟机
nftables
框架使用一个内部虚拟机来处理规则。此虚拟机执行与汇编语言操作类似的指令(将数据加载到寄存器,执行比较等)。这种机制可以实现高度灵活和有效的规则处理。nftables
中的增强功能可以作为该虚拟机的新指令引入。这通常需要一个新的内核模块,以及对libnftnl
库和nft
命令行工具的更新。或者,您可以通过将现有指令以一种创新的方式结合来引进新功能,而无需进行内核修改。
nftables
规则的语法反映了底层虚拟机的灵活性。例如,如果 TCP 目的地端口为 22,规则meta mark set tcp dport map { 22: 1, 80: 2 }
将数据包的防火墙标记设置为 1 ,如果端口为 80,则设置为 2。这展示了如何简洁地表达复杂的逻辑。- 复杂的过滤和判决图
nftables
框架集成并扩展了ipset
工具的功能,其在iptables
中用于对 IP 地址、端口、其他数据类型、最重要的是其中的组合进行批量匹配。此集成使您更容易直接管理nftables
中的大型和动态的数据集。接下来,nftables
原生支持根据任何数据类型的多个值或范围匹配数据包,这增强了其处理复杂过滤要求的能力。使用nftables
,您可以操作数据包中的任何字段。在
nftables
中,集合可以是命名的或匿名的。命名的集合可被多个规则引用和动态修改。匿名集合在规则内被内联定义,并且是不可变的。集合可以包含是不同类型组合的元素,如 IP 地址和端口号对。此功能在匹配复杂标准方面提供了更大的灵活性。要管理集合,内核可以根据特定要求(性能、内存效率等)选择最合适的后端。集合也可以作为具有键值对的映射。值部分可用作数据点(写入数据包头的值),或者作为要跳到的判决或链。这可启用复杂和动态的规则行为,称为"判决映射"。- 灵活的规则格式
nftables
规则的结构非常简单。条件和操作从左到右顺序应用。这种直观的格式简化了规则创建和故障排除。规则中的条件在逻辑上连接(使用 AND 运算符)在一起,这意味着要使规则匹配,所有条件都必须被评估为 "true" 。如果有任何条件失败,评估将移到下一个规则。
nftables
中的操作可以是最终的操作,如drop
或accept
,这停止对数据包的进一步规则处理。非终端操作,如counter log meta mark set 0x3
,执行特定的任务(计算数据包、日志记录、设置标记等),但允许评估后续规则。
8.2.3. 弃用的 iptables 框架中的概念 复制链接链接已复制到粘贴板!
与主动维护的 nftables
框架类似,弃用的 iptables
框架使您能够执行各种数据包过滤任务、日志记录和审计、与 NAT 相关的配置任务等。
iptables
框架由多个表组成,其中每个表都为特定目的而设计:
filter
- 默认表确保常规数据包过滤
nat
- 对于网络地址转换(NAT),包括更改数据包的源和目标地址
mangle
- 对于特定的数据包更改,您可以为高级路由决策对数据包标头进行修改
raw
- 对于需要在连接跟踪之前发生的配置
这些表作为单独的内核模块实现,其中每个表都提供一组固定的内置链,如 INPUT
、OUTPUT
和 FORWARD
。链是针对其评估数据包的规则的序列。这些将钩住内核中数据包处理流中的特定点。链在不同的表中有相同的名称,但它们的执行顺序由各自的钩子优先级决定。优先级由内核在内部管理,以确保规则以正确的顺序应用。
最初,iptables
被设计为处理 IPv4 流量。但是,随着 IPv6 协议的出现,需要引入 ip6tables
工具来提供可比较功能(如 iptables
),并使用户能够创建和管理用于 IPv6 数据包的防火墙规则。使用相同的逻辑,创建 arptables
工具是为了处理地址解析协议(ARP),开发 ebtables
工具是为了处理以太网桥接帧。这些工具确保您可以在各种网络协议中应用 iptables
的数据包过滤功能,并提供全面的网络覆盖。
要增强 iptables
的功能,开始开发扩展。功能扩展通常作为与用户空间动态共享对象(DSO)配对的内核模块实现。扩展引入了"匹配"和"目标",您可以在防火墙规则中使用它们来执行更复杂的操作。扩展可以启用复杂的匹配和目标。例如,您可以匹配或操作特定的第 4 层协议标头值,执行速率限制、强制配额等。某些扩展旨在解决默认 iptables
语法中的限制,如"多端口"匹配扩展。此扩展允许单个规则匹配多个非连续端口,以简化规则定义,从而减少所需的单个规则的数量。
ipset
是 iptables
的一种特殊的功能扩展。这是一个内核级别的数据结构,它与 iptables
一起使用来创建 IP 地址、端口号和其他与网络有关的您可以匹配数据包的元素的集合。这些集合可显著简化、优化并加快编写和管理防火墙规则的过程。
8.2.4. 将 iptables 和 ip6tables 规则集转换为 nftables 复制链接链接已复制到粘贴板!
使用 iptables-restore-translate
和 ip6tables-restore-translate
实用程序将 iptables
和 ip6tables
规则集转换为 nftables
。
先决条件
-
已安装
nftables
和iptables
软件包。 -
系统配置了
iptables
和ip6tables
规则。
流程
将
iptables
和ip6tables
规则写入一个文件:iptables-save >/root/iptables.dump ip6tables-save >/root/ip6tables.dump
# iptables-save >/root/iptables.dump # ip6tables-save >/root/ip6tables.dump
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将转储文件转换为
nftables
指令:iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nft
# iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft # ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
检查,如果需要,手动更新生成的
nftables
规则。 要启用
nftables
服务来加载生成的文件,请在/etc/sysconfig/nftables.conf
文件中添加以下内容:include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"
include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 停止并禁用
iptables
服务:systemctl disable --now iptables
# systemctl disable --now iptables
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您使用自定义脚本加载
iptables
规则,请确保脚本不再自动启动并重新引导以刷新所有表。启用并启动
nftables
服务:systemctl enable --now nftables
# systemctl enable --now nftables
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
显示
nftables
规则集:nft list ruleset
# nft list ruleset
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.2.5. 将单个 iptables 和 ip6tables 规则转换为 nftables 复制链接链接已复制到粘贴板!
Red Hat Enterprise Linux 提供了 iptables-translate
和 ip6tables-translate
工具来将 iptables
或 ip6tables
规则转换为与 nftables
相等的规则。
前提条件
-
已安装
nftables
软件包。
流程
使用
iptables-translate
或ip6tables-translate
程序而不是iptables
或ip6tables
显示对应的nftables
规则,例如:iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT
# iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT nft add rule ip filter INPUT ip saddr 192.0.2.0/24 counter accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,一些扩展可能缺少响应的转换支持。在这些情况下,实用程序会输出以
#
符号为前缀的未转换规则,例如:iptables-translate -A INPUT -j CHECKSUM --checksum-fill
# iptables-translate -A INPUT -j CHECKSUM --checksum-fill nft # -A INPUT -j CHECKSUM --checksum-fill
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.2.6. 常见的 iptables 和 nftables 命令的比较 复制链接链接已复制到粘贴板!
以下是常见 iptables
和 nftables
命令的比较:
列出所有规则:
Expand iptables nftables iptables-save
nft list ruleset
列出某个表和链:
Expand iptables nftables iptables -L
nft list table ip filter
iptables -L INPUT
nft list chain ip filter INPUT
iptables -t nat -L PREROUTING
nft list chain ip nat PREROUTING
nft
命令不会预先创建表和链。只有当用户手动创建它们时它们才会存在。列出 firewalld 生成的规则:
nft list table inet firewalld nft list table ip firewalld nft list table ip6 firewalld
# nft list table inet firewalld # nft list table ip firewalld # nft list table ip6 firewalld
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.3. 使用 nftables 配置 NAT 复制链接链接已复制到粘贴板!
有了 nftables
,您就可以配置以下网络地址转换(NAT)类型:
- 伪装
- 源 NAT(SNAT)
- 目标 NAT(DNAT)
- 重定向
您只能在 iifname
和 oifname
参数中使用实际的接口名称,不支持替代名称(altname
)。
8.3.1. NAT 类型 复制链接链接已复制到粘贴板!
这些是不同的网络地址转换(NAT)类型:
- 伪装和源 NAT(SNAT)
使用以上 NAT 类型之一更改数据包的源 IP 地址。例如,互联网服务提供商(ISP)不会路由私有 IP 范围,如
10.0.0.0/8
。如果您在网络中使用私有 IP 范围,用户应该能够访问互联网上的服务器,请将来自这些范围的数据包的源 IP 地址映射为公共 IP 地址。伪装和 SNAT 相互类似。不同之处是:
- 伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装。
- SNAT 将数据包的源 IP 地址设置为指定的 IP 地址,且不会动态查找传出接口的 IP 地址。因此,SNAT 要比伪装更快。如果传出接口使用了固定 IP 地址,则使用 SNAT。
- 目标 NAT(DNAT)
- 使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果您的 Web 服务器使用来自私有 IP 范围的 IP 地址,因此无法直接从互联网访问,您可以在路由器上设置 DNAT 规则,来将传入的流量重定向到此服务器。
- 重定向
- 这个类型是 IDT 的特殊示例,它根据链 hook 将数据包重定向到本地机器。例如,如果服务运行在与其标准端口不同的端口上,您可以将传入的流量从标准端口重定向到此特定端口。
8.3.2. 使用 nftables 配置伪装 复制链接链接已复制到粘贴板!
伪装使路由器动态地更改通过接口到接口 IP 地址发送的数据包的源 IP。这意味着,如果接口被分配了一个新 IP,nftables
会在替换源 IP 时自动使用新的 IP。
将通过 ens3
接口离开主机的数据包源 IP 替换为 ens3
上设置的 IP。
流程
创建一个表:
nft add table nat
# nft add table nat
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向表中添加
prerouting
和postrouting
链:nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要即使您没有向
prerouting
链中添加规则,nftables
框架也会要求此链与传入的数据包回复匹配。请注意,您必须将
--
选项传递给nft
命令,以防止 shell 将负优先级值解释为nft
命令的选项。向
postrouting
链中添加一条规则,来匹配ens3
接口上传出的数据包:nft add rule nat postrouting oifname "ens3" masquerade
# nft add rule nat postrouting oifname "ens3" masquerade
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.3.3. 使用 nftables 配置源 NAT 复制链接链接已复制到粘贴板!
在路由器中,源 NAT(SNAT)可让您将通过接口发送的数据包 IP 改为专门的 IP 地址。然后,路由器会替换传出数据包的源 IP。
流程
创建一个表:
nft add table nat
# nft add table nat
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向表中添加
prerouting
和postrouting
链:nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要即使您没有向
postrouting
链添加规则,nftables
框架也会要求此链与传出数据包回复相匹配。请注意,您必须将
--
选项传递给nft
命令,以防止 shell 将负优先级值解释为nft
命令的选项。向
postrouting
链中添加一条规则,该规则将使用192.0.2.1
替换通过ens3
的传出数据包的源 IP :nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1
# nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.3.4. 使用 nftables 配置目标 NAT 复制链接链接已复制到粘贴板!
目标 NAT (DNAT)可让您将路由器上的流量重定向到无法直接从互联网访问的主机。
例如,有了 DNAT,路由器将发送给端口 80
和 443
的传入流量重定向到 IP 地址为 192.0.2.1
的 Web 服务器。
流程
创建一个表:
nft add table nat
# nft add table nat
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向表中添加
prerouting
和postrouting
链:nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } # nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要即使您没有向
postrouting
链添加规则,nftables
框架也会要求此链与传出数据包回复相匹配。请注意,您必须将
--
选项传递给nft
命令,以防止 shell 将负优先级值解释为nft
命令的选项。向
prerouting
链中添加一条规则,该规则将路由器的ens3
接口上端口80
和443
的传入流量重定向到 IP 地址为192.0.2.1
的 web 服务器:nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1
# nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 根据您的环境,添加 SNAT 或伪装规则,将从 Web 服务器返回的数据包的源地址改为发送者:
如果
ens3
接口使用动态 IP 地址,请添加一条伪装规则:nft add rule nat postrouting oifname "ens3" masquerade
# nft add rule nat postrouting oifname "ens3" masquerade
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果
ens3
接口使用静态 IP 地址,请添加一条 SNAT 规则。例如,如果ens3
使用198.51.100.1
IP 地址:nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1
# nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
启用数据包转发:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.3.5. 使用 nftables 配置重定向 复制链接链接已复制到粘贴板!
重定向
功能是目标网络地址转换(DNAT)的一种特殊情况,它根据链 hook 将数据包重定向到本地计算机。
例如,您可以将发送到本地主机端口 22
的流量重定向到端口 2222
。
流程
创建一个表:
nft add table nat
# nft add table nat
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向表中添加
prerouting
链:nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,您必须将
--
选项传递给nft
命令,以防止 shell 将负优先级值解释为nft
命令的选项。向
prerouting
链中添加一条规则,其将端口22
上的传入流量重定向到端口2222
:nft add rule nat prerouting tcp dport 22 redirect to 2222
# nft add rule nat prerouting tcp dport 22 redirect to 2222
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.4. 编写和执行 nftables 脚本 复制链接链接已复制到粘贴板!
使用 nftables
框架的主要优点是脚本的执行是原子的。这意味着,系统会应用整个脚本,或者在出现错误时防止执行。这样可保证防火墙始终处于一致状态。
另外,使用 nftables
脚本环境时,您可以:
- 添加评论
- 定义变量
- 包括其他规则集文件
安装 nftables
软件包时,Red Hat Enterprise Linux 会在 /etc/nftables/
目录中自动创建 *.nft
脚本。这些脚本包含为不同目的创建表和空链的命令。
8.4.1. 支持的 nftables 脚本格式 复制链接链接已复制到粘贴板!
您可以使用以下格式在 nftables
脚本环境中编写脚本:
与
nft list ruleset
命令相同的格式显示规则集:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 与
nft
命令的语法相同:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.4.2. 运行 nftables 脚本 复制链接链接已复制到粘贴板!
您可以通过将脚本传递给 nft
实用程序或直接执行脚本来运行 nftables
脚本。
流程
要通过将其传给
nft
工具来运行nftables
脚本,请输入:nft -f /etc/nftables/<example_firewall_script>.nft
# nft -f /etc/nftables/<example_firewall_script>.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要直接运行
nftables
脚本:在进行这个时间时:
确保脚本以以下 shebang 序列开头:
#!/usr/sbin/nft -f
#!/usr/sbin/nft -f
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要如果省略了
-f
参数,nft
工具不会读取脚本,并显示Error: syntax error, unexpected newline, expecting string
。可选:将脚本的所有者设为
root
:chown root /etc/nftables/<example_firewall_script>.nft
# chown root /etc/nftables/<example_firewall_script>.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使脚本可以被其所有者执行:
chmod u+x /etc/nftables/<example_firewall_script>.nft
# chmod u+x /etc/nftables/<example_firewall_script>.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
运行脚本:
/etc/nftables/<example_firewall_script>.nft
# /etc/nftables/<example_firewall_script>.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果没有输出结果,系统将成功执行该脚本。
即使 nft
成功地执行了脚本,在脚本中错误放置的规则、缺失的参数或其他问题都可能会导致防火墙的行为不符合预期。
8.4.3. 使用 nftables 脚本中的注释 复制链接链接已复制到粘贴板!
nftables
脚本环境将 #
字符右侧的所有内容解释为行尾。
注释可在行首或命令旁边开始:
8.4.4. 使用 nftables 脚本中的变量 复制链接链接已复制到粘贴板!
要在 nftables
脚本中定义一个变量,请使用 define
关键字。您可以在变量中存储单个值和匿名集合。对于更复杂的场景,请使用 set 或 verdict 映射。
- 只有一个值的变量
以下示例定义了一个名为
INET_DEV
的变量,其值为enp1s0
:define INET_DEV = enp1s0
define INET_DEV = enp1s0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您可以通过输入
$
符号后再输入变量名称来使用脚本中的变量:... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...
... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 包含匿名集合的变量
以下示例定义了一个包含匿名集合的变量:
define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }
define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 您可以通过在
$
符号后跟变量名称来在脚本中使用变量:add rule inet example_table example_chain ip daddr $DNS_SERVERS accept
add rule inet example_table example_chain ip daddr $DNS_SERVERS accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意当您在规则中使用大括号时具有特殊的语义,因为它们表示变量代表一个集合。
8.4.5. 在 nftables 脚本中包含文件 复制链接链接已复制到粘贴板!
在 nftables
脚本环境中,您可以使用 include
语句包含其他脚本。
如果您只指定没有绝对或相对路径的文件名,nftables
包含了默认搜索路径(设置为 Red Hat Enterprise Linux 上的 /etc
)。
例 8.1. 包含默认搜索目录中的文件
从默认搜索目录中包含一个文件:
include "example.nft"
include "example.nft"
例 8.2. 包含目录中的所有 *.nft 文件
要包括以 *.nft
结尾的所有文件,它们存储在 /etc/nftables/rulesets/
目录中:
include "/etc/nftables/rulesets/*.nft"
include "/etc/nftables/rulesets/*.nft"
请注意,include
语句不匹配以点开头的文件。
8.4.6. 系统引导时自动载入 nftables 规则 复制链接链接已复制到粘贴板!
nftables
systemd 服务加载包含在 /etc/sysconfig/nftables.conf
文件中的防火墙脚本。
前提条件
-
nftables
脚本存储在/etc/nftables/
目录中。
流程
编辑
/etc/sysconfig/nftables.conf
文件。-
如果您使用
nftables
软件包的安装修改了在/etc/nftables/
中创建的*.nft
脚本,请取消对这些脚本的include
语句的注释。 如果您编写了新脚本,请添加
include
语句以包含这些脚本。例如,要在nftables
服务启动时加载/etc/nftables/example.nft
脚本,请添加:include "/etc/nftables/_example_.nft"
include "/etc/nftables/_example_.nft"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
如果您使用
可选:启动
nftables
服务来加载防火墙规则,而无需重启系统:systemctl start nftables
# systemctl start nftables
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启用
nftables
服务。systemctl enable nftables
# systemctl enable nftables
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.5. 使用 nftables 命令中的设置 复制链接链接已复制到粘贴板!
nftables
框架原生支持集合。您可以使用一个集合,例如,规则匹配多个 IP 地址、端口号、接口或其他匹配标准。
8.5.1. 在 nftables 中使用匿名集合 复制链接链接已复制到粘贴板!
匿名集合包含用逗号分开的值,如 { 22、80、443 }
,它们直接在规则中使用。您还可以将匿名集合用于 IP 地址以及任何其他匹配标准。
匿名集合的缺陷是,如果要更改集合,则需要替换规则。对于动态解决方案,使用命名集合,如 在 nftables 中使用命名集合 中所述。
先决条件
-
inet
系列中的example_chain
链和example_table
表存在。
流程
例如,要向
example_table
中的example_chain
添加一条规则,其允许传入流量到端口22
、80
和443
:nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept
# nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选: 在
example_table
中显示所有链及其规则:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.5.2. 在 nftables 中使用命名集 复制链接链接已复制到粘贴板!
nftables
框架支持可变命名集合。命名集是一个列表或一组元素,您可以在表中的多个规则中使用。匿名集合的另外一个好处在于,您可以更新命名的集合而不必替换使用集合的规则。
当您创建一个命名集时,必须指定集合包含的元素类型。您可以设置以下类型:
-
包含 IPv4 地址或范围的集合的
ipv4_addr
,如192.0.2.1
或192.0.2.0/24
。 -
包含 IPv6 地址或范围的集合的
ipv6_addr
,如2001:db8:1::1
或2001:db8:1::1/64
。 -
包含介质访问控制(MAC)地址列表的集合的
ether_addr
,如52:54:00:6b:66:42
。 -
包含互联网协议类型列表的集合的
inet_proto
,如tcp
。 -
包含互联网服务列表的集合的
inet_service
,如ssh
。 -
包含数据包标记列表的集合的
mark
。数据包标记可以是任意正 32 位整数值(0
到2147483647
)。
先决条件
-
example_chain
链和example_table
表存在。
流程
创建一个空集。以下示例为 IPv4 地址创建了一个集合:
要创建可存储多个独立 IPv4 地址的集合:
nft add set inet example_table example_set { type ipv4_addr \; }
# nft add set inet example_table example_set { type ipv4_addr \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建可存储 IPv4 地址范围的集合:
nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
可选:创建使用集合的规则。例如,以下命令向
example_table
中的example_chain
中添加一条规则,该规则将丢弃example_set
中来自 IPv4 地址的所有数据包。nft add rule inet example_table example_chain ip saddr @example_set drop
# nft add rule inet example_table example_chain ip saddr @example_set drop
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 由于
example_set
仍为空,所以该规则目前不起作用。向
example_set
中添加 IPv4 地址:如果您创建存储单个 IPv4 地址的集合,请输入:
nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }
# nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您创建存储 IPv4 范围的集合,请输入:
nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }
# nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 当您指定 IP 地址范围时,您可以使用无类别域间路由(CIDR)表示法,如上例中的
192.0.2.0/24
。
8.5.3. 使用动态集添加来自数据包路径的条目 复制链接链接已复制到粘贴板!
nftables
框架中的动态集允许自动添加来自数据包的元素。例如,IP 地址、目标端口、MAC 地址等。此功能使您能够实时收集这些元素,并使用它们创建拒绝列表、禁止列表等,以便您能够立即对安全威胁做出反应。
先决条件
-
inet
系列中的example_chain
链和example_table
表存在。
流程
创建一个空集。以下示例为 IPv4 地址创建了一个集合:
要创建可存储多个独立 IPv4 地址的集合:
nft add set inet example_table example_set { type ipv4_addr \; }
# nft add set inet example_table example_set { type ipv4_addr \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建可存储 IPv4 地址范围的集合:
nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
创建一条规则,将传入数据包的源 IPv4 地址添加到
example_set
集中:nft add rule inet example_table example_chain set add ip saddr @example_set
# nft add rule inet example_table example_chain set add ip saddr @example_set
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令在
example_chain
规则链和example_table
中创建了一个新规则,来将数据包的源 IPv4 地址动态添加到example_set
中。
验证
确保规则已添加:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令显示当前在
nftables
中加载的整个规则集。它显示 IP 正在主动触发规则,并且正在使用相关地址更新example_set
。
后续步骤
有动态 IP 集后,您可以将它用于各种安全性、过滤和流量控制目的。例如:
- 块、限制或记录网络流量
- 与允许列表结合,以避免禁止可信用户
- 使用自动超时来防止过度阻塞
8.6. 在 nftables 命令中使用判决映射 复制链接链接已复制到粘贴板!
判决映射(也称为字典),使 nft
能够通过将匹配条件映射到某个操作来根据数据包信息执行操作。
8.6.1. 在 nftables 中使用匿名映射 复制链接链接已复制到粘贴板!
匿名映射是直接在规则中使用的 { match_criteria : action }
语句。这个语句可以包含多个用逗号分开的映射。
匿名映射的缺点是,如果要修改映射,则必须替换规则。对于动态解决方案,请使用命名映射,如 在 nftables 中使用命名映射 中所述。
例如,您可以使用匿名映射将 IPv4 和 IPv6 协议的 TCP 和 UDP 数据包路由到不同的链,以分别计算传入的 TCP 和 UDP 数据包。
流程
创建新表:
nft add table inet example_table
# nft add table inet example_table
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
example_table
中创建tcp_packets
链:nft add chain inet example_table tcp_packets
# nft add chain inet example_table tcp_packets
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向统计此链中流量的
tcp_packets
中添加一条规则:nft add rule inet example_table tcp_packets counter
# nft add rule inet example_table tcp_packets counter
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
example_table
中创建udp_packets
链nft add chain inet example_table udp_packets
# nft add chain inet example_table udp_packets
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向统计此链中流量的
udp_packets
中添加一条规则:nft add rule inet example_table udp_packets counter
# nft add rule inet example_table udp_packets counter
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为传入的流量创建一个链。例如,要在过滤传入的流量的
example_table
中创建一个名为incoming_traffic
的链:nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 添加一条带有到
incoming_traffic
匿名映射的规则 :nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 匿名映射区分数据包,并根据它们的协议将它们发送到不同的计数链。
要列出流量计数器,请显示
example_table
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tcp_packets
和udp_packets
链中的计数器显示两者接收的数据包和字节数。
8.6.2. 在 nftables 中使用命名映射 复制链接链接已复制到粘贴板!
nftables
框架支持命名映射。您可以在表中的多个规则中使用这些映射。匿名映射的另一个好处在于,您可以更新命名映射而不比替换使用它的规则。
在创建命名映射时,您必须指定元素的类型:
-
匹配部分包含 IPv4 地址的映射的
ipv4_addr
,如192.0.2.1
。 -
匹配部分包含 IPv6 地址的映射的
ipv6_addr
,如2001:db8:1::1
。 -
匹配部分包含介质访问控制(MAC)地址的映射的
ether_addr
,如52:54:00:6b:66:42
。 -
匹配部分包含互联网协议类型的映射的
inet_proto
,如tcp
。 -
匹配部分包含互联网服务名称端口号的映射的
inet_service
,如ssh
或22
。 -
匹配部分包含数据包的映射的
mark
。数据包标记可以是任意正 32 位整数值(0
到2147483647
)。 -
匹配部分包含计数器值的映射的
counter
。计数器值可以是任意正 64 位整数值。 -
匹配部分包含配额值的映射的
quota
。配额值可以是任意正 64 位整数值。
例如,您可以根据其源 IP 地址允许或丢弃传入的数据包。使用命名映射时,您只需要一条规则来配置这种场景,而 IP 地址和操作被动态存储在映射中。
流程
创建表。例如,要创建一个处理 IPv4 数据包的、名为
example_table
的表:nft add table ip example_table
# nft add table ip example_table
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建链。例如,要在
example_table
中创建一个名为example_chain
的链:nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
# nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
创建一个空的映射。例如,要为 IPv4 地址创建映射:
nft add map ip example_table example_map { type ipv4_addr : verdict \; }
# nft add map ip example_table example_map { type ipv4_addr : verdict \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建使用该映射的规则。例如,以下命令向
example_table
中的example_chain
添加了一条规则,该规则将操作应用到在example_map
中定义的 IPv4 地址:nft add rule example_table example_chain ip saddr vmap @example_map
# nft add rule example_table example_chain ip saddr vmap @example_map
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向
example_map
添加 IPv4 地址和相应的操作:nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }
# nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这个示例定义了 IPv4 地址到操作的映射。与以上创建的规则相结合,防火墙接受来自
192.0.2.1
的数据包,丢弃来自192.0.2.2
的数据包。可选:通过添加另一个 IP 地址和 action 语句来增强映射:
nft add element ip example_table example_map { 192.0.2.3 : accept }
# nft add element ip example_table example_map { 192.0.2.3 : accept }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:从映射中删除条目:
nft delete element ip example_table example_map { 192.0.2.1 }
# nft delete element ip example_table example_map { 192.0.2.1 }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 可选:显示规则集:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.7. 示例:使用 nftables 脚本保护 LAN 和 DMZ 复制链接链接已复制到粘贴板!
使用 RHEL 路由器上的 nftables
框架来编写和安装防火墙脚本,来保护内部 LAN 中的网络客户端和 DMZ 中的 Web 服务器免受来自互联网和其他网络的未授权访问。
这个示例仅用于演示目的,描述了一个具有特定要求的场景。
防火墙脚本高度依赖网络基础架构和安全要求。当您为自己的环境编写脚本时,请使用此示例了解 nftables
防火墙的概念。
8.7.1. 网络条件 复制链接链接已复制到粘贴板!
本例中的网络具有以下条件:
路由器连接到以下网络:
-
互联网通过接口
enp1s0
-
内部 LAN 通过接口
enp7s0
-
DMZ 通过
enp8s0
-
互联网通过接口
-
路由器的互联网接口分配了静态 IPv4 地址(
203.0.113.1
)和 IPv6 地址(2001:db8:a::1
)。 -
内部 LAN 中的客户端仅使用范围
10.0.0.0/24
中的专用 IPv4 地址。因此,从 LAN 到互联网的流量需要源网络地址转换(SNAT)。 -
内部 LAN 中的管理员 PC 使用 IP 地址
10.0.0.100
和10.0.0.200
。 -
DMZ 使用范围
198.51.100.0/24
和2001:db8:b::/56
中的公共 IP 地址。 -
DMZ 中的 Web 服务器使用 IP 地址
198.51.100.5
和2001:db8:b::5
。 - 路由器为 LAN 和 DMZ 中的主机充当缓存 DNS 服务器。
8.7.2. 防火墙脚本的安全要求 复制链接链接已复制到粘贴板!
以下是示例网络中 nftables
防火墙的要求:
路由器必须能够:
- 递归解析 DNS 查询。
- 在回环接口上执行所有连接。
内部 LAN 中的客户端必须能够:
- 查询运行在路由器上的缓存 DNS 服务器。
- 访问 DMZ 中的 HTTPS 服务器。
- 访问互联网上的任何 HTTPS 服务器。
- 管理员的 PC 必须能够使用 SSH 访问 DMZ 中的路由器以及每个服务器。
DMZ 中的 Web 服务器必须能够:
- 查询运行在路由器上的缓存 DNS 服务器。
- 访问互联网上的 HTTPS 服务器以下载更新。
互联网上的主机必须能够:
- 访问 DMZ 中的 HTTPS 服务器。
另外,存在以下安全要求:
- 应丢弃未明确允许的连接尝试。
- 应记录丢弃的数据包。
8.7.3. 配置将丢弃的数据包记录到文件 复制链接链接已复制到粘贴板!
默认情况下,systemd
会将内核消息如,丢弃的数据包,记录到日志中。另外,您可以配置 rsyslog
服务,来将此类条目记录到单独的文件中。为确保日志文件不会无限增长,请配置轮转策略。
先决条件
-
rsyslog
软件包已安装。 -
rsyslog
服务正在运行。
流程
使用以下内容创建
/etc/rsyslog.d/nftables.conf
文件::msg, startswith, "nft drop" -/var/log/nftables.log & stop
:msg, startswith, "nft drop" -/var/log/nftables.log & stop
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用这个配置,
rsyslog
服务会将丢弃的数据包记录到/var/log/nftables.log
文件,而不是/var/log/messages
。重启
rsyslog
服务:systemctl restart rsyslog
# systemctl restart rsyslog
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下内容创建
/etc/logrotate.d/nftables
文件,以便在大小超过 10 MB 时轮转/var/log/nftables.log
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow maxage 30
设置定义了logrotate
在下一次轮转操作过程中删除超过 30 天的轮转日志。
8.7.4. 编写并激活 nftables 脚本 复制链接链接已复制到粘贴板!
本例是运行在 RHEL 路由器上的一个 nftables
防火墙脚本,其保护内部 LAN 中的客户端以及 DMZ 中的 Web 服务器。有关示例中使用的防火墙的网络和要求的详情,请参阅 网络条件 和 对防火墙脚本的安全要求 。
此 nftables
防火墙脚本仅用于演示目的。不要在未经调整为适合您环境和安全要求的情况下使用它。
前提条件
- 网络已配置,如 网络状况 中所述。
流程
使用以下内容创建
/etc/nftables/firewall.nft
脚本:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
/etc/sysconfig/nftables.conf
文件中包括/etc/nftables/firewall.nft
脚本:include "/etc/nftables/firewall.nft"
include "/etc/nftables/firewall.nft"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启用 IPv4 转发:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启用并启动
nftables
服务:systemctl enable --now nftables
# systemctl enable --now nftables
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
可选:验证
nftables
规则集:nft list ruleset
# nft list ruleset ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 尝试执行防火墙阻止的访问。例如,尝试使用 SSH 从 DMZ 访问路由器:
ssh router.example.com
# ssh router.example.com ssh: connect to host router.example.com port 22: Network is unreachable
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 根据您的日志记录设置,搜索:
阻塞的数据包的
systemd
日志:journalctl -k -g "nft drop"
# journalctl -k -g "nft drop" Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 阻塞的数据包的
/var/log/nftables.log
文件:Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.8. 使用 nftables 限制连接的数量 复制链接链接已复制到粘贴板!
您可以使用 nftables
来限制连接数或限制到建立给定数量连接的块 IP 地址,以防止它们使用太多的系统资源。
8.8.1. 使用 nftables 限制连接的数量 复制链接链接已复制到粘贴板!
通过使用 nft
工具的 ct count
参数,您可以限制每个 IP 地址的同时连接的数量。例如,您可以使用此功能配置每个源 IP 地址只能建立两个到主机的并行 SSH 连接。
流程
创建带有
inet
地址系列的filter
表:nft add table inet filter
# nft add table inet filter
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
input
链添加到inet filter
表中:nft add chain inet filter input { type filter hook input priority 0 \; }
# nft add chain inet filter input { type filter hook input priority 0 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为 IPv4 地址创建动态集合:
nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}
# nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
input
链中添加一条规则,该规则只允许从 IPv4 地址到 SSH 端口(22)的两个同时的传入连接,并拒绝来自同一 IP 的所有进一步的连接:nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter reject
# nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter reject
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
- 建立从同一 IP 地址到主机的两个以上的同时的 SSH 连接。如果已经建立了两个连接,则 nftables 会拒绝到 SSH 端口的连接。
显示
limit-ssh
动态集:Copy to Clipboard Copied! Toggle word wrap Toggle overflow elements
条目显示当前与该规则匹配的地址。在本例中,elements
列出了与 SSH 端口有活动连接的 IP 地址。请注意,输出不会显示活跃连接的数量,或者连接是否被拒绝。
8.8.2. 在一分钟内尝试超过十个进入的 TCP 连接的 IP 地址 复制链接链接已复制到粘贴板!
您可以临时阻止在一分钟内建立十个 IPv4 TCP 连接的主机。
流程
创建具有
ip
地址系列的filter
表:nft add table ip filter
# nft add table ip filter
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 向
filter
表中添加input
链:nft add chain ip filter input { type filter hook input priority 0 \; }
# nft add chain ip filter input { type filter hook input priority 0 \; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 添加一条规则,其丢弃来自源地址的所有数据包,并尝试在一分钟内建立十个 TCP 连接:
nft add rule ip filter input ip protocol tcp ct state new, untracked meter ratemeter { ip saddr timeout 5m limit rate over 10/minute } drop
# nft add rule ip filter input ip protocol tcp ct state new, untracked meter ratemeter { ip saddr timeout 5m limit rate over 10/minute } drop
Copy to Clipboard Copied! Toggle word wrap Toggle overflow timeout 5m
参数定义nftables
在五分钟后自动删除条目,以防止计量被过时的条目填满。
验证
要显示 meter 的内容,请输入:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.9. 调试 nftables 规则 复制链接链接已复制到粘贴板!
nftables
框架为管理员提供了不同的选项来调试规则,以及数据包是否匹配。
8.9.1. 创建带有计数器的规则 复制链接链接已复制到粘贴板!
在识别规则是否匹配时,可以使用计数器。
-
有关在现有规则中添加计数器的流程的更多信息,请参阅
配置和管理网络
中的 向现有规则中添加计数器
先决条件
- 您要添加该规则的链已存在。
流程
向链中添加一条带有
counter
参数的新规则。以下示例添加一个带有计数器的规则,它允许端口 22 上的 TCP 流量,并计算与这个规则匹配的数据包和网络数据的数量:nft add rule inet example_table example_chain tcp dport 22 counter accept
# nft add rule inet example_table example_chain tcp dport 22 counter accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示计数器值:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.9.2. 在现有规则中添加计数器 复制链接链接已复制到粘贴板!
在识别规则是否匹配时,可以使用计数器。
-
有关添加带有计数器的新规则的流程的更多信息,请参阅
配置和管理网络
中的 创建带有计数器的规则
先决条件
- 您要添加计数器的规则已存在。
流程
在链中显示规则及其句柄:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过使用
counter
参数替换规则来添加计数器。以下示例替换了上一步中显示的规则并添加计数器:nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter accept
# nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示计数器值:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.9.3. 监控与现有规则匹配的数据包 复制链接链接已复制到粘贴板!
nftables
中的追踪功能与 nft monitor
命令相结合,使管理员能够显示与某一规则匹配的数据包。您可以为规则启用追踪,用它来监控匹配此规则的数据包。
先决条件
- 您要添加计数器的规则已存在。
流程
在链中显示规则及其句柄:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过使用
meta nftrace set 1
参数替换规则来添加追踪功能。以下示例替换了上一步中显示的规则并启用追踪:nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 accept
# nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
nft monitor
命令来显示追踪。以下示例过滤了命令的输出,来只显示包含inet example_table example_chain
的条目:nft monitor | grep "inet example_table example_chain"
# nft monitor | grep "inet example_table example_chain" trace id 3c5eb15e inet example_table example_chain packet: iif "enp1s0" ether saddr 52:54:00:17:ff:e4 ether daddr 52:54:00:72:2f:6e ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49710 ip protocol tcp ip length 60 tcp sport 56728 tcp dport ssh tcp flags == syn tcp window 64240 trace id 3c5eb15e inet example_table example_chain rule tcp dport ssh nftrace set 1 accept (verdict accept) ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 警告根据启用了追踪的规则数量以及匹配流量的数量,
nft monitor
命令可以显示很多输出。使用grep
或其他工具来过滤输出。
8.10. 备份和恢复 nftables 规则集 复制链接链接已复制到粘贴板!
您可以将 nftables
规则备份到文件,并稍后恢复它们。此外,管理员可以使用带有规则的文件,来将规则传给其他服务器。
8.10.1. 将 nftables 规则集备份到文件 复制链接链接已复制到粘贴板!
您可以使用 nft
工具将 nftables
规则集备份到文件。
流程
要备份
nftables
规则:以
nft list ruleset
格式生成的格式:nft list ruleset > file.nft
# nft list ruleset > file.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow JSON 格式:
nft -j list ruleset > file.json
# nft -j list ruleset > file.json
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.10.2. 从文件中恢复 nftables 规则集 复制链接链接已复制到粘贴板!
您可以从文件恢复 nftables
规则集。
流程
要恢复
nftables
规则:如果要恢复的文件是
nft list ruleset
生成的格式,或直接包含nft
命令:nft -f file.nft
# nft -f file.nft
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果要恢复的文件采用 JSON 格式:
nft -j -f file.json
# nft -j -f file.json
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
第 9 章 保护网络服务 复制链接链接已复制到粘贴板!
Red Hat Enterprise Linux 8 支持许多不同类型的网络服务器。这些服务器提供的网络服务可能会暴露系统的安全性,从而可能会面临各种类型的攻击,如拒绝服务攻击(DoS)、分布式拒绝服务攻击(DDoS)、脚本漏洞攻击和缓冲区溢出攻击。
为增加系统的安全性,务必要监控您使用的活跃网络服务。例如,当网络服务在计算机上运行时,其守护进程会侦听网络端口的连接,这可能会降低系统的安全性。要限制暴露会受到攻击的网络,应关闭所有未使用的服务。
9.1. 保护 rpcbind 服务 复制链接链接已复制到粘贴板!
rpcbind
服务是用于远程过程调用(RPC)服务的动态端口分配守护进程,如网络信息服务(NIS)和网络文件共享(NFS)。由于其身份验证机制较弱,并可为其控制的服务分配大量端口,因此保护 rpcbind
服务非常重要。
您可以通过限制访问所有网络并使用服务器上的防火墙规则来定义特定例外来保护 rpcbind
。
-
NFSv2
和NFSv3
服务器中需要rpcbind
服务。 -
NFSv4
上不需要rpcbind
服务。
先决条件
-
已安装
rpcbind
软件包。 -
firewalld
软件包已安装,且服务正在运行。
流程
添加防火墙规则,例如:
限制 TCP 连接,并只接受来自
192.168.0.0/24
主机111
端口的包:firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 限制 TCP 连接,并只接受来自本地主机
111
端口的包:firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept'
# firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 限制 UDP 连接,并只接受来自
192.168.0.0/24
主机111
端口的包:firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要使防火墙设置永久化,请在添加防火墙规则时使用
--permanent
选项。
重新载入防火墙以应用新规则:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
列出防火墙规则:
firewall-cmd --list-rich-rule
# firewall-cmd --list-rich-rule rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
9.2. 保护 rpc.mountd 服务 复制链接链接已复制到粘贴板!
rpc.mountd
守护进程实现 NFS 挂载协议的服务器端。NFS 挂载协议用于 NFS 版本 2(RFC 1904)和 NFS 版本 3(RFC 1813)。
您可以通过对服务器添加防火墙规则来保护 rpc.mountd
服务。您可以限制对所有网络的访问,并使用防火墙规则定义特定的异常。
前提条件
-
已安装
rpc.mountd
软件包。 -
firewalld
软件包已安装,且服务正在运行。
流程
在服务器中添加防火墙规则,例如:
接受来自
192.168.0.0/24
主机的mountd
连接:firewall-cmd --add-rich-rule 'rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --add-rich-rule 'rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 接受来自本地主机的
mountd
连接:firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="127.0.0.1" service name="mountd" accept'
# firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="127.0.0.1" service name="mountd" accept'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要使防火墙设置永久化,请在添加防火墙规则时使用
--permanent
选项。
重新载入防火墙以应用新规则:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
列出防火墙规则:
firewall-cmd --list-rich-rule
# firewall-cmd --list-rich-rule rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop rule family="ipv4" source address="127.0.0.1" service name="mountd" accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
9.3. 保护 NFS 服务 复制链接链接已复制到粘贴板!
您可以使用 Kerberos 验证并加密所有文件系统操作来保护网络文件系统 4(NFSv4)。在将 NFSv4 与网络地址转换(NAT)或防火墙搭配使用时,您可以通过修改 /etc/default/nfs
文件来关闭委托。委托(Delegation)是服务器将文件管理委派给客户端的一种技术。相反,NFSv2 和 NFSv3 不使用 Kerberos 锁定和挂载文件。
NFS 服务在所有 NFS 版本中使用 TCP 发送流量。该服务支持 Kerberos 用户和组身份验证,作为 RPCSEC_GSS
内核模块的一部分。
NFS 允许远程主机通过网络挂载文件系统,并与这些文件系统进行交互,就像它们被挂载到本地一样。您可以在集中服务器中合并资源,并在共享文件系统时额外自定义 /etc/nfsmount.conf
文件中的 NFS 挂载选项。
9.3.1. 保护 NFS 服务器的导出选项 复制链接链接已复制到粘贴板!
NFS 服务器决定有关将哪些文件系统导出到 /etc/exports
文件中的目录和主机的列表结构。
您可以对 /etc/exports
文件使用以下导出选项:
ro
- 将 NFS 卷导出为只读。
rw
-
允许对 NFS 卷的读和写请求。请小心使用这个选项,因为允许写入访问会增加攻击的风险。如果您的场景需要使用
rw
选项挂载目录,请确保它们对所有用户都不可写,以减少可能的风险。 root_squash
-
将来自
uid
/gid
0 的请求映射到匿名uid
/gid
。这不适用于其它可能比较敏感的uid
或gid
,如bin
用户或staff
组。 no_root_squash
-
关闭 root 挤压。默认情况下,NFS 共享将
root
用户改为nobody
用户,这是一个非特权用户帐户。这会将所有root
创建的文件的所有者改为nobody
,这样可以防止上传设置了setuid
位的程序。如果使用no_root_squash
选项,则远程 root 用户可以更改共享文件系统上的任何文件,并将感染特洛伊木马的应用程序留给其他用户。 secure
-
将导出限制到保留的端口。默认情况下,服务器只允许客户端通信通过保留的端口。但是在网络上,任何人都可以容易地成为客户端上的
root
用户,因此,对于服务器来说,假设通过保留端口的通信都具有特权是不安全的。因此,对保留端口的限制具有有限的值;最好根据 Kerberos、防火墙和对特定客户端的导出限制来决定。
/etc/exports
文件语法中额外的空格可能会导致配置中的重大变化。
在以下示例中,/tmp/nfs/
目录与 bob.example.com
主机共享,并且具有读取和写入权限。
/tmp/nfs/ bob.example.com(rw)
/tmp/nfs/ bob.example.com(rw)
以下示例与前一个相同,但对 bob.example.com
主机共享具有只读权限的相同的目录,由于主机名后面有一个空格字符,因此可以对 world 共享具有读写权限的目录。
/tmp/nfs/ bob.example.com (rw)
/tmp/nfs/ bob.example.com (rw)
您可以通过输入 showmount -e <hostname>
命令检查您系统上的共享目录。
另外,在导出 NFS 服务器时请考虑以下最佳实践:
- 导出主目录存在风险,因为某些应用以纯文本或弱加密格式存储密码。您可以通过检查并改进应用程序代码来降低风险。
- 有些用户未对 SSH 密钥设置密码,这再次给主目录带来风险。您可以通过强制使用密码或使用 Kerberos 来降低这些风险。
-
将 NFS 导出仅限制为所需的客户端。在 NFS 服务器上使用
showmount -e
命令来检查服务器正在导出什么。不要导出不需要的任何内容。 - 不要允许不必要的用户登录到服务器,以减少攻击风险。您可以定期检查谁可以访问服务器,以及可以访问服务器的什么数据。
要导出整个文件系统,因为导出文件系统的子目录不安全。攻击者可能会访问部分导出的文件系统的未导出部分。
9.3.2. 保护 NFS 客户端的挂载选项 复制链接链接已复制到粘贴板!
您可以将以下选项传递给 mount
命令,以增加基于 NFS 的客户端的安全性:
nosuid
-
使用
nosuid
选项禁用set-user-identifier
或set-group-identifier
位。这样可防止远程用户通过运行setuid
程序获得更高的特权,并可使用此选项与setuid
选项相反。 noexec
-
使用
noexec
选项禁用客户端上的所有可执行文件。使用此选项可防止用户意外执行位于共享文件系统中的文件。 nodev
-
使用
nodev
选项防止客户端将设备文件作为硬件设备处理。 resvport
-
使用
resvport
选项将通信限制到保留端口,您可以使用特权源端口与服务器通信。保留的端口是为特权用户和进程保留的,如root
用户。 秒
-
使用 NFS 服务器上的
sec
选项,选择 RPCGSS security 类别来访问挂载点上的文件。有效的安全类别包括none
,sys
,krb5
,krb5i
, 和krb5p
。
krb5-libs
软件包提供的 MIT Kerberos 库不支持新部署中的数据加密标准(DES)算法。因为安全和兼容性的原因,在 Kerberos 库中默认禁用 DES。出于兼容性的原因,请使用更新、更安全的算法而不是 DES。
9.3.3. 使用防火墙保护 NFS 复制链接链接已复制到粘贴板!
要保护 NFS 服务器上的防火墙,请仅开放所需的端口。不要将 NFS 连接端口号用于任何其他服务。
前提条件
-
已安装
nfs-utils
软件包。 -
firewalld
软件包已安装并运行。
流程
-
在 NFSv4 上,防火墙必须打开 TCP 端口
2049
。 在 NFSv3 上,使用
2049
打开四个额外端口:rpcbind
服务动态分配 NFS 端口,这可能会在创建防火墙规则时导致问题。要简化这个过程,使用/etc/nfs.conf
文件指定要使用哪些端口:-
在
[mountd]
部分为mountd
(rpc.mountd
) 设置 TCP 和 UDP 端口,格式为port=<value>
。 -
在
[statd]
部分为statd
(rpc.statd
) 设置 TCP 和 UDP 端口,格式为port=<value>
。
-
在
在
/etc/nfs.conf
文件中为 NFS 锁定管理器(nlockmgr
)设置 TCP 和 UDP 端口:-
在
[lockd]
部分为nlockmgr
(rpc.statd
) 设置 TCP 端口,格式为port=value
。或者,也可以使用/etc/modprobe.d/lockd.conf
文件中的nlm_tcpport
选项。 -
在
[lockd]
部分为nlockmgr
(rpc.statd
) 设置 UDP 端口,格式为udp-port=value
。或者,您可以使用/etc/modprobe.d/lockd.conf
文件中的nlm_udpport
选项。
-
在
验证
列出 NFS 服务器中的活跃端口和 RPC 程序:
rpcinfo -p
$ rpcinfo -p
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
9.4. 保护 FTP 服务 复制链接链接已复制到粘贴板!
您可以使用文件传输协议(FTP)来通过网络传输文件。因为服务器的所有 FTP 事务(包括用户身份验证)都未加密,因此确保其被安全配置。
RHEL 8 提供两个 FTP 服务器:
- 红帽内容加速器(
tux
) - 具有 FTP 功能的内核空间 Web 服务器。
- 非常安全的 FTP 守护进程(
vsftpd
) - FTP 服务的一种独立、面向安全的实现。
以下安全指南是用于设置 vsftpd
FTP 服务:
9.4.1. 保护 FTP 的问候横幅 复制链接链接已复制到粘贴板!
当用户连接到 FTP 服务时,FTP 会显示一条问候横幅,其默认包含版本信息。攻击者可以利用此信息识别系统中的弱点。您可以通过更改默认的横幅来隐藏此信息。
您可以通过编辑 /etc/banners/ftp.msg
文件来定义自定义横幅。它可以直接包含一个单行消息,或引用一个单独的文件,其中包含多行消息。
流程
要定义单行消息,请在
/etc/vsftpd/vsftpd.conf
文件中添加以下选项:ftpd_banner=Hello, all activity on ftp.example.com is logged.
ftpd_banner=Hello, all activity on ftp.example.com is logged.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在单独的文件中定义信息:
创建一个
.msg
文件,其中包含横幅消息,如/etc/banners/ftp.msg
:######### Hello, all activity on ftp.example.com is logged. #########
######### Hello, all activity on ftp.example.com is logged. #########
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为了简化多个横幅的管理,请将所有横幅放在
/etc/banners/
目录中。将横幅文件的路径添加到
/etc/vsftpd/vsftpd.conf
文件中的banner_file
选项中:banner_file=/etc/banners/ftp.msg
banner_file=/etc/banners/ftp.msg
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
显示修改后的横幅:
ftp localhost
$ ftp localhost Trying ::1… Connected to localhost (::1). Hello, all activity on ftp.example.com is logged.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
9.4.2. 防止匿名访问并在 FTP 中上传 复制链接链接已复制到粘贴板!
默认情况下,安装 vsftpd
软件包会为匿名用户创建 /var/ftp/
目录和一个目录树,用户对这些目录有只读权限。由于匿名用户可以访问数据,因此请勿将敏感数据存储在这些目录中。
要增加系统的安全性,您可以将 FTP 服务器配置为允许匿名用户将文件上传到特定目录并阻止匿名用户读取数据。在以下流程中,匿名用户可以将文件上传到 root
用户拥有的目录中,但不能更改该它。
流程
在
/var/ftp/pub/
目录中创建只写的目录:mkdir /var/ftp/pub/upload chmod 730 /var/ftp/pub/upload ls -ld /var/ftp/pub/upload
# mkdir /var/ftp/pub/upload # chmod 730 /var/ftp/pub/upload # ls -ld /var/ftp/pub/upload drwx-wx---. 2 root ftp 4096 Nov 14 22:57 /var/ftp/pub/upload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
/etc/vsftpd/vsftpd.conf
文件中添加以下行:anon_upload_enable=YES anonymous_enable=YES
anon_upload_enable=YES anonymous_enable=YES
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
可选:如果您的系统启用了 SELinux 并使用强制(enforcing)模式,请启用 SELinux 布尔值属性
allow_ftpd_anon_write
和allow_ftpd_full_access
。
允许匿名用户在目录中读取和写入,可能会导致服务器成为盗取软件的存储库。
9.4.3. 为 FTP 保护用户帐户 复制链接链接已复制到粘贴板!
FTP 通过不安全的网络以未加密的方式传输用户名和密码以进行身份验证。您可以通过拒绝系统用户从其用户帐户访问服务器来提高 FTP 安全性。
请根据您的配置执行以下几个步骤。
流程
通过在
/etc/vsftpd/vsftpd.conf
文件中添加以下行来禁用vsftpd
服务器中的所有用户帐户:local_enable=NO
local_enable=NO
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
要禁用特定帐户或特定帐户组(如
root
用户和带有sudo
权限的组)对 FTP 的访问,您可以将用户名添加到/etc/pam.d/vsftpd
PAM 配置文件。 -
通过在
/etc/vsftpd/ftpusers
文件中添加用户名来禁用用户帐户。
9.5. 保护 HTTP 服务器 复制链接链接已复制到粘贴板!
9.5.1. httpd.conf 中的安全增强 复制链接链接已复制到粘贴板!
您可以通过在 /etc/httpd/conf/httpd.conf
文件中配置安全选项来提高 Apache HTTP 服务器的安全性。
在将脚本加入到生产环境前,需要验证它们是否可以正常工作。
确保只有 root
用户对包含脚本或通用网关接口(CGI)的任何目录具有写入权限。要将目录所有权改为具有写权限的 root
,请输入以下命令:
chown root <directory_name> chmod 755 <directory_name>
# chown root <directory_name>
# chmod 755 <directory_name>
在 /etc/httpd/conf/httpd.conf
文件中,您可以配置以下选项:
FollowSymLinks
- 这个指令默认为启用,并遵循目录中的符号链接。
索引
- 这个指令被默认启用。禁用这个指令,以防止访问者浏览服务器上的文件。
UserDir
-
这个指令默认为禁用,因为它可以确认系统中存在用户帐户。要激活用户目录浏览
/root/
以外的所有用户目录,使用UserDir enabled
和UserDir disabled
root 指令。要将用户添加到禁用帐户列表中,请在UserDir disabled
行中添加以空格分隔的用户列表。 ServerTokens
这个指令控制向客户端发送的服务器响应标头字段。您可以使用以下参数来自定义信息:
ServerTokens Full
提供所有可用信息,如 Web 服务器版本号、服务器操作系统详情、已安装的 Apache 模块,例如:
Apache/2.4.37 (Red Hat Enterprise Linux) MyMod/1.2
Apache/2.4.37 (Red Hat Enterprise Linux) MyMod/1.2
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Full-Release
提供与发行版本相关的所有可用信息,例如:
Apache/2.4.37 (Red Hat Enterprise Linux) (Release 41.module+el8.5.0+11772+c8e0c271)
Apache/2.4.37 (Red Hat Enterprise Linux) (Release 41.module+el8.5.0+11772+c8e0c271)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Prod / ServerTokens ProductOnly
提供 Web 服务器名称,例如:
Apache
Apache
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Major
提供 Web 服务器主发行版本,例如:
Apache/2
Apache/2
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Minor
提供 Web 服务器次发行版本,例如:
Apache/2.4
Apache/2.4
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Min
/ServerTokens Minimal
提供 Web 服务器最小发行版本,例如:
Apache/2.4.37
Apache/2.4.37
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens OS
提供 Web 服务器发行版本和操作系统,例如:
Apache/2.4.37 (Red Hat Enterprise Linux)
Apache/2.4.37 (Red Hat Enterprise Linux)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
ServerTokens Prod
选项降低攻击者获取任何有关您系统的有价值信息的风险。
不要删除 IncludesNoExec
指令。默认情况下,Server Side Includes (SSI) 模块无法执行命令。更改这个设置可让攻击者在系统中输入命令。
删除 httpd 模块
您可以删除 httpd
模块来限制 HTTP 服务器的功能。编辑 /etc/httpd/conf.modules.d/
或 /etc/httpd/conf.d/
目录中的配置文件。例如,要删除代理模块:
echo '# All proxy modules disabled' > /etc/httpd/conf.modules.d/00-proxy.conf
echo '# All proxy modules disabled' > /etc/httpd/conf.modules.d/00-proxy.conf
9.5.2. 保护 Nginx 服务器配置 复制链接链接已复制到粘贴板!
Nginx 是一个高性能 HTTP 和代理服务器。您可以使用以下配置选项强化 Nginx 配置。
流程
要禁用版本字符串,修改
server_tokens
配置选项:server_tokens off;
server_tokens off;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这个选项将停止显示其他详细信息,如服务器版本号。此配置仅显示 Nginx 提供的所有请求中的服务器名称,例如:
curl -sI http://localhost | grep Server
$ curl -sI http://localhost | grep Server Server: nginx
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 添加额外的安全标头,以缓解特定
/etc/nginx/
conf 文件中的某些已知 Web 应用程序漏洞:例如,
X-Frame-Options
标头选项拒绝您的域之外的任何页面来帧由 Nginx 提供的任何内容,缓解了攻击:add_header X-Frame-Options "SAMEORIGIN";
add_header X-Frame-Options "SAMEORIGIN";
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 例如,
x-content-type
标头在某些较旧的浏览器中可以防止 MIME-type sniffing:add_header X-Content-Type-Options nosniff;
add_header X-Content-Type-Options nosniff;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 例如,
X-XSS-Protection
标头启用跨站点脚本过滤(XSS)过滤,这可防止浏览器渲染由 Nginx 中包含的潜在的恶意内容:add_header X-XSS-Protection "1; mode=block";
add_header X-XSS-Protection "1; mode=block";
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
您可以限制公开的服务,并限制它们对访问者执行的操作,例如:
limit_except GET { allow 192.168.1.0/32; deny all; }
limit_except GET { allow 192.168.1.0/32; deny all; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 该片段将限制对除
GET
和HEAD
外的所有方法的访问。您可以禁用 HTTP 方法,例如:
Allow GET, PUT, POST; return "405 Method Not Allowed" for all others.
# Allow GET, PUT, POST; return "405 Method Not Allowed" for all others. if ( $request_method !~ ^(GET|PUT|POST)$ ) { return 405; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 您可以配置 SSL 来保护 Nginx web 服务器提供的数据,请考虑仅通过 HTTPS 提供它。另外,您可以使用 Mozilla SSL 配置生成器生成在 Nginx 服务器中启用 SSL 的安全配置配置文件。生成的配置确保了,所有已知存在安全漏洞的协议(例如, SSLv2 和 SSLv3),加密程序和哈希算法(例如 3DES 和 MD5) 都已禁用。您还可以使用 SSL 服务器测试来验证您的配置是否满足现代安全要求。
9.6. 通过限制对经过身份验证的用户的访问来保护 PostgreSQL 复制链接链接已复制到粘贴板!
PostgreSQL 是一个对象相关数据库管理系统(DBMS)。在 Red Hat Enterprise Linux 中,PostgreSQL 由 postgresql-server
软件包提供。
您可以通过配置客户端身份验证来降低攻击的风险。pg_hba.conf
配置文件存储在数据库集群的数据目录中,控制客户端身份验证。按照以下步骤为基于主机的验证配置 PostgreSQL。
流程
安装 PostgreSQL:
yum install postgresql-server
# yum install postgresql-server
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下选项之一初始化数据库存储区域:
使用
initdb
工具:initdb -D /home/postgresql/db1/
$ initdb -D /home/postgresql/db1/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 带有
-D
选项的initdb
命令会创建您指定的目录(如果尚未存在),例如/home/postgresql/db1/
。然后,此目录包含数据库中存储的所有数据以及客户端身份验证配置文件。使用
postgresql-setup
脚本:postgresql-setup --initdb
$ postgresql-setup --initdb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 默认情况下,该脚本使用
/var/lib/pgsql/data/
目录。此脚本可以帮助具有基本数据库集群管理的系统管理员。
要允许任何经过身份验证的用户使用其用户名访问任何数据库,请在
pg_hba.conf
文件中修改以下行:local all all trust
local all all trust
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 当使用创建数据库用户和没有本地用户的层次应用程序时,这可能会造成问题。如果您不想显式控制系统中所有用户名,请从
pg_hba.conf
文件中删除local
行条目。重启数据库以应用更改:
systemctl restart postgresql
# systemctl restart postgresql
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 上一命令更新数据库,同时还验证配置文件的语法。
9.7. 保护 Memcached 服务 复制链接链接已复制到粘贴板!
Memcached 是一个开源、高性能分布式内存对象缓存系统。它可以通过降低数据库负载来提高动态 Web 应用程序的性能。
Memcached 是一个内存键值存储,用于任意数据(如字符串和对象)的小块,来自于数据库调用、API 调用或页面渲染的结果。Memcached 允许将内存从未充分利用的区域分配给需要更多内存的应用程序。
2018 年,发现了向公共互联网公开的 Memcached 服务器漏洞 DDoS 扩展攻击。这些攻击利用了使用 UDP 协议进行传输的 Memcached 通信。这个攻击非常有效,因为其具有非常高的放大比率,具有几百字节大小的请求会产生带有几兆字节甚至几百兆字节的响应。
在大多数情况下,memcached
服务不需要向公共互联网公开。如果公开,其本身可能会带有安全问题。远程攻击者可能会泄漏或修改存储在 Memcached 中的信息。
9.7.1. 针对 DDoS 强化 Memcached 复制链接链接已复制到粘贴板!
要降低安全风险,请根据您的配置执行以下步骤。
流程
在 LAN 中配置防火墙。如果您的 Memcached 服务器应只在本地网络访问,请不要将外部流量路由到
memcached
服务使用的端口。例如,从允许的端口列表中删除默认端口11211
:firewall-cmd --remove-port=11211/udp firewall-cmd --runtime-to-permanent
# firewall-cmd --remove-port=11211/udp # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果您在与应用程序相同的机器上使用单一 Memcached 服务器,请设置
memcached
来仅侦听 localhost 流量。修改/etc/sysconfig/memcached
文件中的OPTIONS
值:OPTIONS="-l 127.0.0.1,::1"
OPTIONS="-l 127.0.0.1,::1"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启用简单验证和安全层(SASL)身份验证:
修改或添加
/etc/sasl2/memcached.conf
文件:sasldb_path: /path.to/memcached.sasldb
sasldb_path: /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 SASL 数据库中添加帐户:
saslpasswd2 -a memcached -c cacheuser -f /path.to/memcached.sasldb
# saslpasswd2 -a memcached -c cacheuser -f /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 确保
memcached
用户和组可以访问数据库:chown memcached:memcached /path.to/memcached.sasldb
# chown memcached:memcached /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 通过在
/etc/sysconfig/memcached
文件中的OPTIONS
参数中添加-S
值在 Memcached 中启用 SASL 支持:OPTIONS="-S"
OPTIONS="-S"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重启 Memcached 服务器以应用更改:
systemctl restart memcached
# systemctl restart memcached
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 将 SASL 数据库中创建的用户名和密码添加到应用程序的 Memcached 客户端配置中。
使用 TLS 加密 Memcached 客户端和服务器间的通信:
通过在
/etc/sysconfig/memcached
文件中的OPTIONS
参数中添加-Z
值来启用 Memcached 客户端和服务器间的加密通信:OPTIONS="-Z"
OPTIONS="-Z"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
使用
-o ssl_chain_cert
选项,以 PEM 格式添加证书链文件路径。 -
使用
-o ssl_key
选项添加私钥文件路径。