gotosocial/docs/locales/zh/advanced/security/firewall.md

175 lines
8.8 KiB
Markdown
Raw Normal View History

# 防火墙
你应该在你的实例上部署防火墙,以关闭任何开放端口,并提供一个机制来封禁可能行为不端的客户端。许多防火墙前端还会自动安装一些规则来屏蔽明显的恶意数据包。
部署工具来监控日志文件中的某些趋势,并自动封禁表现出某种行为的客户端是很有帮助的。这可以用于监控你的 SSH 和 Web 服务器访问日志,以应对如 SSH 暴力破解攻击。
## 端口
对于 GoToSocial你需要确保端口 `443` 保持开放。没有它,任何人都无法访问你的实例。联合将失败,客户端应用程序将无法正常工作。
如果你使用 ACME 或 GoToSocial 的内置 Lets Encrypt 支持[配置 TLS 证书](../certificates.md),你还需要开放端口 `80`
为了通过 SSH 访问你的实例,你还需要保持 SSH 守护进程绑定的端口开放。默认情况下SSH 端口是 `22`
## ICMP
[ICMP](https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol) 是在机器之间交换数据,以检测某些网络条件或排除故障的协议。许多防火墙倾向于完全屏蔽 ICMP但这并不理想。应该允许一些 ICMP 类型,你可以使用防火墙为它们配置速率限制。
### IPv4
为了确保功能可靠,你的防火墙必须允许:
* ICMP 类型 3"目标不可达",并有助于路径 MTU 发现
* ICMP 类型 4"源抑制"
如果你希望能够 ping 或被 ping还应允许
* ICMP 类型 0"回显应答"
* ICMP 类型 8"回显请求"
为了 traceroute 能够工作,还可以允许:
* ICMP 类型 11"时间超限"
### IPv6
IPv6 协议栈的所有部分非常依赖 ICMP屏蔽它会导致难以调试的问题。[RFC 4890](https://www.rfc-editor.org/rfc/rfc4890) 专门为此而写,值得查看。
简单来说,你必须始终允许:
* ICMP 类型 1"目标不可达"
* ICMP 类型 2"数据包过大"
* ICMP 类型 3代码 0"时间超限"
* ICMP 类型 4代码 1, 2"参数问题"
对于 ping你应该允许
* ICMP 类型 128"回显请求"
* ICMP 类型 129"回显应答"
## 防火墙配置
在 Linux 上,通常使用 [iptables](https://en.wikipedia.org/wiki/Iptables) 或更现代、更快的 [nftables](https://en.wikipedia.org/wiki/Nftables) 作为后端进行防火墙配置。大多数发行版正在转向使用 nftables许多防火墙前端可以配置为使用 nftables。你需要参考发行版的文档但通常会有一个 `iptables``nftables` 服务,可以通过预定义的位置加载防火墙规则。
手动使用原始的 iptables 或 nftables 规则提供了最大的控制精度,但如果不熟悉这些系统,这样做可能会有挑战。为了帮助解决这个问题,存在许多配置前端可以使用。
在 Debian 和 Ubuntu 以及 openSUSE 系列的发行版中,通常使用 UFW。它是一个简单的防火墙前端许多针对这些发行版的教程都会使用它。
对于 Red Hat/CentOS 系列的发行版,通常使用 firewalld。它是一个更高级的防火墙配置工具也有桌面 GUI 和 [Cockpit 集成](https://cockpit-project.org/)。
尽管发行版有各自偏好,你可以在任何 Linux 发行版中使用 UFW、firewalld 或其他完全不同的工具。
* [Ubuntu Wiki](https://wiki.ubuntu.com/UncomplicatedFirewall?action=show&redirect=UbuntuFirewall) 关于 UFW 的介绍
* [ArchWiki](https://wiki.archlinux.org/title/Uncomplicated_Firewall) 关于 UFW 的介绍
* DigitalOcean 指南 [在 Ubuntu 22.04 上使用 UFW 建立防火墙](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-22-04)
* [firewalld](https://firewalld.org/) 项目主页及文档
* [ArchWiki](https://wiki.archlinux.org/title/firewalld) 关于 firewalld 的介绍
* [使用和配置 firewalld](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_firewalls_and_packet_filters/using-and-configuring-firewalld_firewall-packet-filters) 的 Red Hat 文档
* Linode 指南 [如何使用 firewalld](https://www.linode.com/docs/guides/introduction-to-firewalld-on-centos/)
## 暴力攻击防护
[fail2ban](https://www.fail2ban.org) 和 [SSHGuard](https://www.sshguard.net/) 可以配置以监控日志文件中暴力破解登录和其他恶意行为的尝试。它们可以配置为自动插入防火墙规则,以屏蔽恶意 IP 地址,屏蔽可以是暂时的,也可以是永久的。
SSHGuard 最初只为 SSH 设计但现在支持多种服务。Fail2ban 往往支持任何可生成一致日志行的服务,而 SSHGuard 的签名方法可以捕获更复杂或隐蔽的攻击,因为它随着时间的推移计算攻击分数。
SSHGuard 和 fail2ban 都带有后端,可以直接针对 iptables 和 nftables或与你选择的前端如 UFW 或 firewalld 在 Linux 上工作,在 \*BSD 系统上可以使用 pf。确保查看其文档以正确配置。
* [ArchWiki](https://wiki.archlinux.org/title/Fail2ban) 关于 fail2ban 的介绍
* DigitalOcean 指南如何在 Ubuntu 上使用 [fail2ban 保护 SSH](https://www.digitalocean.com/community/tutorial_collections/how-to-protect-ssh-with-fail2ban)
* Linode 指南如何使用 [fail2ban 保护服务器](https://www.linode.com/docs/guides/using-fail2ban-to-secure-your-server-a-tutorial/)
* [ArchWiki](https://wiki.archlinux.org/title/sshguard) 关于 sshguard 的介绍
* [FreeBSD 手册](https://man.freebsd.org/cgi/man.cgi?query=sshguard&sektion=8&manpath=FreeBSD+13.2-RELEASE+and+Ports) sshguard 的介绍
* [SSHGuard 设置](https://manpages.ubuntu.com/manpages/lunar/en/man7/sshguard-setup.7.html) 的 Ubuntu 手册
对于 fail2ban可以使用以下正则表达式该正则表达式在身份验证失败时触发 fail2ban而不是其他“未经授权”的错误例如 API
```regex
statusCode=401 path=/auth/sign_in clientIP=<HOST> .* msg=\"Unauthorized:
```
## IP 屏蔽
GoToSocial 实现了速率限制,以保护你的实例不被单个主体占用所有处理能力。然而,如果你知道这不是合法流量,或者来自你不想与之联邦的实例,你可以屏蔽流量来源的 IP以节省 GoToSocial 的处理能力。
### Linux
屏蔽 IP 是通过 iptables 或 nftables 实现的。如果你使用 UFW 或 firewalld 等防火墙前端,请使用其功能来屏蔽 IP。
在 iptables 中,人们倾向于在 `filter` 表的 `INPUT` 链中为 IP 添加一个 `DROP` 规则。在 nftables 中,通常在一个具有 `ip``ip6` 地址族的链的表中完成。在这些情况下,内核已经对传入流量进行了大量不必要的处理,然后再通过 IP 匹配进行屏蔽。
使用 iptables 时,可以更有效地使用 `mangle` 表和 `PREROUTING` 链。你可以查看这篇博客文章,[了解它在 iptables 中的工作原理][iptblock]。对于 nftables你可能会想要使用 [`netdev` family][nftnetdev] 进行屏蔽。
[iptblock]: https://javapipe.com/blog/iptables-ddos-protection/
[nftnetdev]: https://wiki.nftables.org/wiki-nftables/index.php/Nftables_families#netdev
#### iptables
使用 `iptables` 屏蔽 IP 的示例:
```
iptables -t mangle -A PREROUTING -s 1.0.0.0/8 -j DROP
ip6tables -t mangle -A PREROUTING -s fc00::/7 -j DROP
```
当使用 iptables 时,添加许多规则会显著降低速度,包括在添加/删除规则时重新加载防火墙。由于你可能希望屏蔽许多 IP 地址,请使用 [ipset 模块][ipset] 并为集合添加单个屏蔽规则。
[ipset]: https://ipset.netfilter.org/ipset.man.html
首先创建你的集合并添加一些 IP
```
ipset create baddiesv4 hash:ip family inet
ipset create baddiesv6 hash:ip family inet6
ipset add baddiesv4 1.0.0.0/8
ipset add baddiesv6 fc00::/7
```
然后,更新你的 iptables 规则以针对该集合:
```
iptables -t mangle -A PREROUTING -m set --match-set baddiesv4 src -j DROP
ip6tables -t mangle -A PREROUTING -m set --match-set baddiesv6 src -j DROP
```
#### nftables
对于 nftables你可以使用如下配置
```
table netdev filter {
chain ingress {
set baddiesv4 {
type ipv4_addr
flags interval
elements = { \
1.0.0.0/8, \
2.2.2.2/32 \
}
}
set baddiesv6 {
type ipv6_addr
flags interval
elements = { \
2620:4f:8000::/48, \
fc00::/7 \
}
}
type filter hook ingress device <interface name> priority -500;
ip saddr @baddiesv4 drop
ip6 saddr @baddiesv6 drop
}
}
```
### BSDs
使用 pf 时,你可以创建一个通常命名为 `<badhosts>` 的持久化表,将需要屏蔽的 IP 地址添加到该表中。表格还可以从其他文件读取,因此可以将 IP 列表保存在主 `pf.conf` 之外。
有关如何执行此操作的示例,可以在 [pf 手册][manpf] 中找到。
[manpf]: https://man.openbsd.org/pf.conf#TABLES