systemd服务怎么设置代理?Drop-in、EnvironmentFile与重启验证

Shell里的export不会自动传给后台进程,服务必须重新读取自己的有效环境
发布于
18

在SSH终端里执行 export HTTPS_PROXY=... 后,手工curl可以联网,但后台服务仍然超时,原因通常很简单:systemd启动的服务不继承你当前交互式Shell的环境。代理必须进入该服务的有效配置,并在重新加载和重启后由新进程读取。

变更前先确认软件确实支持环境变量代理。有些服务只读取自己的配置文件,盲目增加变量不会生效。

一、先确认服务名称和实际启动命令

systemctl status your-service
systemctl cat your-service
systemctl show your-service -p FragmentPath -p DropInPaths

查看单元文件、已有drop-in和启动用户。不要直接编辑发行版安装在 /usr/lib/systemd/system 或类似目录的原始单元文件,软件升级可能覆盖它。

二、为什么推荐使用drop-in

drop-in只覆盖需要修改的字段,便于审计、删除和回滚。可使用:

sudo systemctl edit your-service

在编辑器中加入结构示意:

[Service]
Environment="HTTP_PROXY=http://proxy.example:8080"
Environment="HTTPS_PROXY=http://proxy.example:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.internal.example"

实际变量名称、代理URL和NO_PROXY取值以应用文档及企业网络为准。

三、含密码的代理URL不要直接放在公开单元文件

单元配置可能被有权限查询systemd的用户看到,也可能进入诊断包和备份。更安全的做法是使用权限严格的EnvironmentFile或密钥注入机制,并限制服务账户读取。

[Service]
EnvironmentFile=/etc/your-service/proxy.env

环境文件示意:

HTTPS_PROXY=http://user:password@proxy.example:8080
NO_PROXY=localhost,127.0.0.1,.internal.example

文件应由root或专用账户所有,并设置最小读取权限。即使如此,环境变量仍可能被同权限调试工具读取,高敏凭据优先使用应用支持的密钥接口。

四、修改后为什么要daemon-reload

systemd管理器需要重新读取单元定义:

sudo systemctl daemon-reload
sudo systemctl restart your-service

daemon-reload不会自动让业务进程使用新环境;通常还要重启或按应用支持方式重载。重启会不会中断业务,应在变更前确认。

五、怎么确认新配置进入服务

systemctl show your-service -p Environment
systemctl status your-service
journalctl -u your-service --since "10 minutes ago"

注意:显示Environment可能暴露凭据,不应把完整输出贴到公开工单。更可靠的业务验证是让服务访问自有健康端点,并在代理日志中确认节点ID、来源和时间。

六、NO_PROXY要包含哪些内部地址

至少检查localhost、本机依赖、内网域名、数据库、服务发现、元数据服务和必须直连的管理端点。不同程序对域名后缀、端口、CIDR和大小写变量的支持不同,应以该服务使用的HTTP库为准。

不要复制Kubernetes或其他机器的NO_PROXY列表。每个服务的依赖关系不同。

七、服务还是不走代理的常见原因

现象 可能原因
systemctl show有变量,业务仍直连 应用不读取环境变量或内部配置覆盖
只有HTTPS失败 HTTPS_PROXY格式、CONNECT或证书问题
内部服务返回502 NO_PROXY未覆盖内网域名
重启后407 凭据格式、转义、过期或白名单错误
手工命令正常、服务失败 服务用户、DNS、证书库或权限不同

证书错误可参考HTTPS代理TLS与SNI排查,HTTP状态码见代理错误码分层指南

八、特殊字符如何处理

代理密码包含 @:% 或空格时,URL编码和systemd的解析规则可能同时影响结果。不要反复猜转义方式。优先创建只含必要字符的独立代理凭据,或使用应用支持的分字段认证与密钥文件。

测试命令不要把密码直接放进Shell历史。

九、安全回滚怎么做

  1. 保存变更前的有效单元和drop-in列表;
  2. 准备关闭代理后仍可访问的内部依赖;
  3. 变更失败时恢复或删除本次drop-in;
  4. 执行daemon-reload并重启服务;
  5. 验证服务、内部依赖和外部访问恢复;
  6. 撤销不再使用的临时凭据。

远程服务器上操作时,确保管理连接本身不依赖即将修改的代理路径。

十、什么时候不该用全服务代理

若服务只有一个外部接口需要代理,应用内对该客户端单独配置,通常比给整个进程设置全局环境更可控。全局变量可能让监控、数据库、内部API和更新检查都走代理。

Windows和应用级代理的同类作用域问题可参考系统代理与应用代理区别。systemd配置的目标也是最小作用范围,而不是让所有请求都经过同一出口。

常见问题(FAQ)

终端export代理后systemd服务会继承吗?
通常不会。systemd服务由管理器启动,不继承当前SSH Shell环境,需要在服务有效配置中单独设置。
daemon-reload后服务会自动使用新代理吗?
不会自动保证。daemon-reload只让systemd重读单元定义,业务进程通常还需重启或按应用能力重载。
代理密码可以直接写在drop-in里吗?
不建议。单元配置可能被查询或进入诊断包,应使用权限严格的环境文件、密钥系统或应用专用凭据接口。
systemctl show看到变量但服务仍直连怎么办?
检查应用是否支持环境变量、是否被应用配置覆盖,并从服务进程实际访问自有端点做验证。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600