## 0.前期准备 某些业务场景下需要构建安全可靠的网络隧道,来打通异地内网环境或从外部访问内网的私有资源。 经过实际测试,当 TS 服务器具有 IPv6 GUA 地址时,能稳定建立隧道。 本文将使用 Debian 云镜像以及 `Tailscale` 来制作内网组网服务器。 对于虚拟机创建部分,请参考 [04.PVE创建模板虚拟机](./04.PVE创建模板虚拟机.md) ,其他 `Cloud-Init` 相关参数如下。 |参数|值|说明| |--|--|--| |虚拟机名称|`SVR01`| TS 服务器 `主机名` | |DNS 域|`fox.internal`| TS 服务器 `Cloud-Init` | |DNS 服务器|`172.16.1.1`| TS 服务器 `Cloud-Init` | |IPv4|`172.16.1.4/24`| TS 服务器 `Cloud-Init` | |IPv4 网关|`172.16.1.1`| TS 服务器 `Cloud-Init` | |IPv6|`SLAAC`| TS 服务器 `Cloud-Init` | ## 1.配置系统 由于 TS 服务器具备路由功能,所以在配置方法和系统参数方面与内网 DNS 服务器有一些区别。 ### 1.1.配置 SSH 与配置 Debian 模板虚拟机时一样,首先需要调整系统的 SSH 登录权限参数。 在虚拟机的命令行界面,使用 `vim` 编辑器编辑 `sshd` 服务的配置文件,执行以下命令。 ```bash ## 编辑 SSH 配置文件 $ sudo vim /etc/ssh/sshd_config.d/10-server-sshd.conf ``` 在配置文件中输入以下内容,并保存。 ```bash ## SSH 配置项 PasswordAuthentication yes PermitEmptyPasswords no UseDNS no ``` 修改完成后,需要重启 SSH 服务。 ```bash ## 重启 ssh.service $ sudo systemctl restart ssh.service ``` ### 1.2.配置软件源 使用如下命令对 `debian.sources` 配置文件进行修改。 ```bash ## 配置 Debian 系统默认软件源脚本 $ sudo tee /etc/apt/sources.list.d/debian.sources >/dev/null <<'EOF' Types: deb URIs: https://mirrors.ustc.edu.cn/debian Suites: trixie trixie-updates Components: main contrib non-free non-free-firmware Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg Types: deb URIs: https://mirrors.ustc.edu.cn/debian-security Suites: trixie-security Components: main contrib non-free non-free-firmware Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg EOF ``` 为了防止 `Cloud-Init` 服务意外修改软件源配置,需要添加文件保护,执行以下命令。 ```bash ## 增加文件保护 $ sudo chattr +i /etc/apt/sources.list.d/debian.sources ## 检查文件保护 $ lsattr /etc/apt/sources.list.d/debian.sources #### 示例输出 ----i---------e------- /etc/apt/sources.list.d/debian.sources ``` ### 1.3.安装软件 软件源设置完成后,需要更新系统,执行以下命令。 ```bash ## 清理不必要的包 $ sudo bash -c 'apt clean && apt autoclean && apt autoremove --purge' ## 更新软件源 $ sudo apt update ## 更新系统 $ sudo apt full-upgrade ``` 接下来安装系统必要软件,安装 `iperf3` 后,系统将询问是否将其作为系统服务开机自启,选择 `no` 即可。 ```bash ## 安装系统软件 $ sudo apt install btop cronie curl git logrotate neovim qemu-guest-agent tmux zsh ## 安装系统自动更新工具 $ sudo apt install powermgmt-base unattended-upgrades ## 安装网络工具 $ sudo apt install conntrack dnsmasq ethtool knot-dnsutils lsof networkd-dispatcher nftables sshguard ## 安装 TS $ curl -fsSL https://tailscale.com/install.sh | sh ## 安装网络检测工具(可选) $ sudo apt install iftop iperf iperf3 ## 刷新 systemd 日志分类索引 $ sudo journalctl --update-catalog ## 写入磁盘 $ sudo sync ``` ### 1.4.配置 ZSH `Zsh` 是比 `Bash` 好用的 `Shell` 程序,使用 `oh-my-zsh` 进行配置。 ```bash ## 安装 oh-my-zsh $ sh -c "$(curl -fsSL https://install.ohmyz.sh)" ## 询问是否切换默认 shell,输入 Y #### 示例输出 Time to change your default shell to zsh: Do you want to change your default shell to zsh? [Y/n] y ## oh-my-zsh 安装后清理 $ cd && rm -rvf .bash_history .zsh_history .shell.pre-oh-my-zsh ``` ### 1.5.配置默认编辑器 Debian 系统默认编辑器为 `nano` ,推荐将默认编辑器更换为 `neovim` ,执行以下命令。 ```bash ## 修改系统默认编辑器(选择 nvim 所在条目,即可将 neovim 设为默认编辑器) $ sudo update-alternatives --config editor #### 系统默认编辑器示例输出 There are 4 choices for the alternative editor (providing /usr/bin/editor). Selection Path Priority Status ------------------------------------------------------------ * 0 /bin/nano 40 auto mode 1 /bin/nano 40 manual mode 2 /usr/bin/nvim 30 manual mode 3 /usr/bin/vim.basic 30 manual mode 4 /usr/bin/vim.tiny 15 manual mode Press to keep the current choice[*], or type selection number: 2 update-alternatives: using /usr/bin/nvim to provide /usr/bin/editor (editor) in manual mode ``` 若需完全禁用 `neovim` 鼠标功能;即关闭所有鼠标交互,右键行为完全交给终端 / 控制台处理,需执行以下命令。 ```bash ## 配置 nvim 鼠标交互行为脚本 $ sudo install -D -m 0644 /dev/stdin /etc/xdg/nvim/sysinit.vim <<'EOF' set mouse= EOF ``` ### 1.6.调整内核模块 编辑 **内核模块** 配置文件,执行以下命令。 ```bash ## 创建 内核模块 配置文件 $ sudo tee /etc/modules-load.d/10-server-modules.conf >/dev/null <<'EOF' # This configuration file is customized by fox, # Optimize netfilter related modules at system boot. nf_conntrack EOF ``` ### 1.7.调整内核参数 编辑 **内核参数** 配置文件,执行以下命令。 ```bash ## 编辑 内核参数 配置文件 $ sudo tee /etc/sysctl.d/99-sysctl.conf >/dev/null <<'EOF' # This configuration file is customized by fox, # Optimize sysctl parameters for local TS server. kernel.panic = 20 kernel.panic_on_oops = 1 net.core.default_qdisc = fq_pie net.ipv4.tcp_congestion_control = bbr net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 net.ipv6.conf.default.forwarding = 1 # Other adjustable system parameters net.core.netdev_budget = 800 net.core.netdev_max_backlog = 8192 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 67108864 net.core.wmem_max = 67108864 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.default.arp_ignore = 1 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.igmp_max_memberships = 256 net.ipv4.tcp_fastopen = 3 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_notsent_lowat = 131072 net.ipv4.tcp_rmem = 4096 1048576 67108864 net.ipv4.tcp_wmem = 4096 1048576 67108864 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 net.ipv6.conf.all.use_tempaddr = 0 net.ipv6.conf.default.use_tempaddr = 0 net.netfilter.nf_conntrack_acct = 1 net.netfilter.nf_conntrack_checksum = 1 net.netfilter.nf_conntrack_tcp_timeout_established = 7440 EOF ``` 配置文件编辑完成后,重启系统或者执行以下命令让配置生效。 ```bash ## 让内核参数生效 $ sudo sysctl --system ``` ### 1.8.调整系统时间 默认情况下 Debian 云镜像的系统时间需要调整,执行以下命令将系统时区设置为中国时区。 ```bash ## 设置系统时区 $ sudo timedatectl set-timezone Asia/Shanghai ## 检查系统时间 $ date -R ``` Debian 云镜像默认使用 `systemd-timesyncd.service` 同步时间,且需要调整为使用国内 NTP 服务器。 调整 NTP 服务器参数,执行以下命令。 ```bash ## 创建 NTP 配置目录 $ sudo mkdir -p /etc/systemd/timesyncd.conf.d ## 创建 NTP 配置文件 $ sudo tee /etc/systemd/timesyncd.conf.d/10-server-ntp.conf >/dev/null <<'EOF' # This configuration file is customized by fox, # Optimize system NTP server. [Time] NTP=ntp.aliyun.com ntp.tencent.com cn.pool.ntp.org EOF ``` 配置文件编辑完成后,需重启 `systemd-timesyncd.service` 服务,并再次检查系统 NTP 服务器地址。 ```bash ## 重启 systemd-timesyncd.service $ sudo systemctl restart systemd-timesyncd.service ## 检查系统 NTP 服务器 $ sudo systemctl status systemd-timesyncd.service ``` ### 1.9.配置自动更新 配置系统自动更新策略,执行以下命令,使用键盘 `左右方向键` 进行选择,`回车键` 进行确认。 ```bash ## 配置自动更新策略 $ sudo dpkg-reconfigure -plow unattended-upgrades ## 选择 “是” ``` 开始调整 `20auto-upgrades` 配置文件。 配置文件中,用来控制更新周期的参数为 `APT::Periodic::Unattended-Upgrade` ,`5` 表示更新周期为 `5` 天。 ```bash ## 编辑 20auto-upgrades 配置文件 $ sudo tee /etc/apt/apt.conf.d/20auto-upgrades >/dev/null <<'EOF' APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "5"; APT::Periodic::AutocleanInterval "1"; APT::Periodic::CleanInterval "1"; EOF ``` 进一步调整 `50unattended-upgrades` 配置文件。 ```bash ## 编辑 50unattended-upgrades 配置文件 $ sudo editor /etc/apt/apt.conf.d/50unattended-upgrades ``` 因为该配置文件很长,完整的配置文件可查看 [debian_ts_50unattended_upgrades.conf](./src/debian/debian_ts_50unattended_upgrades.conf) 以便对比。 ```bash ## 删除以下行前面的注释符 // ,代表启用 "origin=Debian,codename=${distro_codename}-updates"; ## 添加 TS 更新项目 "origin=Tailscale,codename=${distro_codename},label=Tailscale"; ## 在配置文件末尾增加以下内容,代表启用,并调整参数 Unattended-Upgrade::AutoFixInterruptedDpkg "true"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "13:00"; ``` 系统自动更新配置文件修改完成后,需调整自动更新定时器,执行以下命令。 ```bash ## 配置系统定时器 $ sudo systemctl edit apt-daily-upgrade.timer ``` 根据配置文件中的提示,在中间空白处填入以下内容。 ```bash ## 定时器配置项 [Timer] OnCalendar= OnCalendar=12:00 RandomizedDelaySec=0 ``` 设置完成后,重启自动更新定时器并检查其状态,执行以下命令。 在输出结果中,看到系统自动更新的触发时间为 `12:00` 则表示设置正确。 ```bash ## 重启触发器 $ sudo systemctl restart apt-daily-upgrade.timer ## 再次检查触发器状态 $ sudo systemctl status apt-daily-upgrade.timer ``` ### 1.10.配置防火墙 修改防火墙配置之前,需检查 `nftables.service` 服务状态,确保该服务开机自启。 ```bash ## 检查 nftables.service $ sudo systemctl status nftables.service ## 设置 nftables.service 开机自启 $ sudo systemctl enable nftables.service ``` 由于防火墙规则内容较多,请打开文件 [debian_ts_nftables.conf](./src/debian/debian_ts_nftables.conf) ,复制全文内容,完整替换 `nftables` 配置文件中的现有配置。 ```bash ## 编辑 nftables 配置文件 $ sudo editor /etc/nftables.conf ``` 配置完成后,先检查防火墙规则,再重启 `nftables.service` 服务。 ```bash ## 检查 nftables 配置文件 $ sudo nft --check --file /etc/nftables.conf ## 重启 nftables.service $ sudo systemctl restart nftables.service ``` ### 1.11.调整系统端口 为了正常使用 `53` 端口,需要对 `systemd-resolved.service` 进行配置,执行以下命令。 ```bash ## 创建 systemd-resolved 配置目录 $ sudo mkdir -p /etc/systemd/resolved.conf.d ## 创建 systemd-resolved 配置文件 $ sudo tee /etc/systemd/resolved.conf.d/10-server-dns.conf >/dev/null <<'EOF' # This configuration file is customized by fox, # Optimize system resolve parameters for local TS server. [Resolve] DNS=127.0.0.1 DNS=::1 DNSStubListener=no LLMNR=no MulticastDNS=no EOF ``` 配置文件编辑完成后,还需调整系统 `resolv.conf` 配置文件,执行以下命令。 ```bash ## 创建 resolv.conf 软链接 $ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf ``` 配置完成后,需重启 `systemd-resolved.service` 服务。 ```bash ## 重启 systemd-resolved.service $ sudo systemctl restart systemd-resolved.service ``` ### 1.12.配置 Dnsmasq 检查 `dnsmasq.service` 服务状态,确保该服务开机自启。 ```bash ## 检查 dnsmasq.service $ sudo systemctl status dnsmasq.service ## 设置 dnsmasq.service 开机自启 $ sudo systemctl enable dnsmasq.service ``` `Dnsmasq` 的主配置文件一般位于 `/etc` 目录下,修改配置文件之前,执行以下命令。 ```bash ## 创建 Dnsmasq 配置目录 $ sudo mkdir -p /etc/dnsmasq.d ``` 创建 `Dnsmasq` 主配置文件,执行以下命令。 ```bash ## 创建 Dnsmasq 主配置文件 $ sudo editor /etc/dnsmasq.d/10-server-dnsmasq.conf ``` 在编辑器对话框中输入以下内容,并保存。 **额外说明:** - 请根据系统内存使用情况,调整缓存参数 `cache-size` - 配置文件中监听的网卡名为 `eth0` 和 `tailscale0` ,请根据实际情况进行调整 - 配置文件中内网域名为 `fox.internal` ,请根据实际情况进行调整 - `Dnsmasq` 上游 DNS 服务器分为三类,请根据实际情况进行调整 - `server=/ts.net/100.100.100.100` :TS 服务 `MagicDNS` 专用 DNS 服务器 - `server=/fox.internal/172.16.1.1` :内网域名解析 DNS 服务器,通常为主路由地址 - `server` 参数中的其他 DNS 服务器供 TS 服务器自身及其下游设备使用 ```bash # This configuration file is customized by fox, # Optimize dnsmasq parameters for local TS server. # Main Config log-facility=/var/log/dnsmasq.log log-async=20 cache-size=2048 max-cache-ttl=7200 fast-dns-retry=1800 interface=eth0,tailscale0 bind-dynamic bogus-priv domain-needed no-hosts no-ident no-resolv no-round-robin stop-dns-rebind rebind-domain-ok=/fox.internal/ts.net/ # DNS Filter local=/alt/ local=/bind/ local=/example/ local=/home.arpa/ local=/internal/ local=/invalid/ local=/lan/ local=/local/ local=/localhost/ local=/onion/ local=/test/ # DNS Server server=/fox.internal/172.16.1.1 server=/ts.net/100.100.100.100 server=172.16.1.1 ``` 配置完成后,需重启 `dnsmasq.service` 服务。 ```bash ## 重启 dnsmasq.service $ sudo systemctl restart dnsmasq.service ``` ## 2. Tailscale 根据不同的启动参数,TS 服务将具有不同的业务能力。 ### 2.1.网卡调优 根据 TS 官方文档 [Performance best practices](https://tailscale.com/docs/reference/best-practices/performance) 的技术指引,Linux 转发节点可通过调整网卡 Offload 参数提升 UDP 性能。 为了在网卡重新上线后自动恢复参数,本文使用 `networkd-dispatcher` 监听 `routable` 状态。 优化脚本直接使用事件中的 `IFACE` ,仅处理由 `systemd-networkd` 配置的底层网卡,并跳过 `tailscale0` 和其他 TUN 设备。 首先检查 TS 服务器的底层出口网卡。 ```bash ## 检查 systemd-networkd 状态 $ systemctl is-active systemd-networkd ## 获取由 networkd 配置且已上线的以太网卡 $ NETDEV=$(networkctl list --no-legend --no-pager | awk '$3 == "ether" && $4 == "routable" && $5 == "configured" {print $2; exit}') ## 检查网卡管理状态 $ networkctl status "$NETDEV" ``` `systemd-networkd` 应显示为 `active` ,底层出口网卡应显示为 `State: routable (configured)` 。 检查完成后,创建 `networkd-dispatcher` 的 `routable` 事件脚本。 ```bash ## 创建 routable 事件脚本目录 $ sudo install -d -o root -g root -m 0755 /etc/networkd-dispatcher/routable.d ## 创建 TS 网卡优化脚本 $ sudo editor /etc/networkd-dispatcher/routable.d/50-tailscale ``` 在脚本文件中输入以下内容,并保存。 **额外说明:** - 脚本会记录跳过、成功或失败原因,并在执行失败时保留 `ethtool` 的原始退出状态 - `networkd-dispatcher` 会记录非零退出警告,但不会停止服务或立即重试 - 网卡再次进入 `routable` 状态时,脚本会重新执行 ```bash #!/bin/sh # # This script is customized by fox, # Optimize NIC offload parameters for local TS server. # if [ -z "${IFACE:-}" ]; then echo "Error: IFACE is not set." >&2 exit 1 fi if [ -z "${AdministrativeState:-}" ]; then echo "Error: AdministrativeState is not set for $IFACE." >&2 exit 1 fi if [ "$AdministrativeState" != "configured" ]; then echo "Skipping network device $IFACE: administrative state is $AdministrativeState." exit 0 fi if [ ! -e "/sys/class/net/$IFACE/device" ]; then echo "Skipping network device $IFACE: no hardware device is associated." exit 0 fi ETHTOOL_PATH=$(command -v ethtool 2>/dev/null) if [ -z "$ETHTOOL_PATH" ]; then echo "Error: ethtool command not found in PATH. Please install ethtool." >&2 exit 127 fi if "$ETHTOOL_PATH" -K "$IFACE" rx-udp-gro-forwarding on rx-gro-list off; then echo "Configured network device $IFACE using $ETHTOOL_PATH successfully." else exit_status=$? echo "Error: $ETHTOOL_PATH failed to configure network device $IFACE (exit status $exit_status)." >&2 exit "$exit_status" fi ``` `networkd-dispatcher` 仅执行属于 `root` 且具有可执行权限的脚本,执行以下命令进行设置。 ```bash ## 设置脚本所有者 $ sudo chown root:root /etc/networkd-dispatcher/routable.d/50-tailscale ## 设置脚本可执行权限 $ sudo chmod 0755 /etc/networkd-dispatcher/routable.d/50-tailscale ## 设置脚本文件防篡改 $ sudo chattr +i /etc/networkd-dispatcher/routable.d/50-tailscale ``` 设置完成后,手动模拟网卡事件,检查脚本能否正常应用参数。 ```bash ## 测试 TS 网卡优化脚本 $ sudo env IFACE="$NETDEV" AdministrativeState=configured /etc/networkd-dispatcher/routable.d/50-tailscale ``` 由于 TS 虚拟机不包含无线网卡,可通过 `systemd` 日志过滤器忽略无线工具探测信息。 ```bash ## 编辑 networkd-dispatcher.service 服务扩展配置 $ sudo systemctl edit networkd-dispatcher.service ``` 根据配置文件中的提示,在中间空白处填入以下内容。 ```bash ## 日志过滤配置项 [Service] LogFilterPatterns=~^No valid path found for iw(config)?$ ``` 测试通过后,启动 `networkd-dispatcher` 并设置为开机自启状态。 ```bash ## 设置 networkd-dispatcher 开机自启 $ sudo systemctl enable --now networkd-dispatcher.service ## 验证启动状态事件补发机制 $ sudo systemctl restart networkd-dispatcher.service ``` 最后检查网卡优化参数。 ```bash ## 检查网卡优化参数 $ sudo ethtool -k "$NETDEV" | grep -E 'rx-udp-gro-forwarding|rx-gro-list' #### 网卡优化后 ethtool 示例输出 rx-gro-list: off rx-udp-gro-forwarding: on ``` ### 2.2.启动模式 若仅需 TS 组网功能,执行以下命令。 ```bash ## TS 普通组网模式 $ sudo tailscale up ``` 若需 TS 提供 `Exit Node` 功能,执行以下命令。 ```bash ## TS Exit Node 模式 $ sudo tailscale up --advertise-exit-node --reset ## TS Exit Node 模式,但不使用 MagicDNS $ sudo tailscale up --advertise-exit-node --accept-dns=false --reset ``` 若需 TS 提供内网路由功能并能访问内网私有服务,执行以下命令。 **额外说明:** - 请根据内网网段,调整 TS 内网路由参数 `advertise-routes` ```bash ## TS 内网路由模式 $ sudo tailscale up --advertise-exit-node --accept-routes --advertise-routes=172.16.1.0/24 --reset ``` 执行命令后,TS 将自动显示登录链接,只需根据链接进行登录操作即可。 ### 2.3.自动更新 目前 TS 将跟随系统自动更新,若需额外开启 TS 的自动更新功能,执行以下命令。 ```bash ## TS 开启自动更新 $ sudo tailscale set --auto-update ## TS 关闭自动更新 $ sudo tailscale set --auto-update=false ``` ### 2.4.定时任务 本步骤为可选操作,主要用于设置 TS 定时重启。 ```bash ## 创建 Tailscale 定时重启任务 $ sudo tee /etc/cron.d/tailscale-restart >/dev/null <<'EOF' 30 10 * * * root /usr/bin/systemctl restart tailscaled.service EOF ## 设置定时任务文件权限 $ sudo chmod 0644 /etc/cron.d/tailscale-restart ``` 至此,TS 服务器已配置完成。