628 字
3 分钟
在无 Root 的 Linux 机器上运行全功能 Socks5 Netbird
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/Loading Comment Component...
