I had a Jetson Nano lying around doing nothing and wanted to use it as a self-hosted OpenClaw gateway. OpenClaw gets broad system access — filesystem, shell, network, credentials — and there’s been a steady stream of security issues, including a one-click RCE vulnerability (CVE-2026-25253) and hundreds of exposed instances found via Shodan with no authentication. A dedicated device keeps the blast radius away from anything I actually care about.

System specs Link to heading

  • Board: NVIDIA Jetson Nano (4GB)
  • CPU: Quad-core ARM Cortex-A57 (ARMv8)
  • RAM: 4GB LPDDR4
  • Storage: 128GB eMMC
  • OS: Ubuntu 18.04.6 LTS (JetPack R32.1.0)
  • Kernel: 4.9.140-tegra
  • Connection: SSH over local network, HDMI to external projector

The Nano runs Ubuntu 18.04 with a 4.9 kernel — NVIDIA’s last supported JetPack for this hardware. That means ancient system packages, including Node.js v8.10, and OpenClaw requires Node 22+. Here’s how I got it working with Bun instead, and what to expect when running modern software on end-of-life hardware.

The problem Link to heading

OpenClaw’s standard installer assumes a modern Node.js:

curl -fsSL https://openclaw.ai/install.sh | bash

This fails on the Jetson Nano because:

  • The system Node is v8.10 (Ubuntu 18.04 repos)
  • NodeSource doesn’t publish Node 22 binaries for the Nano’s aarch64/L4T combo
  • nvm-installed Node 22 also doesn’t work on the old glibc

Install with Bun Link to heading

Bun ships its own runtime and works on aarch64. Install it:

curl -fsSL https://bun.sh/install | bash
export PATH=$HOME/.bun/bin:$PATH

Then install OpenClaw globally:

bun install -g openclaw@latest

Fix the shebang Link to heading

The openclaw binary has #!/usr/bin/env node as its shebang, so it’ll try to run with the ancient system Node. Fix it:

sed -i '1s|#!/usr/bin/env node|#!/usr/bin/env bun|' \
  ~/.bun/install/global/node_modules/openclaw/openclaw.mjs

Now openclaw runs with Bun. Complete the onboarding:

openclaw

Fix the gateway service Link to heading

After onboarding, OpenClaw creates a systemd user service for the gateway. But it hardcodes /usr/bin/node in the service file, so the gateway crashes immediately.

Check:

systemctl --user status openclaw-gateway.service

If it’s in a restart loop, fix the service file:

sed -i 's|"/usr/bin/node"|/home/YOUR_USER/.bun/bin/bun|' \
  ~/.config/systemd/user/openclaw-gateway.service

systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service

Verify it’s running:

systemctl --user status openclaw-gateway.service

You should see active (running) with Bun as the process.

Connecting Telegram Link to heading

Create a bot via @BotFather and paste the token into the config. Watch out for truncated tokens — BotFather tokens are typically 46 characters. If the token gets clipped during the onboarding wizard, the gateway logs will show:

[telegram] setMyCommands failed: Call to 'setMyCommands' failed! (401: Unauthorized)
[telegram] [default] channel exited: Call to 'getMe' failed! (401: Unauthorized)

Fix by patching the config with the full token:

openclaw config set channels.telegram.botToken "YOUR_FULL_BOT_TOKEN"

On first DM to the bot, you’ll get a pairing prompt with your Telegram user ID. Approve access by adding your ID to the allowlist:

{
  "channels": {
    "telegram": {
      "dmPolicy": "allowlist",
      "allowFrom": [YOUR_TELEGRAM_USER_ID]
    }
  }
}

GitHub SSH access Link to heading

If your Jetson has stale GitHub SSH host keys (they rotated in 2023), update them:

ssh-keygen -f ~/.ssh/known_hosts -R github.com

Then add the current keys from GitHub’s docs:

cat >> ~/.ssh/known_hosts << 'EOF'
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
EOF

