Skip to content

Latest commit

 

History

History
906 lines (655 loc) · 22.3 KB

File metadata and controls

906 lines (655 loc) · 22.3 KB

Local Proxy Setup for Unitree GO2 Orin Development

中文文档 | English

A beginner-friendly guide for configuring a local-computer proxy for the NVIDIA Jetson Orin expansion platform on Unitree GO2 EDU. This is useful when setting up ROS 2, SLAM, FAST-LIO, Nav2, Livox drivers, Python packages, Node.js packages, and other robotics development dependencies.


1. What problem does this solve?

When developing on the Orin expansion platform of Unitree GO2 EDU, you often need to run commands such as:

sudo apt update
sudo apt install ...
git clone ...
curl ...
wget ...
pip install ...
npm install ...
rosdep update

However, the Orin device may not be able to reliably access GitHub, ROS package sources, Python package repositories, Node.js package repositories, or other external resources.

Typical symptoms include:

  • git clone hangs or fails;
  • apt update is very slow or fails on some repositories;
  • rosdep update cannot download rule files from GitHub;
  • pip install or npm install fails while downloading dependencies;
  • curl or wget cannot access external URLs;
  • proxy variables work for normal commands but not for sudo apt.

This guide provides a practical solution:

Commands on Orin
apt / git / curl / pip / npm / rosdep
        ↓
Connect to the proxy port on your local computer
        ↓
Use your local computer's proxy client to access the Internet

In short, you do not need to run a proxy client on Orin. Instead, Orin reuses the proxy service already running on your local computer.


2. When should you use this guide?

This guide is suitable if:

  • you are using Unitree GO2 EDU with an Orin expansion platform;
  • your Orin and local computer are in the same LAN or GO2 network segment;
  • your local computer already runs a proxy client such as Clash, Mihomo, Clash Verge, V2RayN, Surge, or Quantumult X;
  • you want commands on Orin, such as apt, git, curl, pip, npm, and rosdep, to use your local computer's proxy;
  • you prefer a user-level setup instead of a complex system-wide proxy configuration on Orin.

This guide does not solve:

  • invalid proxy subscriptions or broken proxy nodes;
  • network disconnection between Orin and your local computer;
  • firewall rules blocking LAN access to your proxy port;
  • network policies in a company, school, or lab that block LAN proxy access;
  • SSH-style GitHub URLs such as git@github.com:xxx/yyy.git.

3. Example network environment

This guide uses the following example environment:

Device Example address / port Description
Local computer IP in the GO2 network 192.168.123.99 Orin connects to this address
Local proxy mixed port 10808 Common port for Clash / Mihomo
GO2 Orin IP 192.168.123.18 Commands are executed here
GO2 motion-control host IP 192.168.123.161 Usually unchanged
MID360 / MID360s IP 192.168.1.161 Should not go through proxy

If your local computer IP is not 192.168.123.99, replace this line in the script:

LOCAL_PROXY_HOST="192.168.123.99"

with your actual local-computer IP address.


4. Why not use 127.0.0.1:10808?

This is one of the most common beginner mistakes.

On Orin:

127.0.0.1

means Orin itself, not your Windows / macOS / Linux local computer.

If you configure the proxy as:

127.0.0.1:10808

Orin will try to connect to port 10808 on itself. In most cases, no proxy service is running on Orin, so the connection will fail.

The correct address should be your local computer's IP address in the GO2 network, for example:

192.168.123.99:10808

5. Step 1: Allow LAN access in your local proxy client

For Clash / Mihomo / Clash Verge, make sure your configuration includes something similar to:

mixed-port: 10808
allow-lan: true
bind-address: '*'

or:

mixed-port: 10808
allow-lan: true
bind-address: 0.0.0.0

Meaning:

Option Meaning
mixed-port: 10808 Proxy listens on port 10808; usually supports both HTTP and SOCKS
allow-lan: true Allows devices in the LAN to access the proxy
bind-address: 0.0.0.0 or '*' Listens on all network interfaces instead of localhost only

If the proxy only listens on 127.0.0.1, Orin cannot access it.

On your local computer, check the listening status:

ss -lntp | grep 10808

Expected output should contain something like:

0.0.0.0:10808

or:

192.168.123.99:10808

If you only see:

