在 NixOS 上由 swanctl 启动的脚本中,“sysctl”不可用

在 NixOS 上由 swanctl 启动的脚本中,“sysctl”不可用

我用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 通第三台机器。

相关内容