Гид по технологиям

SSH и Docker: стоит ли подключаться к контейнерам по SSH?

7 min read DevOps Обновлено 13 Dec 2025
SSH и Docker: стоит ли подключаться к контейнерам
SSH и Docker: стоит ли подключаться к контейнерам

Docker

Быстрая навигация

  • Нужно ли использовать SSH внутри контейнеров?
  • Как установить SSH-сервер в контейнере (пример для Debian)
  • Настройка аутентификации: пароли и ключи
  • Подключение к контейнеру и варианты порт-форвардинга
  • Упрощение с Dockssh
  • Альтернативы, шаблоны и рекомендации по безопасности
  • Контрольный список для ролей
  • Итог

Почему обычно не стоит использовать SSH внутри контейнера

SSH в контейнере часто рассматривают как «быстрый» способ получить интерактивный доступ. Однако контейнеры проектировались как короткоживущие, одноцелевые и воспроизводимые единицы. Вот основные аргументы против:

  • Иммутабельность: контейнеры должны быть неизменяемыми после сборки. Правки внутри запущенного контейнера теряются при пересоздании — вместо исправлений нужно пересобрать образ и перезапустить контейнер.
  • Дополнительная поверхность атаки: SSH-сервер добавляет зависимости, потенциальные уязвимости и необходимость управлять учётными записями.
  • Оверхед управления: если на хосте много контейнеров, потребуется отслеживать отдельные SSH-порты или процессы.
  • Инфраструктурная несовместимость: многие CI/CD и оркестраторы ожидают, что контейнер запускает только целевое приложение, а не системные демоны.

Вместо SSH чаще применяют:

  • docker exec -it bash (или sh) — быстрый и аудируемый способ получить shell;
  • kubectl exec для Kubernetes-кластеров;
  • специализированные прокси (например, Dockssh) для удобного внешнего подключения без установки SSH в образ.

Важно: в отдельных сценариях (локальная отладка, интеграция со старыми IDE, тестовые стенды) SSH внутри контейнера может быть допустимым временным решением.

Когда SSH внутри контейнера оправдан

  • Интеграция с устаревшими инструментами, требующими SSH-доступ;
  • Быстрая интерактивная отладка локального окружения в режиме разработки (не в production);
  • Учебные и экспериментальные среды;
  • Если невозможно модифицировать образ или процесс деплоя (например, проприетарные образы), и нужен временный доступ.

Как установить SSH-сервер в Docker-контейнер (пример для Debian)

Большинство базовых образов минималистичны — OpenSSH нужно добавить самостоятельно. Пример Dockerfile-фрагмента для Debian-подобного образа:

RUN apt-get update && apt-get install -y openssh-server
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN mkdir -p /var/run/sshd
ENTRYPOINT ["/usr/sbin/sshd","-D"]

Пояснения:

  • apt-get install устанавливает SSH-сервер;
  • sed меняет настройку PermitRootLogin; включать root-доступ не рекомендуется в production;
  • /var/run/sshd нужен systemd-less окружению, чтобы sshd мог создать pid-файл;
  • ENTRYPOINT запускает sshd в foreground (-D) вместо запуска systemd или service.

Лучше не давать прямой root-доступ, а создать отдельного пользователя:

RUN useradd -m -s /bin/bash sshuser

Настройка аутентификации

Парольный вход — простой, но менее безопасный:

RUN echo "sshuser:Changeme" | chpasswd

Более безопасно использовать ключи SSH. Генерируйте ключи на клиенте и добавьте публичный ключ в образ или смонтируйте его через volume. Пример “вшивания” ключа в образ (не всегда безопасно):

COPY id_rsa.pub /home/sshuser/.ssh/authorized_keys
RUN chown -R sshuser:sshuser /home/sshuser/.ssh
RUN chmod 600 /home/sshuser/.ssh/authorized_keys

Примечания безопасности:

  • Встраивание публичного ключа в образ делает ключ частью артефакта и доступным всем, у кого есть образ;
  • Лучше монтировать ~/.ssh/authorized_keys через volume при запуске контейнера или использовать конфигурационные системы/секрет-менеджеры;
  • Убедитесь, что права файлов соответствуют требованиям SSH (600 для authorized_keys, 700 для ~/.ssh).

Важное

Никогда не храните приватные ключи внутри образа. Приватные ключи должны оставаться только на клиентских машинах.