127.0.0.1:10808

then the proxy is only available to the local computer itself. Check allow-lan and bind-address again.

Windows users may not have the ss command. In that case, check the GUI settings of Clash Verge / Mihomo and make sure “Allow LAN” is enabled. Also check whether Windows Defender Firewall blocks port 10808.


6. Step 2: Test whether Orin can reach the local proxy port

Run this command on Orin:

timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL

If the output is:

OK

then Orin can reach the proxy port on your local computer.

If the output is:

FAIL

check the following:

  1. Is your local computer IP really 192.168.123.99?
  2. Is allow-lan enabled in the proxy client?
  3. Is the proxy listening on 0.0.0.0:10808 or 192.168.123.99:10808?
  4. Is the local firewall blocking port 10808?
  5. Are Orin and the local computer in the same network?
  6. Can Orin ping the local computer?
ping 192.168.123.99

If ping fails, the problem is not the proxy itself. The network connection must be fixed first.


7. Step 3: Create the proxy helper script on Orin

Run the following command on Orin to create ~/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 ----------
# Local computer IP in the GO2 network. Modify this if needed.
LOCAL_PROXY_HOST="192.168.123.99"

# Local proxy port. Common Clash / Mihomo / Clash Verge ports: 7890 or 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"

# A mixed port usually supports SOCKS as well. socks5h means DNS resolution is also handled by the proxy.
export all_proxy="socks5h://${LOCAL_PROXY_HOST}:${LOCAL_PROXY_PORT}"
export ALL_PROXY="$all_proxy"

# These addresses should not go through proxy, to avoid affecting robot internal communication,
# LiDAR communication, and LAN traffic.
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 may clear normal user's proxy environment variables by default.
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-style Git usually respects http_proxy / https_proxy.
# gitp uses temporary proxy settings and does not pollute global Git config.
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 usually respects environment variables. If not, configure conda proxy_servers manually.
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 ----------
# This affects network commands inside Dockerfile RUN steps. It does not affect 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 ----------
# If you want git / npm / pip to use proxy even without gitp / npmp / pipp, run proxy_persist_on.
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

8. Step 4: Enable the proxy

You must use source:

source ~/proxy_on.sh

Do not run:

./proxy_on.sh

Why?

  • ./proxy_on.sh runs the script in a child shell;
  • after the child shell exits, environment variables and functions disappear;
  • helper functions such as sapt, gitp, pipp, and npmp will not remain in your current terminal.

source ~/proxy_on.sh runs the script inside the current terminal, so the proxy environment stays active.


9. Step 5: Test the proxy

After enabling the proxy, run:

proxy_test

You can also test each part manually.

Test proxy port:

timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL

Test curl:

curlp -I https://github.com

Test Git:

gitp ls-remote https://github.com/Livox-SDK/livox_ros_driver2.git | head

Test apt:

sapt update

If these commands work, Orin is successfully using your local computer's proxy.


10. Command cheat sheet

Original command Recommended command Description
sudo apt update sapt update Run apt through proxy with sudo
sudo apt install -y xxx sapt install -y xxx Install system packages
git clone https://... gitp clone https://... Temporary Git proxy without global pollution
curl -I https://... curlp -I https://... Explicit HTTP proxy for curl
wget https://... wgetp https://... Explicit proxy for wget
pip install xxx pipp install xxx Python package installation
npm install npmp install Node.js package installation
yarn install yarnp install Yarn package installation
pnpm install pnpmp install pnpm package installation
rosdep update rosdepp update Update ROS dependency index
sudo rosdep install ... srosdep install ... rosdep install requiring sudo
docker build ... docker_build_proxy ... Proxy for commands inside Docker build

11. Disable the proxy

If you only want to stop using the proxy in the current SSH session, simply close the terminal.

If you want to clean the current terminal environment, create ~/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

# If proxy_persist_on was used, also remove persistent configs.
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

Disable proxy:

source ~/proxy_off.sh

12. Scope of this setup

12.1 Commands covered

In most cases, this setup covers:

  • curl
  • wget
  • HTTPS-style git, such as https://github.com/xxx/yyy.git
  • apt, through sapt
  • pip, through pipp
  • npm, through npmp
  • yarn, through yarnp
  • pnpm, through pnpmp
  • rosdep, through rosdepp or srosdep
  • docker build, through docker_build_proxy

