落雨宸的时光机
628 字
3 分钟
在无 Root 的 Linux 机器上运行全功能 Socks5 Netbird
2026-08-13
...

0. 前言#

学校提供无 Root 的机器,无 Root 意味着无法注册 Tun 设备,也就无法使用 Netbird……吗?But at what cost?

不。Netbird 有一个 Netstack Mode,用于禁用 Tun,并对外提供一个 Socks5 代理。想要启用它,需要设置以下环境变量:

export NB_USE_NETSTACK_MODE=true
export NB_SOCKS5_LISTENER_PORT=1080
export NB_ENABLE_LOCAL_FORWARDING=true
export NB_ENABLE_NETSTACK_LOCAL_FORWARDING=true

其中,LOCAL_FORWARDING 用于允许将其他机器的流量转发到本机器(Socks5 Netbird)的对应端口。如果你不需要从其他机器访问本机器(Socks5 Netbird),可以关掉。

1. 配置#

1.1. Nix Package#

由于我惯用 Nix,所以把这个 Socks5 Netbird 打成了一个包,如下:

# pkgs/pkgs/netbird.nix

{ coreutils, netbird, writeShellScriptBin }:

writeShellScriptBin "netbird" ''
  set -euo pipefail

  state_dir="''${NB_STATE_DIR:-$HOME/.config/netbird}"
  config_file="''${NB_CONFIG:-$state_dir/default.json}"
  runtime_base="''${XDG_RUNTIME_DIR:-/run/user/$(${coreutils}/bin/id -u)}"
  runtime_dir="''${NB_RUNTIME_DIR:-$runtime_base/netbird}"
  daemon_addr="''${NB_DAEMON_ADDR:-unix://$runtime_dir/sock}"
  management_url="''${NB_MANAGEMENT_URL:-https://api.netbird.io}"
  log_file="''${NB_LOG_FILE:-console}"

  ${coreutils}/bin/mkdir -p "$state_dir" "$runtime_dir"
  ${coreutils}/bin/chmod 700 "$state_dir" "$runtime_dir"

  export NB_STATE_DIR="$state_dir"
  export NB_CONFIG="$config_file"
  export NB_MANAGEMENT_URL="$management_url"
  export NB_USE_NETSTACK_MODE="''${NB_USE_NETSTACK_MODE:-true}"
  export NB_SOCKS5_LISTENER_PORT="''${NB_SOCKS5_LISTENER_PORT:-1080}"
  export NB_ENABLE_LOCAL_FORWARDING="''${NB_ENABLE_LOCAL_FORWARDING:-true}"
  export NB_ENABLE_NETSTACK_LOCAL_FORWARDING="''${NB_ENABLE_NETSTACK_LOCAL_FORWARDING:-true}"

  case "''${1:-}" in
    service)
      exec ${netbird}/bin/netbird \
        --management-url "$management_url" \
        --daemon-addr "$daemon_addr" \
        --log-file "$log_file" \
        "$@"
      ;;
    up|down|status|login|deregister|debug|state|profile|networks|forwarding|expose|ssh)
      exec ${netbird}/bin/netbird \
        --management-url "$management_url" \
        --daemon-addr "$daemon_addr" \
        --log-file "$log_file" \
        "$@"
      ;;
    *)
      exec ${netbird}/bin/netbird "$@"
      ;;
  esac
''

为了方便初始化,写了这个初始化 Helper:

# pkgs/pkgs/netbird-init.nix

{ coreutils, netbird, writeShellScriptBin }:

writeShellScriptBin "netbird-init" ''
  set -euo pipefail

  usage() {
    echo "usage: netbird-init <setup-key>" >&2
    echo "       NB_SETUP_KEY=<setup-key> netbird-init" >&2
  }

  if [[ "''${1:-}" == "-h" || "''${1:-}" == "--help" ]]; then
    usage
    exit 0
  fi
  if [[ "$#" -gt 1 ]]; then
    usage
    exit 2
  fi

  setup_key="''${NB_SETUP_KEY:-''${1:-}}"
  if [[ -z "$setup_key" ]]; then
    usage
    exit 2
  fi

  runtime_base="''${XDG_RUNTIME_DIR:-/run/user/$(${coreutils}/bin/id -u)}"
  runtime_dir="''${NB_RUNTIME_DIR:-$runtime_base/netbird}"

  systemctl --user start netbird-rootless.service

  for _ in $(${coreutils}/bin/seq 1 30); do
    [[ -S "$runtime_dir/sock" ]] && break
    ${coreutils}/bin/sleep 1
  done
  if [[ ! -S "$runtime_dir/sock" ]]; then
    echo "netbird daemon socket not ready: $runtime_dir/sock" >&2
    exit 1
  fi

  ${netbird}/bin/netbird up \
    --setup-key "$setup_key" \
    --disable-dns \
    --no-browser

  ${netbird}/bin/netbird status
''

接下来只需要起一个服务即可:

# services.nix

{ pkgs, ... }:
let
  localPkgs = import ./pkgs { inherit pkgs; };
in
{
  # Bare rootless NetBird daemon. Registration is manual via netbird-init.
  systemd.user.services.netbird-rootless = {
    Unit = {
      Description = "Rootless NetBird daemon";
      After = [ "network-online.target" ];
      Wants = [ "network-online.target" ];
    };

    Service = {
      Type = "simple";
      Restart = "on-failure";
      RestartSec = "10s";
      RuntimeDirectory = "netbird";
      ExecStart = "${localPkgs.netbird}/bin/netbird service run";
      ExecStop = "${localPkgs.netbird}/bin/netbird down";
      TimeoutStopSec = "30";
    };
  };
}

此外,因为 Rootless Netbird SSH 不走 pam_systemd,所以需要补充环境变量 $XDG_RUNTIME_DIR, $DBUS_SESSION_BUS_ADDRESS,否则 systemctl 会报错 Failed to connect to bus: No medium found:

  programs.fish = {
    enable = true;
    shellInit = lib.mkBefore ''
      if test -z "$XDG_RUNTIME_DIR"; and test -d /run/user/(id -u)
        set -gx XDG_RUNTIME_DIR /run/user/(id -u)
      end

      if test -z "$DBUS_SESSION_BUS_ADDRESS"; and test -n "$XDG_RUNTIME_DIR"; and test -S "$XDG_RUNTIME_DIR/bus"
        set -gx DBUS_SESSION_BUS_ADDRESS unix:path=$XDG_RUNTIME_DIR/bus
      end
    '';
  };

完成。

1.2. Systemctl#

非 Nix-Managed 系统,可以采用如下 systemctl user 配置。

# ~/.config/systemd/user/netbird-rootless.service

[Service]
ExecStart=/home/<Your-Name>/bin/netbird service run
ExecStop=/home/<Your-Name>/bin/netbird down
Restart=on-failure
RestartSec=10s
RuntimeDirectory=netbird
TimeoutStopSec=30
Type=simple

[Unit]
After=network-online.target
Description=Rootless NetBird daemon
Wants=network-online.target

其中 /home/<Your-Name>/bin/netbird 就是刚刚提到的 Wrapper 脚本:

# /home/<Your-Name>/bin/netbird

# 自己去上面抄!

2. 特别注意#

如果需要从外部机器访问本机器,绝对不能 --disable-firewall (DisableFirewall=True),否则会超时!

在无 Root 的 Linux 机器上运行全功能 Socks5 Netbird
https://blog.lzc256.com/posts/running-full-socks5-netbird-on-a-rootless-linux-server/
作者
落雨宸
发布于
2026-08-13
许可协议
CC BY-NC-SA 4.0


Loading Comment Component...