This repository contains systemd unit files and configuration examples to run a ptunnel-based SSH reverse tunnel setup.
All sensitive values (IPs, ports, usernames) are stored in an environment file; a sanitized template (ptunnel.env.example) is included so the repo is safe to publish on GitHub.
Ptunnel (implemented by the upstream ptunnel-ng) is a TCP tunneling tool that lets clients behind NAT or restrictive firewalls create an outbound control channel to a public server. Over that channel the client and server can negotiate port forwarding so services on the private machine become reachable via a port bound on the server.
Why use it:
- Expose an SSH or HTTP service running on a machine behind NAT without opening inbound firewall ports.
- Provide a persistent channel for port forwarding across unreliable networks.
How it works (overview):
- The client establishes an outbound connection to the server (control channel).
- The server accepts connections on a bound port and forwards traffic over the control channel to the client.
- The client receives forwarded traffic and connects to a local service (e.g.,
localhost:22for SSH), making the service available via the server's bound port.
Security notes:
- Protect server endpoints with firewall rules and SSH keys.
- Store secrets in files with strict permissions (e.g.,
/etc/ptunnel.envwith mode600).
- Upstream ptunnel-ng (source & build): https://github.com/utoni/ptunnel-ng/
client/— systemd unit files intended to be deployed on client machines (machines that initiate the tunnel)server/— systemd unit files intended to be deployed on the server (machine that receives the tunnel)ptunnel.env.example— sanitized template; fill values and copy to/etc/ptunnel.envptunnel.env— (local) your current configuration — ignored by git.gitignore— prevents local env files from being committed
- On client machines: copy the files from the
client/directory (ptnl.service,ptnl-prox.service,ptnl-res.service,ptnl.timerif present). These units useEnvironmentFile=/etc/ptunnel.env. - On the server: deploy the files from the
server/directory (ptnl.service,ptnl-res.service,ptnl.timer). The server typically runs theptunnel-ngbinary and listens for client connections.
If you don't already have a ptunnel-ng binary, build it from upstream.
Debian/Ubuntu prerequisites (example):
sudo apt update
sudo apt install build-essential libpcap-dev autoconf automake pkg-configBuild and install:
git clone https://github.com/utoni/ptunnel-ng.git
cd ptunnel-ng
./autogen.sh # or ./configure && make
sudo make installAfter installation the ptunnel-ng binary is commonly installed at /usr/local/bin/ptunnel-ng.
Use ptunnel.env.example as a template. Populate /etc/ptunnel.env with your values and ensure it is not committed.
Example:
sudo cp ptunnel.env.example /etc/ptunnel.env
sudo nano /etc/ptunnel.env
# set PTNL_SERVER_IP, PTNL_SERVER_SSH_PORT, etc.Key variables (present in ptunnel.env.example):
PTNL_SERVER_IP,PTNL_SERVER_SSH_PORT,PTNL_REMOTE_PORTLOCAL_BIND_IP,LOCAL_BIND_PORT,TARGET_HOST,TARGET_PORTSSH_USER,SSH_HOST,SSH_SSH_PORT,PTNL_SSH_USER
Security: never commit /etc/ptunnel.env to a public repo. Use the example file to document required variables.
After ptunnel-ng is installed and /etc/ptunnel.env is configured:
sudo systemctl daemon-reload
sudo systemctl enable --now ptnl.service
sudo systemctl enable --now ptnl-prox.serviceIf using the timer unit to periodically restart the tunnel:
sudo systemctl enable --now ptnl.timerCheck logs:
sudo systemctl status ptnl.service
sudo journalctl -u ptnl.service -f- Build or install
ptunnel-ngon the server (see upstream repo). - Copy
server/ptnl.serviceand related server units to/etc/systemd/system/on the server and enable them. - On each client, copy the files from
client/to/etc/systemd/system/, create/etc/ptunnel.envfrom the example, then enable the client units.
An install.sh helper is provided to simplify installing units and copying the example environment file. Usage examples (run as root from the repo root):
# Install client units and copy env (non-destructive)
sudo ./install.sh client
# Install server units only
sudo ./install.sh server
# Install both and overwrite any existing /etc/ptunnel.env
sudo ./install.sh all --forceThe script will copy unit files into /etc/systemd/system/, reload systemd, and enable/start the relevant units. It will set /etc/ptunnel.env mode to 600 if it copies the example file. Edit /etc/ptunnel.env to set real values before relying on the services.