12.2 Commands not fully covered

The following cases may not be fully handled by this script.

1. Git SSH URLs

Example:

git clone git@github.com:xxx/yyy.git

This uses SSH, not HTTPS. It usually does not read http_proxy.

Recommended alternative:

gitp clone https://github.com/xxx/yyy.git

2. Docker pull

Example:

docker pull ubuntu:22.04

docker pull is performed by the Docker daemon. It may not read proxy variables from your current terminal. The docker_build_proxy helper mainly solves network access during docker build.

If you need docker pull to use proxy, configure Docker daemon proxy separately.

3. GUI applications

GUI programs may not read environment variables from your SSH terminal.

4. Robot internal communication

GO2 motion control, Livox / MID360 LiDAR communication, ROS topics, and LAN traffic should not go through proxy. This is why no_proxy includes 192.168.123.0/24 and 192.168.1.0/24.


13. Troubleshooting

13.1 Proxy port test fails on Orin

Command:

timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL

Output:

FAIL

Check:

  1. Is the local computer IP correct?
  2. Is allow-lan enabled?
  3. Is the proxy listening on 0.0.0.0:10808?
  4. Is the local firewall blocking the port?
  5. Are Orin and the local computer in the same network?
  6. Can Orin ping the local computer?
ping 192.168.123.99

If ping fails, fix the network connection first.


13.2 sapt: command not found

Reason: the script was not enabled with source, or you opened a new terminal.

Run again:

source ~/proxy_on.sh

Do not use:

./proxy_on.sh

13.3 sudo apt update does not use proxy

This is expected. sudo may remove normal user environment variables.

Do not use:

sudo apt update

Use:

sapt update

For package installation:

sapt install -y git cmake build-essential

13.4 SSL certificate problem: certificate is not yet valid

A common cause is incorrect system time on Orin, especially after power loss.

Check time:

timedatectl

If the time is wrong, set it manually:

sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-ntp false
sudo date -s "2026-05-22 12:00:00"
sudo hwclock -w || true

Then test again:

source ~/proxy_on.sh
curlp -I https://github.com
sapt update

13.5 apt lock is held

Symptom:

Could not get lock /var/lib/apt/lists/lock

First check whether any apt / dpkg process is running:

ps aux | grep -E "apt|apt-get|dpkg" | grep -v grep

If a normal install or update process is running, wait for it to finish.

If no related process exists, carefully remove stale locks:

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

Then run:

sapt update

13.6 ROS 2 mirror returns 404

If installing ROS 2 packages returns 404 Not Found, it may not be a proxy problem. Some mirrors may have updated their apt index but not yet synchronized the actual .deb files.

Suggested workflow:

  1. Run:
sapt update
  1. If the issue remains, temporarily switch to the official ROS source.
  2. Use this proxy setup when accessing the official source is slow.

13.7 ROS official source GPG key expired

If you see something like:

EXPKEYSIG ... Open Robotics
The repository ... is not signed.

then the local ROS keyring may be outdated.

Download the key again:

sproxy curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  -o /usr/share/keyrings/ros-archive-keyring.gpg

Make sure the apt source uses signed-by:

cat /etc/apt/sources.list.d/ros2-official.list

Example:

deb [arch=arm64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu focal main

Then run:

sapt update

14. Minimal workflow

If you only want the fastest setup path, follow this sequence:

# 1. Enable allow-lan on your local computer's proxy client.
#    Make sure the proxy port is 10808.

# 2. On Orin, test whether the proxy port is reachable.
timeout 3 bash -c '</dev/tcp/192.168.123.99/10808' && echo OK || echo FAIL

# 3. Create and enable proxy_on.sh.
source ~/proxy_on.sh

# 4. Test the proxy.
proxy_test

# 5. Use 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

15. Security notes

  1. Do not expose your local proxy port to the public Internet.
  2. Enable allow-lan only in trusted LAN or lab environments.
  3. Disable LAN access in your proxy client after development if it is no longer needed.
  4. Do not enable LAN proxy access on untrusted public Wi-Fi.
  5. Never upload proxy subscriptions, tokens, private nodes, or credentials to GitHub.

16. License

This document is released under the MIT License unless otherwise specified.