gotosocial/docs/locales/zh/advanced/security/firewall.md
2024-11-02 05:58:56 +08:00

175 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 防火墙
你应该在你的实例上部署防火墙,以关闭任何开放端口,并提供一个机制来封禁可能行为不端的客户端。许多防火墙前端还会自动安装一些规则来屏蔽明显的恶意数据包。
部署工具来监控日志文件中的某些趋势,并自动封禁表现出某种行为的客户端是很有帮助的。这可以用于监控你的 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