Linux systemd RestrictAddressFamilies 怎样限制服务使用的网络协议族
来源:17golang原创
时间:2026-10-28 13:20:59 117浏览 收藏
Linux 上用 systemd 管理服务时,如果一个进程只需要本地 Unix socket 或普通 TCP,却不应该随意创建原始链路、数据包捕获等地址族,可以在服务单元里使用 RestrictAddressFamilies=。它的核心是给 socket(2) 的地址族做 allow-list 或 deny-list,而不是替代防火墙,也不是把已经传入进程的套接字重新筛一遍。
官方地址:https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RestrictAddressFamilies=
最稳妥的落地方式是先列出服务实际需要的地址族,通常保留AF_UNIX,再按需加入AF_INET或AF_INET6;如果服务由 socket activation 接收套接字,还要把“创建套接字”和“接收传入套接字”分开判断。
- 只限制服务进程通过
socket(2)创建的地址族,不负责端口放行、路由和流量过滤。 - 不写该选项时默认不限制;写地址族列表时是允许列表,前缀
~时是拒绝列表。 AF_UNIX经常承担本地日志、服务管理或 IPC,盲目写成none可能让服务启动后无法工作。
先把它放在正确的隔离层
RestrictAddressFamilies= 解决的是“这个 unit 里的进程能以哪些地址族调用 socket 创建接口”,典型目标是减少服务接触不必要网络协议的机会。它不等于 nftables 规则:不会替你决定哪个端口可以访问,也不会替你配置入站和出站流量策略。
因此,应用服务通常需要把两个问题拆开:systemd 负责缩小进程能创建的地址族,防火墙或网络策略负责控制地址、端口和流量。如果只想让服务访问本机守护进程,优先从 AF_UNIX 开始;如果确实要访问 IPv4 或 IPv6,再显式增加对应地址族。

allow-list 和 deny-list 怎么选
普通列表是 allow-list。例如下面的值允许服务创建本地 Unix socket、IPv4 和 IPv6 socket,其它地址族不在允许范围内:
[Service]
# 只允许本地 IPC、IPv4 和 IPv6,按服务真实依赖删减
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
如果服务确实需要“默认可用,只屏蔽少数地址族”,可以给列表加 ~,形成 deny-list。它适合已有服务依赖较多、暂时只需要排除某个高风险族的迁移阶段,但长期维护时要警惕新地址族被默认放行:
[Service]
# 仅拒绝指定地址族;其它地址族仍可能保持可用
RestrictAddressFamilies=~AF_PACKET
none 表示拒绝所有地址族。它只适合完全不创建 socket 的短任务,不能把它当成“网络服务的默认安全值”。空字符串则用于撤销前面设置过的限制,适合 drop-in 回滚时恢复继承配置。
把配置放进 drop-in,并保留本地通信
生产环境建议用 drop-in 记录加固意图,这样不会直接改发行版提供的原始 unit。下面的示例假设服务名为 report-worker.service,服务需要访问本地日志 socket 和一个 IPv4 上游:
# 创建服务 drop-in 目录;文件名只表达这次隔离意图
sudo mkdir -p /etc/systemd/system/report-worker.service.d
# 写入最小地址族白名单;AF_UNIX 保留本地日志或 IPC 能力
sudo tee /etc/systemd/system/report-worker.service.d/10-network-family.conf
如果服务还需要 IPv6,把 AF_INET6 加入同一个值;如果服务根本不需要网络,只要保留它依赖的本地通信方式即可。上线前要把日志、监控、DNS 解析、数据库驱动和插件的 socket 需求列在清单里,不能只看主进程的业务代码。
为什么 socket activation 仍然可能工作
该选项限制的是进程调用 socket(2) 创建新套接字的行为。systemd socket unit 预先创建并通过激活机制传给服务的套接字,不会因为服务单元设置了 RestrictAddressFamilies= 就被收回。因此,服务可能无法自行创建新的 IPv6 socket,但仍然能够处理 systemd 已经传入的监听 socket。
这也是最容易误判的边界:看到服务仍能接收激活连接,并不能说明地址族白名单没有生效;它可能只是没有走新的 socket(2) 路径。另一方面,socketpair() 创建的连接以及通过其它机制传入的套接字也不应被当作普通新建 socket 来推断。

和其它沙箱选项组合时看清代价
限制地址族只是沙箱的一层。如果目标是减少服务的系统调用面,可以进一步评估官方手册建议的 SystemCallFilter=@service;如果系统支持多种 ABI,还应考虑 SystemCallArchitectures=native,避免服务通过另一种 ABI 绕过预期边界。它们都会增加兼容性成本,应该按服务依赖逐项开启。
常见的回退顺序是:先撤掉 drop-in 中的限制值,确认服务恢复;再逐个加入 AF_UNIX、AF_INET、AF_INET6 等真正需要的族。不要一遇到连接失败就把列表改成全放行,否则失去了定位依赖的机会。
# 临时回退:清空该 drop-in 中的限制,便于确认故障是否由地址族造成
sudo tee /etc/systemd/system/report-worker.service.d/10-network-family.conf
上线前的判断清单
| 检查项 | 应回答的问题 | 常见误区 |
|---|---|---|
| 地址族 | 服务自己创建了哪些 AF_* socket? | 把端口规则当成地址族规则 |
| 本地 IPC | 日志、监控、DNS 或代理是否依赖 AF_UNIX? | 直接写 none 导致辅助功能失效 |
| 激活路径 | 监听 socket 是服务创建还是 socket unit 传入? | 以仍能接收连接判断限制没生效 |
| 兼容性 | 是否需要 IPv4、IPv6 或多 ABI 支持? | 只按开发机网络环境写死白名单 |
归根结底,RestrictAddressFamilies= 适合做“服务进程能创建什么类型 socket”的精细边界。先用 allow-list 表达真实依赖,再单独处理 socket activation、防火墙和系统调用过滤,配置才不会因为职责混杂而难以维护。
常见问题
不写 RestrictAddressFamilies 时默认是什么?
默认不做地址族限制,服务进程可以使用系统允许的地址族。要收紧范围,需要在 unit 或 drop-in 中显式设置。
只允许 AF_INET 会影响本地日志吗?
可能会。很多本地日志或 IPC 路径使用 AF_UNIX;如果服务存在这类依赖,应把 AF_UNIX 一并加入允许列表。
RestrictAddressFamilies 能替代防火墙吗?
不能。它限制创建 socket 时可用的地址族,不负责端口、地址、路由或流量策略,仍需配合网络访问控制。
socket activation 传入的 socket 会被过滤吗?
不会按普通新建 socket 的路径重新过滤。服务单元收到的激活 socket 可能继续工作,所以要把监听 socket 的配置和服务进程的新建 socket 分开审查。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
223 收藏
-
225 收藏
-
301 收藏
-
216 收藏
-
108 收藏
-
434 收藏
-
112 收藏
-
404 收藏
-
118 收藏
-
382 收藏
-
430 收藏
-
123 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习