Перенаправление SSH подключений в Docker контейнеры

16 января 2020
526
Docker

Все большую популярность набирает заворачивание приложений в контейнеры Docker.

Мы как-то сталкивались с задачей отправки входящих SSH соединений в Docker контейнер. И в нашем случае контейнеров на сервере было запущено несколько и нужный надо было выбирать в зависимости от SSH пользователя.

Такую задачу можно решить по-разному. Например через PAM модули или через утилиту SSSD. Расскажем как решили такую задачу мы.

Предположим у нас на сервере есть 3 контейнера:

root@docker-host:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e030b82754aa        httpd               "httpd-foreground"       16 minutes ago      Up 16 minutes       80/tcp              objective_ptolemy
009a6a67088c        nginx               "nginx -g 'daemon of…"   17 minutes ago      Up 17 minutes       80/tcp              zealous_bhabha
44bfa92a9a85        postgres            "docker-entrypoint.s…"   17 minutes ago      Up 17 minutes       5432/tcp            sweet_bohr

И у нас на сервере есть 3 пользователя:

root@docker-host:~# id sveta
uid=1000(sveta) gid=1000(sveta) groups=1000(sveta)

root@docker-host:~# id yaroslav
uid=1001(yaroslav) gid=1001(yaroslav) groups=1001(yaroslav)

root@docker-host:~# id liza
uid=1002(liza) gid=1002(liza) groups=1002(liza)

Мы бы хотели чтобы при входе по SSH от пользователя sveta логин происходил не на сервер docker-host, а в определенный контейнер. Вот как это сделать:

Добавим sveta в группу docker:

root@docker-host:~# usermod -a -G docker sveta

Создадим небольшой скрипт. Он будет определять в какой контейнер перенаправить входящее SSH подключение.

mcedit /usr/local/bin/docker.wrapper

Добавим туда содержимое:

#!/bin/bash -eu

declare -r USER="$1"
declare -r USER_LIST='/etc/docker.users'
declare -r CONTNAME="$(grep -w "$USER" $USER_LIST | cut -d':' -f2)"
declare -r CONT_ID="$(docker ps --filter "name=${CONTNAME}" | sed -e '1d' | awk '{print $1}')"

[[ "$@" = "$USER" ]] && {
    declare -r COMMAND='/bin/bash'

    docker exec -it $CONTNAME $COMMAND
} || {
    declare -r COMMAND="$(echo "$@" | awk '{$1 = ""; print $0}')"

    docker exec -i $CONTNAME $COMMAND
}

Позволим выполнять этот файл:

chmod 755 /usr/local/bin/docker.wrapper

Создадим файл, где будет храниться соответствие каких пользователей отправлять в какой контейнер:

mcedit /etc/docker.users

Чтобы пользователь sveta имел доступ к контейнеру с httpd под названием objective_ptolemy добавим в файл содержимое:

sveta:objective_ptolemy

Откроем настройки

mcedit /etc/ssh/sshd_config

В конце файла добавим строки

Match Group docker
        X11Forwarding no
        AllowTcpForwarding no
        ForceCommand /usr/local/bin/docker.wrapper $USER $SSH_ORIGINAL_COMMAND

После этого перезапустим SSH

service ssh restart

С локального компьютера проверим, как все работает:

user@local-pc ~ $ ssh sveta@docker-host
sveta@docker-host's password:
root@e030b82754aa:/usr/local/apache2# cat /etc/hostname
e030b82754aa

Аналогично можно сделать и для других локальных пользователей, например yaroslav и liza. Достаточно лишь добавить их в группу docker и прописать в /etc/docker.users. Готово!

Мы используем файлы cookie для предоставления наших услуг, а также для аналитики и маркетинга. Продолжая просматривать наш веб-сайт, вы соглашаетесь на использование нами файлов cookie.
ОК