Подключение к контейнеру по SSH: примеры порт-форвардинга и альтернативы

Запуск контейнера и проброс порта 22 на хост (внимание: это может конфликтовать с SSH хоста):

docker run -p 22:22 my-image:latest

Если уже есть SSH-сервер на хосте или требуется нестандартный порт, пробрасывайте другой хост-порт, например 2220:

docker run -p 2220:22 my-image:latest

Тогда подключения будут такими:

ssh sshuser@host.example.com -p 2220

Если вы подключаетесь с хоста, где запущен Docker, можно получить IP контейнера (в простых сценариях bridge-сети):

docker inspect  | grep 'IPAddress' | head -n 1

Затем подключиться по IP:

ssh sshuser@172.17.0.1

Но адрес контейнера в bridge-сети часто недоступен извне и не стабилен при пересоздании.

Короткие имена через ~/.ssh/config

Чтобы не запоминать IP и порт, добавьте в ~/.ssh/config запись:

Host my-container
  HostName host.example.com
  Port 2220
  User sshuser

После этого ssh my-container откроет сессию в контейнере.

Dockssh: прокси, который делает docker exec доступным через ssh

Dockssh — проект, который слушает SSH-подключения и проксирует их в docker exec, избавляя от необходимости ставить sshd в каждом образе.

Пример установки и настройки (порядок действий):

  1. Установите Redis (Dockssh использует Redis для хранения паролей/настроек):
sudo apt install redis
  1. Добавьте запись для контейнера в Redis
redis-cli set dockssh:my-container:pass "container-password-here"
  1. Скачайте бинарный файл Dockssh и сделайте его исполняемым:
sudo curl https://github.com/alash3al/dockssh/releases/download/v1.1.0/dockssh_linux_amd64 -O /usr/local/bin/dockssh
sudo chmod +x /usr/local/bin/dockssh
  1. Откройте порт брандмауэра (по умолчанию Dockssh слушает 22022):
sudo ufw allow 22022
  1. Запустите Dockssh и проверьте доступ:
dockssh
ssh my-container@example.com -p 22022
  1. Можно зарегистрировать Dockssh как системную службу systemd:
sudo nano /etc/systemd/system/dockssh.service

Содержимое сервиса:

[Unit]
Description=Dockssh service
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/local/bin/dockssh

[Install]
WantedBy=multi-user.target

Активируйте сервис:

sudo systemctl enable dockssh.service
sudo systemctl start dockssh

Плюсы Dockssh:

  • Не требует установки sshd в образах;
  • Упрощает подключение к множеству контейнеров;
  • Позволяет использовать привычные команды ssh;
  • Централизует аутентификацию и аудит.

Ограничения:

  • Зависимость от Redis и дополнительного демона;
  • Требует настройки и безопасности на хосте;
  • Может не подходить для высоконагруженных продакшен-сред.

Альтернативные подходы (когда SSH не подходит)

  • docker exec / kubectl exec — стандартный и рекомендованный способ;
  • docker attach — прикрепление к рабочему процессу (если приложение поддерживает интерактивный ввод);
  • Sidecar-контейнер для отладки — отдельный контейнер с инструментами, подключённый к тому же namespace;
  • Remote debugging через IDE (настроить проброс портов от отладчика, а не SSH);
  • Использование CI/CD для внесения изменений через сборку новых образов.

Практическое руководство: когда и как безопасно использовать SSH

Мини-методология принятия решения:

  1. Определите цель доступа: отладка, интеграция, поддержка.
  2. Оцените риск: production vs dev/test.
  3. Если цель — временная отладка, используйте docker exec или sidecar.
  4. Если обязательна внешняя интеграция и альтернатив нет — применяйте SSH только с ключами, без паролей, и с ограниченным доступом по брандмауэру.
  5. Автоматизируйте: если правка кода нужна постоянно — внедрите CI и пересобирайте образы.

Контрольный список по ролям

Разработчик:

  • Использует docker exec вместо SSH для интерактивных сессий;
  • Если нужно, запускает временный контейнер с SSH только в локальном окружении;
  • Настраивает SAM/Makefile для воспроизводимых билдов.

Сисадмин/DevOps:

  • Запускает Dockssh или администрирует контроль доступа на хосте;
  • Настраивает firewall и ограничивает доступ по IP/ключам;
  • Внедряет аудит и логи для всех подключений;
  • Автоматизирует создание образов вместо ручных правок в контейнерах.