Generate a dedicated key for the Jetson:

ssh-keygen -t ed25519 -C "$(whoami)@jetson-nano" -f ~/.ssh/id_ed25519_jetson -N ""

cat >> ~/.ssh/config << 'EOF'

Host github.com
  IdentityFile ~/.ssh/id_ed25519_jetson
  IdentitiesOnly yes
EOF

Add the public key at github.com/settings/ssh/new, then install the gh CLI:

wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \
  | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] \
  https://cli.github.com/packages stable main" \
  | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null

sudo apt-get update && sudo apt-get install gh -y
gh auth login --git-protocol ssh --hostname github.com --skip-ssh-key

Installing Claude Code Link to heading

Anthropic acquired Bun in December 2025, so Claude Code runs under Bun:

bun install -g @anthropic-ai/claude-code

The claude binary defaults to node in its shebang, so alias it:

echo 'alias claude="bun run $(which claude)"' >> ~/.bashrc

Caveats Link to heading

  • Use Telegram over WhatsApp: Telegram lets you create a dedicated bot account via @BotFather, so your AI assistant gets its own identity. WhatsApp doesn’t have this — you’d have to use your personal number, which gets messy.
  • Gateway restarts on config changes: When you pair a new device or change settings, OpenClaw restarts the gateway. This is normal — it comes back up in a few seconds.
  • Bun isn’t officially recommended for the gateway: The OpenClaw docs note that Bun is “not recommended for Gateway runtime” due to potential WhatsApp/Telegram bugs. In practice it worked fine for Telegram on my setup.
  • Updates may overwrite your fixes: Running openclaw update or bun install -g openclaw@latest will likely reset the shebang and service file. You’ll need to re-apply both fixes after updating.

The old OS tax Link to heading

The Jetson Nano is stuck on Ubuntu 18.04 because NVIDIA stopped updating JetPack for it after 4.6.x. You can’t just do-release-upgrade — the kernel, GPU drivers, and CUDA stack are all tightly coupled to the L4T (Linux for Tegra) base. This means:

  • Node 22 won’t install — NodeSource binaries need glibc 2.28+, but 18.04 ships 2.27. nvm-built Node hits the same wall. The unofficial Node builds provide old-glibc variants for x64, but not for aarch64 — so there’s no pre-built path to modern Node on the Jetson Nano. You could build from source (expect hours of compile time) or run Node inside a Docker container with a newer base image, but Bun is the pragmatic choice.
  • Python is stuck at 3.6 — the system Python is ancient. You can build newer versions from source, but some wheels won’t have pre-built aarch64 binaries.
  • No persistent journal by default — systemd on 18.04 doesn’t create /var/log/journal, so boot logs vanish on reboot. You need to mkdir -p /var/log/journal yourself.
  • Docker works, but is old — the bundled Docker is from the NVIDIA container runtime and may not support newer image features.
  • Community OS images exist but you’ll likely lose CUDA/GPU support, which defeats the purpose of having a Jetson.

The workaround pattern is always the same: find a runtime that bundles its own dependencies (Bun, Go binaries, Rust binaries, static builds) rather than relying on system libraries. Anything that needs a modern glibc or libc++ will fail.

Enable ESM for security patches Link to heading

Even though you’re stuck on 18.04, you should still apply security updates. Ubuntu’s standard support for 18.04 ended in April 2023, but Extended Security Maintenance (ESM) provides critical patches until 2028. It’s free for up to 5 machines:

sudo pro attach YOUR_TOKEN
sudo apt update && sudo apt upgrade -y

Get a token at ubuntu.com/pro. My Jetson had 366 packages to upgrade after enabling ESM — that’s a lot of unpatched vulnerabilities on a device running an AI agent with shell access.

If you’re buying new hardware for this kind of thing, the Jetson Orin Nano is the successor and runs a much newer Ubuntu base. The original Nano is effectively end-of-life but still perfectly usable if you’re willing to work around the old OS.

Further reading Link to heading