中文 | English
适用于在宇树 Unitree GO2 EDU / Jetson Orin 拓展坞上进行 ROS、SLAM、FAST-LIO、Nav2、Livox 驱动等开发时,需要让 Orin 通过本地电脑代理访问 GitHub、ROS 源、pip、npm、apt 等网络资源的场景。
在 GO2 EDU 的 Orin 平台上做机器人开发时,经常需要执行:
sudo apt update
sudo apt install ...
git clone ...
curl ...
wget ...
pip install ...
npm install ...
rosdep update但实际开发中,Orin 可能无法稳定访问 GitHub、ROS 官方源、Python 包源、Node 包源,导致以下问题:
git clone卡住或连接失败;apt update速度很慢或部分源访问失败;rosdep update无法拉取 GitHub 上的规则文件;pip install、npm install下载依赖失败;curl、wget无法访问外部资源;- 使用
sudo apt时,普通用户设置的代理不生效。
本方案的核心思路是:
Orin 上的 apt / git / curl / pip / npm / rosdep
↓
访问本地电脑在 GO2 网段中的 IP:代理端口
↓
通过本地电脑上的 Clash / Mihomo / Clash Verge 等代理软件访问网络
也就是说,Orin 自己不直接运行代理软件,而是复用本地电脑已经开启的代理端口。
本指南适用于以下情况:
- 你正在使用 Unitree GO2 EDU,并通过 Orin 拓展坞进行二次开发;
- Orin 和你的本地电脑处于同一局域网或同一 GO2 网段;
- 本地电脑已经安装 Clash、Mihomo、Clash Verge、V2RayN、Surge、Quantumult X 等代理客户端;
- 你希望 Orin 上的
apt、git、curl、pip、npm、rosdep等命令走本地电脑代理; - 你不想在 Orin 上配置复杂的系统全局代理。
本指南不解决以下问题:
- 代理订阅、节点、规则本身不可用;
- Orin 与本地电脑网络不通;
- 本地电脑防火墙阻止局域网设备访问代理端口;
- 公司、学校或实验室网络策略限制局域网代理访问;
- SSH 协议形式的
git@github.com:xxx/yyy.git代理问题。
本文以如下网络环境为例:
| 设备 | 示例地址 / 端口 | 说明 |
|---|---|---|
| 本地电脑在 GO2 网段中的 IP | 192.168.123.99 |
Orin 要访问这个 IP |
| 本地代理 mixed-port | 10808 |
Clash / Mihomo 常见端口 |
| GO2 Orin IP | 192.168.123.18 |
在 Orin 上执行命令 |
| GO2 运动控制主机 IP | 192.168.123.161 |
通常不用改 |
| MID360 / MID360s IP | 192.168.1.161 |
不应走代理 |
如果你的本地电脑 IP 不是 192.168.123.99,请把后文脚本中的:
LOCAL_PROXY_HOST="192.168.123.99"改成你自己的电脑 IP。
这是新手最容易犯的错误。
在 Orin 上:
127.0.0.1表示 Orin 自己,不是你的 Windows / macOS / Linux 本地电脑。
如果你把代理地址写成:
127.0.0.1:10808Orin 会去找自己机器上的 10808 端口。但通常 Orin 上并没有运行 Clash / Mihomo,所以会连接失败。
正确做法是写 本地电脑在 GO2 网段中的 IP,例如:
192.168.123.99:10808以 Clash / Mihomo / Clash Verge 为例,需要确保配置中包含类似内容:
mixed-port: 10808
allow-lan: true
bind-address: '*'或:
mixed-port: 10808
allow-lan: true
bind-address: 0.0.0.0含义如下:
| 配置 | 含义 |
|---|---|
mixed-port: 10808 |
代理端口为 10808,一般同时支持 HTTP 和 SOCKS |
allow-lan: true |
允许局域网设备访问代理 |
bind-address: 0.0.0.0 或 '*' |
监听所有网卡,而不是只监听本机 |
如果代理只监听 127.0.0.1,Orin 是访问不到的。
在本地电脑上检查监听状态:
ss -lntp | grep 10808希望看到类似:
0.0.0.0:10808
或者:
192.168.123.99:10808
如果只看到:
127.0.0.1:10808
说明当前代理只允许本机访问,需要重新检查 allow-lan 和 bind-address。
Windows 用户如果没有
ss命令,可以在 Clash Verge / Mihomo 的界面中确认是否开启了“允许局域网连接”。同时注意 Windows Defender 防火墙是否拦截了10808端口。
在 Orin 终端中执行:
timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL如果输出:
OK
说明 Orin 可以访问本地电脑的代理端口。
如果输出:
FAIL
优先检查:
- 本地电脑 IP 是否真的为
192.168.123.99; - 本地代理是否开启
allow-lan; - 本地代理是否监听
0.0.0.0:10808或192.168.123.99:10808; - Windows / Linux / macOS 防火墙是否阻止
10808; - Orin 和本地电脑是否在同一个网络中;
- 本地电脑是否能被 Orin ping 到:
ping 192.168.123.99在 Orin 上执行下面命令,创建 ~/proxy_on.sh:
cat > ~/proxy_on.sh <<'EOF'
#!/usr/bin/env bash
# ============================================================
# Unitree GO2 / Jetson Orin user-level proxy helper
#
# Usage:
# source ~/proxy_on.sh
#
# Do not run directly:
# ./proxy_on.sh
#
# Environment variables and shell functions only remain in the
# current terminal when this file is sourced.
# ============================================================
# ---------- Basic settings ----------
# 本地电脑在 GO2 网段中的 IP,请按实际情况修改
LOCAL_PROXY_HOST="192.168.123.99"
# 本地代理端口,Clash / Mihomo / Clash Verge 常见为 7890 或 10808
LOCAL_PROXY_PORT="10808"
export http_proxy="http://${LOCAL_PROXY_HOST}:${LOCAL_PROXY_PORT}"
export https_proxy="http://${LOCAL_PROXY_HOST}:${LOCAL_PROXY_PORT}"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
# mixed-port 通常也支持 SOCKS。socks5h 表示 DNS 解析也交给代理端处理。
export all_proxy="socks5h://${LOCAL_PROXY_HOST}:${LOCAL_PROXY_PORT}"
export ALL_PROXY="$all_proxy"
# 这些地址不走代理,避免影响机器人内部通信、雷达通信、局域网通信。
export no_proxy="localhost,127.0.0.1,::1,*.local,192.168.123.0/24,192.168.1.0/24,10.0.0.0/8,172.16.0.0/12"
export NO_PROXY="$no_proxy"
# ---------- Generic sudo wrapper ----------
# sudo 默认可能清空普通用户的代理环境变量,所以需要这个包装函数。
sproxy() {
sudo env \
http_proxy="$http_proxy" \
https_proxy="$https_proxy" \
HTTP_PROXY="$HTTP_PROXY" \
HTTPS_PROXY="$HTTPS_PROXY" \
all_proxy="$all_proxy" \
ALL_PROXY="$ALL_PROXY" \
no_proxy="$no_proxy" \
NO_PROXY="$NO_PROXY" \
"$@"
}
# ---------- apt / apt-get ----------
sapt() {
sproxy apt "$@"
}
saptget() {
sproxy apt-get "$@"
}
# ---------- git ----------
# 普通 https:// 开头的 git clone 通常会读取 http_proxy / https_proxy。
# gitp 使用 -c 临时指定代理,不污染全局 git 配置。
gitp() {
git \
-c http.proxy="$http_proxy" \
-c https.proxy="$https_proxy" \
"$@"
}
# ---------- curl / wget ----------
curlp() {
curl -x "$http_proxy" "$@"
}
wgetp() {
wget \
-e "use_proxy=yes" \
-e "http_proxy=$http_proxy" \
-e "https_proxy=$https_proxy" \
"$@"
}
# ---------- Python / pip ----------
pipp() {
python3 -m pip --proxy "$http_proxy" "$@"
}
# ---------- npm / yarn / pnpm ----------
npmp() {
npm \
--proxy="$http_proxy" \
--https-proxy="$https_proxy" \
"$@"
}
yarnp() {
yarn \
--proxy "$http_proxy" \
--https-proxy "$https_proxy" \
"$@"
}
pnpmp() {
pnpm \
--config.proxy="$http_proxy" \
--config.https-proxy="$https_proxy" \
"$@"
}
# ---------- conda ----------
# conda 大多数情况下会读取环境变量;如果不生效,可手动配置 conda proxy_servers。
condap() {
env \
http_proxy="$http_proxy" \
https_proxy="$https_proxy" \
HTTP_PROXY="$HTTP_PROXY" \
HTTPS_PROXY="$HTTPS_PROXY" \
conda "$@"
}
# ---------- rosdep ----------
rosdepp() {
env \
http_proxy="$http_proxy" \
https_proxy="$https_proxy" \
HTTP_PROXY="$HTTP_PROXY" \
HTTPS_PROXY="$HTTPS_PROXY" \
all_proxy="$all_proxy" \
ALL_PROXY="$ALL_PROXY" \
no_proxy="$no_proxy" \
NO_PROXY="$NO_PROXY" \
rosdep "$@"
}
srosdep() {
sproxy rosdep "$@"
}
# ---------- Docker build ----------
# 只影响 docker build 过程中的 RUN apt/pip/npm 等命令,不影响 docker pull。
docker_build_proxy() {
docker build \
--build-arg HTTP_PROXY="$HTTP_PROXY" \
--build-arg HTTPS_PROXY="$HTTPS_PROXY" \
--build-arg http_proxy="$http_proxy" \
--build-arg https_proxy="$https_proxy" \
--build-arg ALL_PROXY="$ALL_PROXY" \
--build-arg all_proxy="$all_proxy" \
--build-arg NO_PROXY="$NO_PROXY" \
--build-arg no_proxy="$no_proxy" \
"$@"
}
# ---------- Optional persistent configs ----------
# 如需让 git / npm / pip 在不使用 gitp / npmp / pipp 的情况下也走代理,可以执行:
proxy_persist_on() {
git config --global http.proxy "$http_proxy"
git config --global https.proxy "$https_proxy"
if command -v npm >/dev/null 2>&1; then
npm config set proxy "$http_proxy"
npm config set https-proxy "$https_proxy"
fi
if command -v pip3 >/dev/null 2>&1; then
pip3 config set global.proxy "$http_proxy" >/dev/null 2>&1 || true
fi
if command -v conda >/dev/null 2>&1; then
conda config --set proxy_servers.http "$http_proxy" >/dev/null 2>&1 || true
conda config --set proxy_servers.https "$https_proxy" >/dev/null 2>&1 || true
fi
echo "Persistent proxy config enabled for supported tools."
}
proxy_persist_off() {
git config --global --unset http.proxy 2>/dev/null || true
git config --global --unset https.proxy 2>/dev/null || true
if command -v npm >/dev/null 2>&1; then
npm config delete proxy >/dev/null 2>&1 || true
npm config delete https-proxy >/dev/null 2>&1 || true
fi
if command -v pip3 >/dev/null 2>&1; then
pip3 config unset global.proxy >/dev/null 2>&1 || true
fi
if command -v conda >/dev/null 2>&1; then
conda config --remove-key proxy_servers >/dev/null 2>&1 || true
fi
echo "Persistent proxy config removed for supported tools."
}
# ---------- Test ----------
proxy_test() {
echo "[1/4] Test proxy port: ${LOCAL_PROXY_HOST}:${LOCAL_PROXY_PORT}"
timeout 3 bash -c "</dev/tcp/${LOCAL_PROXY_HOST}/${LOCAL_PROXY_PORT}" && echo " OK: proxy port is reachable" || echo " FAIL: proxy port is not reachable"
echo
echo "[2/4] Test curl to GitHub"
curl -I --connect-timeout 10 https://github.com 2>/dev/null | head -n 5 || true
echo
echo "[3/4] Test git ls-remote"
gitp ls-remote https://github.com/Livox-SDK/livox_ros_driver2.git 2>/dev/null | head -n 3 || true
echo
echo "[4/4] Current proxy environment"
env | grep -i proxy || true
}
# ---------- Summary ----------
echo "Proxy enabled in current shell."
echo
echo "Proxy address:"
echo " http_proxy=$http_proxy"
echo " https_proxy=$https_proxy"
echo " all_proxy=$all_proxy"
echo
echo "Common commands:"
echo " sapt update"
echo " sapt install -y <package>"
echo " gitp clone https://github.com/xxx/yyy.git"
echo " curlp -I https://github.com"
echo " wgetp <url>"
echo " pipp install <package>"
echo " npmp install"
echo " rosdepp update"
echo " docker_build_proxy -t image_name ."
echo " proxy_test"
echo
echo "Important: use 'source ~/proxy_on.sh', not './proxy_on.sh'."
EOF
chmod +x ~/proxy_on.sh必须使用 source:
source ~/proxy_on.sh不要这样执行:
./proxy_on.sh原因是:
./proxy_on.sh会在子 shell 中运行;- 子 shell 结束后,环境变量和函数都会消失;
sapt、gitp、pipp、npmp等函数不会保留在当前终端中。
而 source ~/proxy_on.sh 会在当前终端中执行脚本,所以代理配置会在当前终端中生效。
启用代理后执行:
proxy_test也可以分开测试。
测试代理端口:
timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL测试 curl:
curlp -I https://github.com测试 git:
gitp ls-remote https://github.com/Livox-SDK/livox_ros_driver2.git | head测试 apt:
sapt update如果这些命令正常,说明 Orin 已经可以通过本地电脑代理访问外部网络。
| 原始命令 | 建议命令 | 说明 |
|---|---|---|
sudo apt update |
sapt update |
让 sudo apt 也继承代理 |
sudo apt install -y xxx |
sapt install -y xxx |
安装系统依赖 |
git clone https://... |
gitp clone https://... |
临时代理,不污染 git 全局配置 |
curl -I https://... |
curlp -I https://... |
显式指定 HTTP 代理 |
wget https://... |
wgetp https://... |
显式指定 HTTP / HTTPS 代理 |
pip install xxx |
pipp install xxx |
Python 包安装 |
npm install |
npmp install |
Node 包安装 |
yarn install |
yarnp install |
Yarn 包安装 |
pnpm install |
pnpmp install |
pnpm 包安装 |
rosdep update |
rosdepp update |
ROS 依赖索引更新 |
sudo rosdep install ... |
srosdep install ... |
需要 sudo 的 rosdep 安装 |
docker build ... |
docker_build_proxy ... |
让 Dockerfile 里的下载命令走代理 |
如果只是关闭当前终端,直接退出 SSH 或关闭终端即可。
如果想在当前终端中清理代理环境变量,可以创建 ~/proxy_off.sh:
cat > ~/proxy_off.sh <<'EOF'
#!/usr/bin/env bash
# Disable current-shell proxy environment and helper functions.
unset http_proxy
unset https_proxy
unset HTTP_PROXY
unset HTTPS_PROXY
unset all_proxy
unset ALL_PROXY
unset no_proxy
unset NO_PROXY
unset -f sproxy 2>/dev/null || true
unset -f sapt 2>/dev/null || true
unset -f saptget 2>/dev/null || true
unset -f gitp 2>/dev/null || true
unset -f curlp 2>/dev/null || true
unset -f wgetp 2>/dev/null || true
unset -f pipp 2>/dev/null || true
unset -f npmp 2>/dev/null || true
unset -f yarnp 2>/dev/null || true
unset -f pnpmp 2>/dev/null || true
unset -f condap 2>/dev/null || true
unset -f rosdepp 2>/dev/null || true
unset -f srosdep 2>/dev/null || true
unset -f docker_build_proxy 2>/dev/null || true
unset -f proxy_test 2>/dev/null || true
unset -f proxy_persist_on 2>/dev/null || true
unset -f proxy_persist_off 2>/dev/null || true
# 如果你执行过 proxy_persist_on,但当前函数已经不存在,可以手动执行下面几行:
git config --global --unset http.proxy 2>/dev/null || true
git config --global --unset https.proxy 2>/dev/null || true
if command -v npm >/dev/null 2>&1; then
npm config delete proxy >/dev/null 2>&1 || true
npm config delete https-proxy >/dev/null 2>&1 || true
fi
if command -v pip3 >/dev/null 2>&1; then
pip3 config unset global.proxy >/dev/null 2>&1 || true
fi
if command -v conda >/dev/null 2>&1; then
conda config --remove-key proxy_servers >/dev/null 2>&1 || true
fi
echo "Proxy disabled in current shell."
EOF
chmod +x ~/proxy_off.sh关闭代理:
source ~/proxy_off.sh在大多数情况下,启用脚本后,以下命令可以通过代理访问网络:
curlwgetgit的 HTTPS 方式,例如https://github.com/xxx/yyy.gitapt,通过sapt使用pip,通过pipp使用npm,通过npmp使用yarn,通过yarnp使用pnpm,通过pnpmp使用rosdep,通过rosdepp或srosdep使用docker build,通过docker_build_proxy使用
以下场景不一定会被本脚本完全覆盖:
- Git SSH 地址
例如:
git clone git@github.com:xxx/yyy.git这种走的是 SSH 协议,不是 HTTPS 协议,通常不读取 http_proxy。建议改用:
gitp clone https://github.com/xxx/yyy.git- Docker pull
docker pull ubuntu:22.04docker pull 由 Docker daemon 执行,不一定读取当前终端的代理环境变量。本文的 docker_build_proxy 主要解决 docker build 中的下载问题。如果你需要让 docker pull 也走代理,需要单独配置 Docker daemon 代理。
- GUI 程序
图形界面程序不一定读取当前 SSH 终端中的环境变量。
- 机器人内部通信
GO2 运动控制、Livox / MID360 雷达、ROS topic、局域网通信不应该走代理。因此脚本中设置了 no_proxy,避免影响 192.168.123.0/24、192.168.1.0/24 等内网地址。
现象:
timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL输出:
FAIL
处理:
- 检查本地电脑 IP 是否写错;
- 检查 Clash / Mihomo 是否开启
allow-lan; - 检查代理是否监听
0.0.0.0:10808; - 检查本地电脑防火墙;
- 检查 Orin 和本地电脑是否在同一网络;
- 在 Orin 上执行:
ping 192.168.123.99如果 ping 不通,说明不是代理问题,而是网络本身不通。
原因:没有用 source 启用脚本,或者换了一个新终端。
重新执行:
source ~/proxy_on.sh注意不要使用:
./proxy_on.sh这是正常现象。sudo 默认可能会清理普通用户的环境变量。
不要直接用:
sudo apt update改用:
sapt update安装包时也用:
sapt install -y git cmake build-essential常见原因是 Orin 系统时间错误,尤其是嵌入式设备断电后时间异常。
先查看时间:
timedatectl如果时间明显错误,可以手动设置:
sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-ntp false
sudo date -s "2026-05-22 12:00:00"
sudo hwclock -w || true然后重新测试:
source ~/proxy_on.sh
curlp -I https://github.com
sapt update现象:
Could not get lock /var/lib/apt/lists/lock
先查看是否有 apt / dpkg 进程正在运行:
ps aux | grep -E "apt|apt-get|dpkg" | grep -v grep如果确实有安装或更新进程,建议等待。
如果确认没有相关进程,再谨慎删除残留锁:
sudo rm -f /var/lib/apt/lists/lock
sudo rm -f /var/cache/apt/archives/lock
sudo rm -f /var/lib/dpkg/lock
sudo rm -f /var/lib/dpkg/lock-frontend
sudo dpkg --configure -a然后重新执行:
sapt update如果安装 ROS2 包时出现 404 Not Found,可能不是代理问题,而是镜像源同步不完整。例如某些镜像站的 apt 索引已经更新,但实际 .deb 文件还没同步完成。
处理思路:
- 先执行:
sapt update- 如果仍然 404,考虑临时切换到 ROS 官方源;
- 如果官方源访问慢,再配合本文代理方案使用。
如果出现类似:
EXPKEYSIG ... Open Robotics
The repository ... is not signed.
说明 ROS 源的 keyring 可能过期或本机配置过旧。
可以重新下载 key:
sproxy curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
-o /usr/share/keyrings/ros-archive-keyring.gpg然后确认 apt 源使用了 signed-by:
cat /etc/apt/sources.list.d/ros2-official.list示例:
deb [arch=arm64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu focal main
最后执行:
sapt update如果你只想快速配置并验证,可以按这个顺序执行:
# 1. 本地电脑开启 allow-lan,并确认代理端口为 10808
# 2. Orin 上测试能否连到本地代理端口
timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL
# 3. 创建并启用脚本
source ~/proxy_on.sh
# 4. 测试代理
proxy_test
# 5. 使用 apt / git / pip / npm / rosdep
sapt update
gitp clone https://github.com/Livox-SDK/livox_ros_driver2.git
pipp install numpy
npmp install
rosdepp update- 不要把本地代理端口暴露到公网。
- 只建议在可信局域网或实验室网络中开启
allow-lan。 - 如果开发完成,建议关闭代理客户端的局域网访问功能。
- 如果你使用的是公共 Wi-Fi,不建议开启局域网代理访问。
- 不要把包含个人代理订阅、token、节点信息的配置文件上传到 GitHub。
This document is released under the MIT License unless otherwise specified.