Ubuntu 22.04 安装 sshuttle 指南
Ubuntu 22.04 安装 sshuttle 的四种方案实测:apt 在线(1.0.5-1ubuntu4)、pip venv(2.0.0)、离线 wheel、git 源码,含 SSH 免密、sudo 免密、升级降级卸载与常见问题排障,全部命令附真实回显
Ubuntu 22.04 安装 sshuttle 指南
目标:在 Ubuntu 22.04 服务器上从零装好 sshuttle 并打通到远端网络的隧道前置——覆盖 apt 在线、pip venv、离线 wheel、git 源码四种安装方案(全部逐条实测),以及 SSH 免密、sudo 免密配置、升级/降级/卸载与常见问题排障。本文全部命令与回显来自 2026-10-20 在 Ubuntu 22.04.5 LTS x86_64 实机上的真实执行记录。
一、环境信息
本章给出实测环境与拓扑,正文中所有命令、版本号、IP 均以此为准。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64),PRETTY_NAME 实测输出
Ubuntu 22.04.5 LTS - sshuttle 版本:apt 源 1.0.5-1ubuntu4;pip/git 方式 2.0.0(当前官方最新稳定版)
- 实测依赖版本:Python 3.10.12、OpenSSH_8.9p1(OpenSSL 3.0.2)、curl 7.81.0、sudo 1.9.9、git 2.34.1、iptables v1.8.7 (nf_tables)、nftables v1.0.2 (Lester Gooch)、sshpass 1.09-1
- 演示拓扑(三台真实服务器):
| 角色 | 主机名 | 地址 | 用途 |
|---|---|---|---|
| 办公端(本机装 sshuttle) | office-client | 10.89.58.2 | 运行 sshuttle 客户端,需要访问 10.89.59.0/24 |
| 跳板服务器 | jump-server | eth1 10.89.58.3(办公侧)/ eth0 10.89.59.2(内网侧) | sshuttle 的 SSH 远端,双网卡转发点 |
| 内网应用服务器 | app-server | 10.89.59.3:80 | 目标服务,提供 HTTP 演示页 |
- 安装位置约定:apt 方式落
/usr/bin/sshuttle;pip venv 方式落/opt/sshuttle-venv/bin/sshuttle;源码方式落/opt/sshuttle-venv2/bin/sshuttle;离线 wheel 方式落/opt/sshuttle-venv3/bin/sshuttle。
💡 说明:sshuttle 的角色划分(客户端要 sudo、远端零部署)决定了本文的验证闭环是「本机安装 → 配好到 jump-server 的 SSH 免密 → 起隧道访问 10.89.59.0/24」。工具定位与选型背景见 《sshuttle 2.0.0 介绍与选型指南》。
二、前置条件
安装与验证前需要满足以下条件,逐项确认:
- 一台可 SSH 登录的远端服务器:本文用 jump-server(10.89.58.3),sshd 已运行且账号可登录。
- 远端 Python 3.10+:2.0.0 要求远端有 Python 3.10 及以上。在 jump-server 上执行确认:
python3 --version
Python 3.10.12
- 客户端 root 或 sudo 权限:sshuttle 启动时要改写本机防火墙规则,非 root 运行会直接报错(报错原文见第十章 FAQ)。本文实验以 root 操作。
- 客户端基础软件:openssh-client、curl(验证用)。先刷新 apt 索引再装:
apt-get update
输出节选(实测尾部):
Fetched 5883 kB in 5s (1111 kB/s)
Reading package lists...
⚠️ 注意:如果公司网络走 apt 官方源较慢,把
/etc/apt/sources.list换成国内 apt 软件源(如 mirrors.aliyun.com/ubuntu、mirrors.tuna.tsinghua.edu.cn/ubuntu)后重新apt-get update。
三、版本选型说明
Ubuntu 22.04 用户有两条主流获取渠道:发行版 universe 仓库的 apt 包(1.0.5 系列)与 PyPI 的 pip 包(2.0.0 系列)。两条渠道交付的版本能力差异不小,先看对照再选:
| 维度 | apt(universe) | pip(PyPI) |
|---|---|---|
| 包版本 | 1.0.5-1ubuntu4 | 2.0.0(2026-09-28 发布的最新稳定版) |
| 1.x/2.x 能力差 | 2020-12-28 的老版本,无 --namespace、--remote-shell、--group,sudoers 选项还是老的 --sudoers(直接改写 sudoers 文件) | 新增 --namespace/--namespace-pid(网络命名空间内运行)、--remote-shell(远端 shell 可指定)、--group(按组生效)、--sudoers-no-modify(只打印 sudo 配置,不自动改文件);远端服务器 IP 自动排除,避免全网转发时 SSH 自断 |
| Python 要求 | 随发行版 | >=3.10,<4.0 |
| 升级方式 | 随 apt upgrade,节奏跟随 Ubuntu 发行版 | pip install -U sshuttle 随官方发版 |
| 隔离性 | 装进系统 Python(依赖 python3-psutil 等系统包) | venv 内隔离,不污染系统 |
关键差异解读:apt 版胜在「一条命令装完、随系统升级」,对偶发性使用足够;但 1.0.5 与 2.0.0 之间隔着近六年的功能演进(命名空间、UDP 之外的转发改进、sudoers 安全化等),正式使用推荐方案二的 pip venv 安装 2.0.0,apt 方式作为最简兜底。若所在服务器完全无外网,走方案三离线 wheel;需要跟踪上游开发版才用方案四源码。
四、方案一:apt 在线安装(1.0.5-1ubuntu4)
4.1 方案说明
从 Ubuntu 22.04 的 universe 仓库安装,一条命令完成,自动带上 Python 依赖(python3-psutil)。适合「能登录内网就行」的轻量使用。
4.2 安装步骤
apt-get install -y sshuttle
实测输出:
(Reading database ... 18059 files and directories currently installed.)
Preparing to unpack .../python3-psutil_5.9.0-1build1_amd64.deb ...
Unpacking python3-psutil (5.9.0-1build1) ...
Selecting previously unselected package sshuttle.
Preparing to unpack .../sshuttle_1.0.5-1ubuntu4_all.deb ...
Unpacking sshuttle (1.0.5-1ubuntu4) ...
Setting up python3-psutil (5.9.0-1build1) ...
Setting up sshuttle (1.0.5-1ubuntu4) ...
可安装版本以 apt 策略为准,随时可查:
apt policy sshuttle
sshuttle:
Installed: (none)
Candidate: 1.0.5-1ubuntu4
Version table:
1.0.5-1ubuntu4 500
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
4.3 验证
sshuttle --version
1.0.5
dpkg -l sshuttle | tail -1
ii sshuttle 1.0.5-1ubuntu4 all Transparent proxy server for VPN over SSH
ls -l /usr/bin/sshuttle
-rwxr-xr-x 1 root root 963 Mar 21 2022 /usr/bin/sshuttle
版本、包状态、落盘路径三项均已确认:apt 方式把可执行入口放在 /usr/bin/sshuttle,是一个 963 字节的发行版包装脚本。
4.4 要点提示
💡 说明:universe 仓库版本锁定在 1.0.5-1ubuntu4,修复与新特性跟随 Ubuntu 点版本更新;想用 2.0.0 的新能力请改用方案二,两者可在同一台机器共存(venv 与系统路径互不干扰)。
五、方案二:pip venv 安装(2.0.0,推荐)
5.1 方案说明
用 Python venv 把 sshuttle 2.0.0 装进独立目录 /opt/sshuttle-venv,与系统 Python 完全隔离,升级卸载都不碰系统环境。这是官方 installation 页推荐的 pip 方式的工程化落地。
5.2 安装 venv 支持
Ubuntu 22.04 默认不带 venv 模块,先补齐:
apt-get install -y python3-venv
输出节选(实测尾部):
0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.
(本机此前已装过,故无新装动作;未装过的机器会显示解包/设置 python3-venv 的过程行。)
5.3 创建 venv 并安装
python3 -m venv /opt/sshuttle-venv
/opt/sshuttle-venv/bin/pip install sshuttle
实测输出:
Downloading sshuttle-2.0.0-py3-none-any.whl (82 kB)
Installing collected packages: sshuttle
Successfully installed sshuttle-2.0.0
pip 自动解析并安装了 PyPI 上的最新稳定版 2.0.0(纯 Python wheel,82 kB,无编译依赖)。
5.4 验证
/opt/sshuttle-venv/bin/sshuttle --version
2.0.0
/opt/sshuttle-venv/bin/pip show sshuttle | grep -E '^(Name|Version|Location)'
Name: sshuttle
Version: 2.0.0
Location: /opt/sshuttle-venv/lib/python3.10/site-packages
5.5 加入全局 PATH(可选)
venv 内的二进制不在默认 PATH,做一个软链接让所有用户直接敲 sshuttle:
ln -sf /opt/sshuttle-venv/bin/sshuttle /usr/local/bin/sshuttle
sshuttle --version
2.0.0
5.6 systemd 托管(可选,需 systemd 真机)
⚠️ 注意:本节面向带 systemd 的 Linux 真机;无 systemd 的环境跳过本节,用
--daemon后台模式即可(守护模式参数详见本专栏后续发布的运行参数与路由规则详解文档)。
长期固定转发时把 sshuttle 注册成 systemd 服务。官方 requirements 页给出的托管形态是 Type=notify(2.0.0 起进程支持向 systemd 发送就绪通知)。新建 /etc/systemd/system/sshuttle.service:
[Unit]
Description=sshuttle transparent proxy over SSH
Wants=network-online.target
After=network-online.target
[Service]
Type=notify
ExecStart=/opt/sshuttle-venv/bin/sshuttle -r root@10.89.58.3 10.89.59.0/24
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
配置项说明:Type=notify 由 sshuttle 进程主动上报就绪状态,systemd 据此判定启动成功;Restart=on-failure 保证隧道异常退出后 5 秒拉起;ExecStart 使用 venv 内的绝对路径,避免 PATH 差异。启用并启动:
systemctl daemon-reload
systemctl enable --now sshuttle
⚠️ 注意:
systemctl enable --now等命令需在 systemd 真机上执行;systemctl is-active sshuttle返回active即托管成功。SSH 免密(第九章)是服务方式运行的前置——systemd 以 root 身份发起 SSH,免密配置必须对 root 生效。
六、方案三:离线 wheel 安装(无外网服务器)
6.1 方案说明
目标服务器完全无外网时,先在任意一台能访问 PyPI 的机器把 wheel 包下载下来,再拷贝到目标机用 pip 从本地文件安装。sshuttle 是纯 Python wheel,离线安装不需要任何编译工具链。
6.2 在联网机下载 wheel
pip download sshuttle -d /opt/wheel-dl
实测输出(已有 pip 缓存时显示 Using cached,首次为 Downloading,两者等价):
Using cached sshuttle-2.0.0-py3-none-any.whl (82 kB)
Saved ./opt/wheel-dl/sshuttle-2.0.0-py3-none-any.whl
Successfully downloaded sshuttle
确认产物:
ls -l /opt/wheel-dl/
total 84
-rw-r--r-- 1 root root 82563 Oct 20 16:49 sshuttle-2.0.0-py3-none-any.whl
💡 说明:
-d指定下载目录,pip 打印路径时保留相对形式(./opt/wheel-dl/sshuttle-2.0.0-py3-none-any.whl),实际落盘在绝对路径/opt/wheel-dl/。把sshuttle-2.0.0-py3-none-any.whl拷贝到离线机的同一路径(scp/rsync/U 盘均可)。
6.3 在离线机创建 venv 并从本地 wheel 安装
python3 -m venv /opt/sshuttle-venv3
/opt/sshuttle-venv3/bin/pip install /opt/wheel-dl/sshuttle-2.0.0-py3-none-any.whl
实测输出:
Processing /opt/wheel-dl/sshuttle-2.0.0-py3-none-any.whl
Installing collected packages: sshuttle
Successfully installed sshuttle-2.0.0
6.4 验证
/opt/sshuttle-venv3/bin/sshuttle --version
2.0.0
七、方案四:git 源码安装(跟踪开发版)
7.1 方案说明
从 GitHub 仓库克隆源码、检出发布 tag 后用 pip 从本地源码目录安装。适合需要阅读/修改源码或使用未发版提交的场景;生产环境请锁定 tag 安装。
7.2 克隆与检出
git clone https://github.com/sshuttle/sshuttle.git /opt/sshuttle-src
cd /opt/sshuttle-src
git checkout v2.0.0
实测输出(checkout 部分):
HEAD is now at a25c686 chore(master): release 2.0.0 (#1067)
确认检出的提交:
git log -1 --oneline
a25c686 chore(master): release 2.0.0 (#1067)
⚠️ 注意:GitHub 克隆在国内网络偶发失败,实测出现过
fatal: unable to access 'https://github.com/sshuttle/sshuttle.git/': GnuTLS recv error (-54): Error in the pull function.——重试即可恢复,持续失败时为 git 配置 HTTP 代理或改用浅克隆git clone --depth 1 --branch v2.0.0减少传输量。
7.3 安装
为源码安装单独建一个 venv(/opt/sshuttle-venv2),从本地目录安装:
python3 -m venv /opt/sshuttle-venv2
/opt/sshuttle-venv2/bin/pip install /opt/sshuttle-src
输出节选(实测尾部;venv 中已有旧安装时 pip 会先卸载再装):
Successfully uninstalled sshuttle-2.0.0
Successfully installed sshuttle-2.0.0
7.4 验证
/opt/sshuttle-venv2/bin/sshuttle --version
2.0.0
/opt/sshuttle-venv2/bin/pip show sshuttle
Name: sshuttle
Version: 2.0.0
Summary: Transparent proxy server that works as a poor man's VPN. Forwards over ssh. Doesn't require admin. Works with Linux and MacOS. Supports DNS tunneling.
Location: /opt/sshuttle-venv2/lib/python3.10/site-packages
💡 说明:源码方式跟随仓库 HEAD,
git pull后重新执行第 7.3 步的 pip install 即可更新;生产环境建议始终检出 v2.0.0 这类发布 tag。
八、方案对比与选择建议
四种方案都已在同型号 Ubuntu 22.04 实机走通,汇总对比:
| 方案 | 得到版本 | 外网要求 | 隔离性 | 适用场景 |
|---|---|---|---|---|
| apt 在线 | 1.0.5-1ubuntu4 | 需 Ubuntu 源 | 系统全局 | 最简安装,偶发使用 |
| pip venv | 2.0.0 | 需 PyPI | venv 独立目录 | 推荐:要新特性与官方最新修复 |
| 离线 wheel | 2.0.0 | 仅下载机需要 | venv 独立目录 | 无外网生产服务器 |
| git 源码 | 2.0.0(tag) | 需 GitHub | venv 独立目录 | 需要改码或跟踪开发版 |
选择建议:优先级为 pip venv > 离线 wheel > apt > git 源码。要 2.0.0 的自动排除远端 IP、命名空间等新能力,只有 pip/wheel/源码三条路;apt 1.0.5 仅在「装完即用、不追新版」时选。
九、SSH 免密与 sudo 配置(连接远端的前置)
装好本机只是第一步——sshuttle 每次启动都要通过 SSH 登录远端 jump-server。逐次输密码既麻烦也无法用于 systemd 托管,先把免密配好。
9.1 生成 SSH 密钥
ssh-keygen -t ed25519
一路回车使用默认路径与空口令,输出节选(实测尾部):
| . . +.= |
| . o..|
+----[SHA256]-----+
9.2 分发公钥到远端
把公钥写入 jump-server 的 root 账号(首次输入一次远端密码;远端密码不便交互时可用 sshpass,apt-get install -y sshpass 实测输出节选:sshpass is already the newest version (1.09-1).):
ssh-copy-id root@10.89.58.3
首次执行输出节选(实测尾部):
and check to make sure that only the key(s) you wanted were added.
重复执行是幂等的——密钥已存在时不会重复写入,实测全量输出:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
(if you think this is a mistake, you may want to use -f option)
9.3 验证免密登录
ssh root@10.89.58.3 hostname
jump-server
不再提示密码、直接返回主机名,免密链路打通。
9.4 sudo 免密配置(可选)
非 root 日常用户运行 sshuttle 时,sudo 每次要密码。2.0.0 提供只打印不落盘的生成器,输出经管理员审核后手工安装:
/opt/sshuttle-venv/bin/sshuttle --sudoers-no-modify
实测全量输出:
# WARNING: If you intend to restrict a user to only running the
# sshuttle command as root, THIS CONFIGURATION IS INSECURE.
# When a user can run sshuttle as root (with or without a password),
# they can also run other commands as root because sshuttle itself
# can run a command specified by the user with the --ssh-cmd option.
# INSTRUCTIONS: Add this text to your sudo configuration to run
# sshuttle without needing to enter a sudo password. To use this
# configuration, run 'visudo /etc/sudoers.d/sshuttle_auto' as root and
# paste this text into the editor that it opens. If you want to give
# multiple users these privileges, you may wish to use different
# filenames for each one (i.e., /etc/sudoers.d/sshuttle_auto_john).
# This configuration was initially generated by the
# 'sshuttle --sudoers-no-modify' command.
Cmnd_Alias SSHUTTLE03A = /usr/bin/env PYTHONPATH=/opt/sshuttle-venv/lib/python3.10/site-packages /opt/sshuttle-venv/bin/sshuttle *
root ALL=NOPASSWD: SSHUTTLE03A
⚠️ 注意:官方在输出开头就明示该配置不安全——能免密跑 sshuttle 的用户配合
--ssh-cmd可以变相以 root 执行任意命令。是否采纳请按你的安全基线决策;更保守的做法是保留密码式 sudo,或用--user限定转发规则只对特定用户生效(参数用法见本专栏参数详解篇)。
9.5 非 root 直接运行的报错实录
不提权直接运行时(root 减去 sudo 权限的受限账号,或脚本环境无终端),报错链路如下,实测原文:
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
fw: fatal: You must have root privileges (or enable su/sudo) to set the firewall
c : fatal: All attempts to run firewall client process with elevated privileges were failed.
看到这三行 fatal 即是权限问题而非网络问题,按 9.4 配置 sudo 免密或改用 root 运行即可。
十、常见问题
10.1 「sudo: a terminal is required to read the password」出现在脚本或托管场景
现象:交互式终端里 sudo 正常,放进 cron/systemd/CI 后报 sudo: a terminal is required to read the password。原因:非交互环境无法弹密码提示。解决:按 9.4 配置 NOPASSWD,或该场景直接以 root 运行。
10.2 启动时报 iptables 链不兼容
现象(实测原文):
iptables v1.8.7 (nf_tables): chain `sshuttle-12300' in table `nat' is incompatible, use 'nft' tool.
原因:系统里存在 nftables 创建的表/链与 iptables-nft 后端冲突(常见于此前用 --method nft 跑过、或系统安全软件建过 nft 规则后 sshuttle 切回 nat 方法)。解决:统一转发方法——显式指定 --method nat 或 --method nft 与现存规则体系保持一致;确有遗留表时用 nft list tables 排查、nft delete table inet <表名> 清理后再启动。
10.3 GitHub 克隆失败(GnuTLS recv error)
现象与原因见 7.2 节 ⚠️。解决按序尝试:重试一次(多为瞬时抖动)→ git clone --depth 1 --branch v2.0.0 浅克隆 → 为 git 配置可用的 HTTP 代理。
10.4 pip 安装到系统 Python 的权限问题
现象:不用 venv 直接 pip install sshuttle 时报权限错误或装进用户目录导致 PATH 混乱。解决:始终按方案二用 venv;root 下也建议 venv,避免与 apt 安装的 python3-psutil 等系统包混淆。
10.5 远端连上了但内网不通
排查顺序:① 确认远端 Python 3.10+(第二节第 2 项);② 确认转发子网写对(本文演示为 10.89.59.0/24,与 jump-server 内网侧 eth0 的 10.89.59.2/24 同段);③ 加 -v 看启动摘要中 Subnets to forward 列表是否包含目标网段;④ 仍不通时检查远端是否开启了转发所需的回程路由。启动摘要的逐项解读见本专栏参数详解篇。
十一、配置说明
sshuttle 没有常驻配置文件,「配置」由四部分组成,汇总便于日常维护:
- 命令行参数:所有行为(子网、转发方法、DNS、守护模式)都由启动参数决定,参数全集与真实默认值见本专栏参数详解篇。
- 子网文件(-s):子网列表可放文件交给
-s引用,避免命令行冗长。实测文件/opt/subnets.txt内容:
cat /opt/subnets.txt
10.89.59.0/24
- sudoers(可选):见 9.4 节,
--sudoers-no-modify生成的/etc/sudoers.d/sshuttle_auto。 - 入口软链接(可选):见 5.5 节,
/usr/local/bin/sshuttle -> /opt/sshuttle-venv/bin/sshuttle。
十二、升级、降级与卸载
12.1 升级(pip 方式)
/opt/sshuttle-venv/bin/pip install -U sshuttle
已是最新版时的实测输出:
Requirement already satisfied: sshuttle in ./opt/sshuttle-venv/lib/python3.10/site-packages (2.0.0)
官方发布新版后同一命令即完成升级;apt 方式升级跟随 apt upgrade。
12.2 降级(pip 方式)
锁定安装任意历史版本,实测降到 1.3.2:
/opt/sshuttle-venv3/bin/pip install sshuttle==1.3.2
Successfully installed sshuttle-1.3.2
/opt/sshuttle-venv3/bin/sshuttle --version
1.3.2
再升回 2.0.0:
/opt/sshuttle-venv3/bin/pip install sshuttle==2.0.0
Successfully installed sshuttle-2.0.0
/opt/sshuttle-venv3/bin/sshuttle --version
2.0.0
💡 说明:1.x 与 2.0.0 之间存在 Python 版本要求差异(1.3.x 接受 Python 3.9,2.0.0 要求 3.10+),降级前先确认目标版本对本机 Python 的约束。
12.3 卸载(pip 方式)
/opt/sshuttle-venv2/bin/pip uninstall -y sshuttle
Successfully uninstalled sshuttle-2.0.0
彻底清理时直接删除对应 venv 目录即可(本文各方案 venv 互相独立,删除不影响其他方案)。
12.4 卸载(apt 方式)
apt-get remove --purge -y sshuttle
输出节选(实测尾部):
(Reading database ... 18108 files and directories currently installed.)
Purging configuration files for sshuttle (1.0.5-1ubuntu4) ...
确认入口已移除:
ls -l /usr/bin/sshuttle
ls: cannot access '/usr/bin/sshuttle': No such file or directory
连带清理随装的依赖:
apt-get autoremove -y
输出节选(实测尾部):
Removing python3-psutil (5.9.0-1build1) ...
十三、参考链接
- 官方安装文档:https://sshuttle.readthedocs.io/en/stable/installation.html
- 官方环境要求(含 systemd Type=notify 托管形态):https://sshuttle.readthedocs.io/en/stable/requirements.html
- PyPI 项目页(版本与包体):https://pypi.org/project/sshuttle/
- GitHub 仓库(源码克隆):https://github.com/sshuttle/sshuttle
- 本专栏选型背景:《sshuttle 2.0.0 介绍与选型指南》