Guide: Deploying Gitea with SSH on Pangolin + Newt
1. Architecture
- Client → connects to
git.example.comover HTTPS or SSH. - Pangolin VPS → public‑facing reverse proxy, terminates TLS, manages identity & access.
- Newt agent → runs inside your private infra (LXC/VM), establishes a WireGuard tunnel to Pangolin, and proxies traffic to local services.
- Gitea → runs locally (Docker or native) on the same host as Newt, reachable only via the tunnel.
Flow:
Client → Pangolin (public) → WireGuard tunnel (Newt) → Gitea (private)
2. Run Gitea Locally
Example docker-compose.yml on your private LXC/VM:
networks:
gitea:
external: false
services:
server:
image: docker.gitea.com/gitea:1.24.6
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
restart: unless-stopped
networks:
- gitea
volumes:
- /mnt/gitea/:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
3. Configure Gitea (app.ini)
[server]
DOMAIN = git.example.com
ROOT_URL = https://git.example.com/
SSH_DOMAIN = git.example.com
DISABLE_SSH = false
SSH_PORT = 2222
SSH_LISTEN_PORT = 22
4. Deploy Newt
Run Newt alongside Gitea. Example docker-compose.yml service:
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://pangolin.example.com
- NEWT_ID=<your-newt-id>
- NEWT_SECRET=<your-newt-secret>
- HEALTH_FILE=/tmp/healthy
NEWT_IDandNEWT_SECRETare generated in Pangolin when you register the Newt client.- Newt automatically sets up the WireGuard tunnel and proxies traffic to your local Gitea ports.
5. Configure Pangolin Resources
In Pangolin’s dashboard:
-
HTTP Resource
- Domain:
git.example.com - Target:
newt://gitea:3000(Newt proxies to local Gitea web UI)
- Domain:
-
TCP Resource
- External Port:
23(oryour liking) - Target:
newt://gitea:2222(Newt proxies to Gitea’s SSH)
- External Port:
Pangolin will handle TLS certificates (via Let’s Encrypt) and identity‑aware access control.
6. Client SSH Config
Add to ~/.ssh/config:
Host gitea
HostName git.example.com
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Test:
ssh -T gitea
Expected:
Hi <username>! You've successfully authenticated, but Gitea does not provide shell access.
7. Pitfalls & Fixes
| Pitfall | Symptom | Fix |
|---|---|---|
| Forgot to register Newt in Pangolin | No tunnel, resource unreachable | Generate NEWT_ID + NEWT_SECRET in Pangolin |
| Wrong SSH_PORT vs LISTEN_PORT | Connection works but auth fails | Keep LISTEN=22 inside, external port defined in Pangolin |
| UFW blocks WireGuard | Tunnel never comes up | Allow 51820/udp on VPS |
| Key not added in Gitea | Permission denied (publickey) |
Add .pub key in Gitea UI |
| Using port 23 | Some ISPs/firewalls block it | Prefer high port like 2222 |
8. Security Best Practices
- Keep VPS SSH separate from Gitea SSH.
- Restrict Pangolin access with CrowdSec or IP rules.
- Regularly update Gitea, Newt, and Pangolin.
- Use Pangolin’s identity features (SSO, RBAC) for fine‑grained access.
With this setup:
- Pangolin is the public gateway.
- Newt is the **tunnel **.
- Gitea stays private, only reachable through the newt tunnel.