RU EN HE
Обо мне Проекты Блог
← Назад к блогу
Сети и инфраструктура

SSH-туннели в контейнерах: безопасный доступ к удалённым сервисам

Введение

Доступ к удалённым сервисам через SSH-туннели — стандартная практика в enterprise-среде. Контейнеризация этих туннелей добавляет изоляцию, упрощает управление и позволяет интегрировать их в инфраструктуру Podman-подов.

Containerfile для SSH-туннеля

FROM docker.io/library/alpine:3.19
RUN apk add --no-cache openssh-client netcat-openbsd
COPY tunnel.sh /tunnel.sh
COPY ssh_config /etc/ssh/ssh_config
RUN chmod +x /tunnel.sh
HEALTHCHECK --interval=10s --timeout=5s --retries=3 
CMD nc -z localhost 8088 || exit 1 ENTRYPOINT [“/tunnel.sh”]

Скрипт туннеля (tunnel.sh)

#!/bin/sh
set -euo pipefail

# Добавляем ключ хоста mkdir -p /root/.ssh ssh-keyscan -H “$REMOTE_HOST” >> /root/.ssh/known_hosts 2>/dev/null

# Цикл переподключения while true; do echo “[$(date)] Connecting to $REMOTE_HOST…” ssh -N -o ServerAliveInterval=30
-o ServerAliveCountMax=3
-o ExitOnForwardFailure=yes
-L 0.0.0.0:“$LOCAL_PORT”:“$TARGET_HOST”:“$TARGET_PORT”
-i /secrets/ssh_key
“$SSH_USER”@“$REMOTE_HOST” || true

echo “[$(date)] Disconnected. Reconnecting in 5s…” sleep 5 done

Health Checks

Healthcheck через netcat проверяет, что локальный порт туннеля доступен. Это позволяет другим контейнерам в поде дождаться установления туннеля перед началом работы. Podman выставляет статус здоровья через podman healthcheck run.

Проброс портов (-L 0.0.0.0:port)

Важный момент — привязка к 0.0.0.0 вместо localhost. Внутри Podman-пода контейнеры общаются через общий сетевой namespace. Туннель, привязанный к 0.0.0.0, доступен всем контейнерам пода. При привязке к 127.0.0.1 — только самому контейнеру туннеля.

Управление known_hosts

ssh-keyscan при запуске контейнера автоматически добавляет ключ удалённого хоста. Для повышения безопасности можно предоставить статический known_hosts через volume или Podman secret. StrictHostKeyChecking можно оставить yes при использовании предзагруженных ключей.

Примеры использования

Мы используем контейнеризированные SSH-туннели для доступа к Asterisk ARI (REST-интерфейс телефонии), базам данных PostgreSQL в защищённых сетях и API-сервисам, доступным только из определённых сегментов сети.

Автоматическое переподключение

Бесконечный цикл while true с sleep обеспечивает автоматическое восстановление при разрыве соединения. ServerAliveInterval и ServerAliveCountMax обнаруживают “мёртвые” соединения. ExitOnForwardFailure гарантирует корректный выход при невозможности проброса порта.

Заключение

Контейнеризированные SSH-туннели — надёжный и удобный способ обеспечения безопасного доступа к удалённым сервисам. Healthcheck, автопереподключение и интеграция с Podman-подами делают это решение production-ready.