Инженер по безопасности:

  • Запрещает проброс порта 22 для контейнеров в production;
  • Проводит ревью образов на предмет лишних сервисов;
  • Обеспечивает управление секретами и rotatation ключей.

Безопасность и харднинг при использовании SSH в контейнере

  • Используйте SSH-ключи, отключите вход по паролю (PasswordAuthentication no) для production;
  • Ограничьте доступ с помощью AllowUsers/Match Address или firewall;
  • Отключите root-вход, создайте привилегированного пользователя с sudo по необходимости;
  • Следите за обновлениями пакетов и минимизируйте базовый образ;
  • Используйте readonly root filesystem, если приложение позволяет;
  • Логируйте сессии и направляйте логи в централизованную систему.

Критерии приёмки

  • Контейнер не содержит лишних демонов в production (включая sshd), если нет обоснования;
  • Все подключения к контейнерам документированы и централизованы;
  • Доступ через SSH защищён ключами, брандмауэр настроен, и есть аудит.

Примеры сценариев и когда это не сработает

Не стоит ставить SSH если:

  • Вы используете оркестраторы (Kubernetes), где ожидается управление через kubectl и инструменты CI;
  • Контейнеры деплоятся автоматически через CD и пересоздаются часто — ручной доступ приведёт к рассогласованию;
  • Требуется минимизация образа и поверхности атаки.

Подходит временно для:

  • Локальной разработки и отладки;
  • Закрытых тестовых стендов;
  • Миграции устаревших систем с ограниченной возможностью изменения процесса деплоя.

Шаблоны и сниппеты (читшит)

Запуск Debian-контейнера с SSHd для локальной отладки:

# Dockerfile
FROM debian:stable-slim
RUN apt-get update && apt-get install -y openssh-server sudo
RUN useradd -m -s /bin/bash sshuser && echo "sshuser:changeme" | chpasswd && adduser sshuser sudo
RUN mkdir -p /var/run/sshd
EXPOSE 22
ENTRYPOINT ["/usr/sbin/sshd","-D"]

Запуск контейнера и проброс порта 2222:

docker build -t my-ssh-image .
docker run -d -p 2222:22 --name my-dev my-ssh-image
ssh sshuser@localhost -p 2222

Dockssh быстрый старт (повтор):

redis-cli set dockssh:my-container:pass "container-password-here"
/usr/local/bin/dockssh
ssh my-container@example.com -p 22022

Рекомендации по миграции от SSH к современным практикам

  1. Автоматизируйте сборку образов и deployment pipelines;
  2. Внедрите docker exec / kubectl exec для администрирования; логируйте команды;
  3. Если необходим постоянный удалённый доступ — рассмотрите централизованные прокси (Dockssh) или bastion-хост на уровне инфраструктуры, но не в каждом образе;
  4. Используйте Sidecar/Debug-контейнеры для временных инструментов и мониторинга.

Итог

SSH в Docker-контейнерах — инструмент со своим местом, но чаще это антипаттерн. Для одноразовой отладки и интеграции с устаревшими процессами SSH может быть удобен, однако для устойчивых и безопасных рабочих процессов предпочтительнее docker exec, централизация доступа и использование прокси-решений вроде Dockssh. Если всё же используете SSH — строго соблюдайте практики безопасности, учёт прав доступа и автоматизацию обновлений.

Ключевые шаги для безопасного использования SSH:

  • По возможности используйте docker exec;
  • Если нужен SSH, применяйте ключи и ограничьте доступ;
  • Централизуйте управление (Dockssh, bastion);
  • Автоматизируйте пересборку образов вместо ручных правок.

Важно: для production-окружений избегайте установки SSH в образах без веской причины.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Компьютер завис на экране загрузки — как исправить
Компьютеры

Компьютер завис на экране загрузки — как исправить

Копирование масок в Camera Raw и Lightroom
Photo Editing

Копирование масок в Camera Raw и Lightroom

Как убрать зелёный треугольник в Excel
Excel

Как убрать зелёный треугольник в Excel

Как понять, что видеокамеру взломали и как реагировать
Безопасность

Как понять, что видеокамеру взломали и как реагировать

Защита от троянов на Android
Безопасность

Защита от троянов на Android

Как исправить поп-ин в играх
Игры

Как исправить поп-ин в играх