RU EN HE
About Projects Blog
← Back to blog
Networking & Infrastructure

SSH Tunnels in Containers: Secure Access to Remote Services

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.