![在 NixOS 上由 swanctl 启动的脚本中,“sysctl”不可用](https://linux22.com/image/1582588/%E5%9C%A8%20NixOS%20%E4%B8%8A%E7%94%B1%20swanctl%20%E5%90%AF%E5%8A%A8%E7%9A%84%E8%84%9A%E6%9C%AC%E4%B8%AD%EF%BC%8C%E2%80%9Csysctl%E2%80%9D%E4%B8%8D%E5%8F%AF%E7%94%A8.png)
我用strongswan-swanctl在运行的VPN服务器上NixOS。
基本上它可以正常工作,我可以从客户端连接到 VPN 服务器。
services.strongswan-swanctl = {
enable = true;
swanctl = {
authorities = {
"vpnca" = {
cacert = "ca-cert.pem";
};
};
connections = {
"ikev2-eap" = {
version = 2;
proposals = [ "aes192gcm16-aes128gcm16-prfsha256-ecp256-ecp521"
"aes192-sha256-modp3072"
"default" ];
rekey_time = "0s";
pools = [ "primary-pool-ipv4" "primary-pool-ipv6" ];
fragmentation = "yes";
dpd_delay = "30s";
local."1" = {
certs = [ "vpn_example_com.pem" ];
id = "@vpn.example.com";
};
remote."1" = {
auth = "eap-mschapv2";
eap_id = "%any";
};
children = {
"ikev2-eap" = {
local_ts = [ "0.0.0.0/0" "::/0" ];
rekey_time = "0s";
dpd_action = "clear";
esp_proposals = [ "aes192gcm16-aes128gcm16-prfsha256-ecp256-modp3072"
"aes192-sha256-ecp256-modp3072"
"default" ];
updown = "/etc/swanctl/proxyndp.updown";
};
};
local_addrs = [ "192.0.2.1" "2001:db8::2"];
};
};
我遇到的问题是在/etc/swanctl/proxyndp.updown
脚本中:
#! /bin/sh
case $PLUTO_VERB in
up-client-v6)
sysctl -w net.ipv6.conf.all.forwarding=1
sysctl -w net.ipv6.conf.all.proxy_ndp=1
ip -6 neigh add proxy ${PLUTO_PEER_CLIENT%????} dev ens3
;;
down-client-v6)
ip -6 neigh delete proxy ${PLUTO_PEER_CLIENT%????} dev ens3
;;
esac
sysctl
执行此脚本时系统未找到该程序。在普通用户 shell 中,我可以看到该工具,/run/current-system/sw/bin/sysctl
但对于此脚本,我在系统日志中收到以下日志消息:
Feb 12 16:04:01 vpn.example.com charon-systemd[9249]: updown: /etc/swanctl/proxyndp.updown: line 5: sysctl: command not found
Feb 12 16:04:01 vpn.example.com charon-systemd[9249]: updown: /etc/swanctl/proxyndp.updown: line 6: sysctl: command not found
笔记: ip
位于同一文件夹中,可以通过脚本运行。
知道那里出了什么问题吗?
答案1
Nix 表达式之外的行为定义
在我看来,您proxy.updown
自己将文件放入了/etc
。 在 NixOS 上您不应该这样做,因为这样您的系统行为就不仅仅取决于您的 Nix 表达式了。 一切都应该在您的configuration.nix
(或 导入的文件中configuration.nix
)中进行管理。 您无需在 中设置路径services.strongswan-swanctl.swanctl.connections."ikev2-eap".children."ikev2-eap".updown
,而是可以直接提供文件的内容:
updown = ''
sysctl -w net.ipv6.conf.all.forwarding=1
...
'';
sysctl:未找到命令
sysctl
找不到该二进制文件,因为它不是 systemd 服务 PATH 的一部分,如您所见这里sysctl
在源代码中。一个简单的解决方法是直接在 updown 脚本中引用 Nix 存储路径"${pkgs.procps}/bin/sysctl ..."
。
updown = ''
${pkgs.procps}/bin/sysctl -w net.ipv6.conf.all.forwarding=1
...
'';
在构建时,该表达式将转换为类似的内容"/nix/store/8f9cypv6vw5hwkh49l1j6b1rkxi4dbsq-procps-3.3.15/bin/sysctl ..."
。
使用 sysctl 命令的替代方法
如果您可以忍受 sysctl 选项一直被定义而不是仅在您的接口启动时被定义,那么您可以使用该boot.kernel.sysctl
选项。
{ config, pkgs, lib, ...}:{
boot.kernel.sysctl = {
"net.ipv6.conf.all.forwarding" = "1";
"net.ipv6.conf.all.proxy_ndp" = "1";
};
services.strongswan-swanctl = {
...
}
资源
我从未使用过strongswan
,但我认为学习 NixOS 最佳实践的宝贵资源是 NixOS 测试。斯特朗斯旺定义三台虚拟机,启动并测试第一台机器是否可以通过VPN ping 通第三台机器。