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

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

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

    От сюда :

    Never place your SSH private keys on the bastion instance. Instead, use SSH agent forwarding to connect first to the bastion and from there to other instances in private subnets. This lets you keep your SSH private key just on your computer.

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

    TCP forward: Setting this value to true will enable TCP forwarding (SSH tunneling). This can be very useful but it is also a security risk, so we recommend that you keep the default (disabled) setting unless required

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

    SSH Agent Forwarding considered harmful

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

answer

Используйте 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, а srvC - это псевдоним для вашего сервера C. В поле HostNameвам необходимо указать IP-адреса или настоящее полное доменное имя для ваших хостов. Для пользователей вам необходимо обновить Userдля правильного имени входа на Bastion и сервере 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 [email protected] -p PORT

Взлом!

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

  • Насколько безопасен мой сервер? И ответ довольно прост:

    • НЕТ!
  • Почему?

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

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

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

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

Следить за целью

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

[[email protected] tmp]# ll
total 12
drwx------  2 bastion bastion 4096 Sep  7 17:35 ssh-mKX88v0Vlo

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

[[email protected] tmp]# cd ssh-mKX88v0Vlo/
[[email protected] 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-агенте на вашем ноутбуке.
  • Вы входите в бастион, авторизуясь через агента.
  • Оттуда войдите на целевой хост, а запрос аутентификации будет перенаправлен обратно на ваш ноутбук .

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

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