Introduction
Accessing remote services through SSH tunnels is standard practice in enterprise environments. Containerizing these tunnels adds isolation, simplifies management, and enables integration into Podman pod infrastructure.
Containerfile for SSH Tunnel
FROM docker.io/library/alpine:3.19
RUN apk add --no-cache openssh-client netcat-openbsd
COPY tunnel.sh /tunnel.sh
RUN chmod +x /tunnel.sh
HEALTHCHECK --interval=10s --timeout=5s --retries=3
CMD nc -z localhost 8088 || exit 1
ENTRYPOINT [“/tunnel.sh”]
Tunnel Script (tunnel.sh)
#!/bin/sh
set -euo pipefail
mkdir -p /root/.ssh
ssh-keyscan -H “$REMOTE_HOST” >> /root/.ssh/known_hosts
while true; do
ssh -N -o ServerAliveInterval=30
-o ExitOnForwardFailure=yes
-L 0.0.0.0:“$LOCAL_PORT”:“$TARGET_HOST”:“$TARGET_PORT”
-i /secrets/ssh_key
“$SSH_USER”@“$REMOTE_HOST” || true
sleep 5
done
Health Checks
Netcat-based healthcheck verifies the tunnel’s local port is accessible. This allows other containers in the pod to wait for tunnel establishment before starting work. Podman exposes health status via podman healthcheck run.
Port Forwarding (-L 0.0.0.0:port)
A critical detail — binding to 0.0.0.0 instead of localhost. Inside a Podman pod, containers communicate through a shared network namespace. A tunnel bound to 0.0.0.0 is accessible to all pod containers. Binding to 127.0.0.1 makes it available only to the tunnel container itself.
known_hosts Management
ssh-keyscan at container startup automatically adds the remote host key. For enhanced security, provide a static known_hosts via volume or Podman secret. StrictHostKeyChecking can remain yes when using preloaded keys.
Use Cases
We use containerized SSH tunnels for accessing Asterisk ARI (telephony REST interface), PostgreSQL databases in secured networks, and API services accessible only from specific network segments.
Automatic Reconnection
The infinite while true loop with sleep provides automatic recovery on connection loss. ServerAliveInterval and ServerAliveCountMax detect “dead” connections. ExitOnForwardFailure ensures clean exit when port forwarding fails.
Conclusion
Containerized SSH tunnels are a reliable and convenient way to provide secure access to remote services. Health checks, auto-reconnection, and Podman pod integration make this solution production-ready.