Настройка AWS Bastion Host SSH-туннель

by moiseevrus

В реальных сценариях развертывания облака рекомендуется защищать инфраструктуру с помощью жесткой сетевой безопасности. Чтобы добиться этого в AWS, вы можете использовать защищенные образы AMI, обеспечивающие только контролируемый доступ на уровне ОС и приложений. На уровне сети или VPC следует рассмотреть многоуровневый подход, при котором клиентам доступен только уровень приложения или веб-консоль пользовательского интерфейса. Доступ к базе данных должен быть ограничен разработчиками, а доступ на уровне экземпляра — только для администраторов. Общедоступная облачная среда отличается от обычной локальной среды, поскольку она имеет большую вероятность взлома, поскольку она не находится за брандмауэром, контролируемым ИТ-специалистами, как в большинстве корпоративных центров обработки данных.

Модель общей ответственности AWS требует, чтобы вы как пользователь обеспечивали безопасность своих ресурсов и данных. Использование хоста-бастиона в таких случаях очень удобно и используется очень часто. В этом посте я расскажу о некоторых основах и покажу, как вы можете получить доступ к своей серверной инфраструктуре с помощью туннелирования SSH через хост-бастион.

Что такое бастионный хост?

Проще говоря, хост-бастион — это единственный хост или компьютер, которому разрешен общедоступный доступ к сети. Другое распространенное имя, используемое для хоста-бастиона, – «Jump Box». Обычно это мощный сервер с высокой сетевой безопасностью, поскольку это единственный хост, к которому разрешен публичный доступ. Системные администраторы могут использовать этот компьютер для подключения к другим экземплярам внутренней инфраструктуры с помощью безопасных механизмов аутентификации.

Что такое SSH-туннелирование? или Что такое переадресация портов по отношению к SSH?

Туннелирование SSH или перенаправление портов — это механизм в SSH для подключения портов приложений с клиентского компьютера на серверный компьютер или наоборот. Для большинства ИТ-приложений он используется для добавления шифрования к устаревшим приложениям, прохождения через брандмауэры и открытия бэкдоров во внутреннюю сеть из их локальной сети или компьютеров корпоративной сети.

Настройка AWS Bastion Host SSH-туннель

В этом разделе я рассмотрю пример архитектуры, показанный на рисунке ниже. Здесь у нас есть один VPC с публичной и частной подсетями. Скажем, например, ваши экземпляры серверов Windows и Linux в частной подсети работают под управлением веб-сервера.

  • Предполагая, что веб-серверы на этих компьютерах с Windows и Linux работают на портах по умолчанию, нам нужно разрешить общий доступ к порту 80. Все остальные порты должны быть заблокированы. Хосту-бастиону требуется доступ к SSH-порту 22 на Linux-сервере и RDS-порту 3389 на Windows-сервере, чтобы его можно было использовать для удаленного доступа к этим машинам. В этом примере я создал одну группу безопасности для обоих типов экземпляров. В качестве альтернативы вы можете иметь группу безопасности для Windows с доступом только к порту RDP 3389 и другую группу безопасности для Linux с доступом только к порту 22 SSH. Остальные права доступа будут одинаковыми для обеих групп безопасности. (ПРИМЕЧАНИЕ. Здесь предполагается, что вы используете список управления доступом к сети (NACL) по умолчанию для подсетей, который разрешает весь трафик. Если это не NACL по умолчанию,
  • Хост-бастион должен быть доступен из Интернета, чтобы системные администраторы могли войти в систему. В этом примере доступ открыт для всех IP-адресов, но в реальном сценарии вы должны ограничить IP-адреса, которые могут получить доступ к диапазону IP-адресов. адреса, которые вы знаете, находятся в белом списке. (ПРИМЕЧАНИЕ. Чтобы разрешить доступ к набору IP-адресов в частной корпоративной сети, необходимо настроить VPN-подключение к корпоративному центру обработки данных и разрешить доступ только к диапазону IP-адресов группы системного администратора).
Настройка AWS Туннель SSH Bastion Host

Настройка SSH-туннеля/переадресации портов с помощью Putty.exe

Первым шагом является настройка туннеля, в котором вы настраиваете перенаправление всего трафика с порта на вашем хосте-бастионе на интересующий порт на компьютерах с серверами Windows и Linux. Прежде чем начать, убедитесь, что у вас есть пара ключей, загруженная с AWS (файл .pem), преобразованный закрытый ключ (файл .ppk) и Putty.exe. Здесь я буду использовать Putty для демонстрации, но вы можете использовать любой другой подобный инструмент. Выполните следующие шаги с изображениями.

Запустите шпатлевку, введите IP-адрес бастионного хоста и SSH-порт 22 для доступа к бастионному хосту.

Выберите файл закрытого ключа .ppk, который будет использоваться для аутентификации.

Настройка AWS Bastion Host SSH-туннель Putty

Нажмите SSH -> X11. Установите флажок «Включить переадресацию X11».

Настройка AWS Bastion Host SSH-туннель Putty

Нажмите SSH-> Туннели. Для туннеля на Linux-сервер введите «Исходный порт», т.е. порт на локальном компьютере, и пункт назначения «<Linux Server IP>:22».

Настройка AWS Bastion Host SSH-туннель Putty

Аналогичным образом настройте туннель для сервера Windows с порта 33389 локального компьютера на порт 3389 сервера Windows. Нажмите «Добавить», а затем нажмите «Применить».

Настройка AWS Bastion Host SSH-туннель Putty

Это настроит сеанс SSH узла-бастиона. Это откроет удаленный сеанс бастионного хоста с настройкой туннелей от локальных портов к портам на серверах Linux и Windows.

Настройка AWS Туннель SSH Bastion Host

Настройка SSH-туннеля/переадресации портов с помощью командной строки

Если у вас установлена ​​утилита командной строки SSH, настроить туннель SSH довольно просто, используя следующие команды:

Для Linux-сервера

ssh -i GATEWAY_KEY.pem -N -L 33322:USERNAME@LINUX_SERVER_PRIVATE_IP:22

Для сервера Windows,

ssh -i GATEWAY_KEY.pem -N -L 33389:USERNAME@WINDOWS_SERVER_PRIVATE_IP:3389

Удаленный доступ к инстансу AWS EC2 Linux

Теперь, с настройкой туннелирования, чтобы получить доступ к серверу Linux, все, что вам нужно сделать, это подключиться к порту 33322 вашей локальной машины через SSH с вашим закрытым ключом. Подключение к этому локальному порту соединит вас с портом 22 на сервере Linux через хост-бастион. Вы можете следовать инструкциям, описанным ниже.

Откройте putty.exe, установите IP-адрес на localhost или 127.0.0.1 и порт 33322.

Настройка AWS Bastion Host SSH-туннель Putty

Выберите файл закрытого ключа .ppk в SSH->Auth. Когда вы нажмете кнопку «Открыть», он подключит вас к порту 22 на сервере Linux.

Настройка AWS Bastion Host SSH-туннель Putty

Удаленный доступ к экземпляру Windows AWS EC2

Точно так же для доступа к серверу Windows вам необходимо подключиться напрямую к порту 33389 на локальной машине. Это позволит подключиться к порту RDP 3389 на сервере Windows путем туннелирования через хост-бастион. Вы можете выполнить следующие действия.

В консоли AWS EC2 выберите экземпляр сервера Windows и нажмите кнопку «Подключиться» вверху. Откроется экран, как показано ниже.

Настройка AWS Туннель SSH Bastion Host

Когда вы нажмете кнопку «Получить пароль», вы попадете на экран, показанный ниже, где вам нужно выбрать файл ключа .pem, который вы загрузили при создании пары ключей. После этого нажмите кнопку «Расшифровать пароль».

Настройка AWS Туннель SSH Bastion Host

Это приведет вас к изображению ниже. Вы можете сохранить имя пользователя и пароль на экране ниже для дальнейшего использования.

Настройка AWS Туннель SSH Bastion Host

Затем откройте приложение «Подключение к удаленному рабочему столу» и введите имя компьютера как localhost, а порт — как тот, который вы сопоставили для туннелирования. Нажмите «Подключиться».

Настройка AWS Туннель SSH Bastion Host

Введите имя пользователя и пароль, показанные на экране ранее. Это соединит вас с сервером Windows.

Настройка AWS Туннель SSH Bastion Host

Удаленный доступ к экземпляру AWS EC2 с помощью AWS SDK

Удаленное взаимодействие на машинах в AWS работает немного по-другому. В обычном случае вы должны использовать библиотеку удаленного взаимодействия и подключаться через SSH к удаленному компьютеру и выполнять команды. Но в случае экземпляров AWS EC2 AWS SDK предоставляет возможность сделать это в своем API. AWS предоставляет Simple Systems Manager (SSM) , с помощью которого вы можете запускать команды на инстансах EC2. Обратитесь к простому примеру Python ниже. За подробным примером и реализацией вы можете обратиться к примеру Remoting на моем GitHub . В этом примере просто замените ACCESS_KEY_ID, SECRET_ACCESS_KEY и REGION на соответствующие значения из вашей среды. Я выделил часть, где выполняется команда.

import time
import boto3def execute_ec2_command(ssm_client, type, instance_id, command, timeout=10):
        # Execute command 
        cmd = [command]
        if type == 'linux':
            command_meta = ssm_client.send_command ( \
   DocumentName = 'AWS-RunShellScript', \
   Parameters = {'commands': cmd}, \
   InstanceIds = [instance_id]) 
        else:
            command_meta = ssm_client.send_command( \
   DocumentName = 'AWS-RunPowershellScript', \
   Parameters = {'commands': cmd}, \
   InstanceIds = [instance_id])
        
        # Wait for timeout or until command returns successfully
        time_initial = time.time()
        now = time.time()
        while now - time_initial < timeout:
            command_status = ssm_client.list_commands( \
    CommandId = command_meta['Command']['CommandId'])['Commands'][0]['Status']
            
            if command_status == 'Success':
                command_result = \
    ssm_client.get_command_invocation( \
    InstanceId=instance_id, \
    CommandId=command_meta['Command'] \
    ['CommandId'])['StandardOutputContent']
                print('Command Output={0}'.format(command_result))
                return command_result
            else:
                time.sleep(0.1)
                now = time.time()
        if now - time_initial > timeout:
            command_status = \
   ssm_client.list_commands( \
   CommandId = command_meta['Command']['CommandId'])['Commands'][0]['Status']
            print('Command Status={0}'.format(command_status))
            if command_status != 'Success':
                raise RuntimeError('function timed out')
                
if __name__=='__main__':
    ec2_ssm_client = boto3.client('ssm', aws_access_key_id='ACCESS_KEY_ID',
                                  secret_access_key='SECRET_ACCESS_KEY',
                                  region_name='REGION')
    
    # for windows ec2 instance with given instance id
    win_ec2_instance_id = 'i-03#####'
    cmd = 'ipconfig'
    print('Command={0}, Result={1}'.format( \
 cmd, \
 execute_ec2_command(ssm_client=ec2_ssm_client, \
  type='windows', \
  instance_id=win_ec2_instance_id, \
  command=cmd)))
   
    # for linux ec2 instance with given instance id 
    linux_ec2_instance_id = 'i-04#####'
    cmd = 'ls /tmp/'
    print('Command={0}, Result={1}'.format( \
 cmd, \
 execute_ec2_command(ssm_client=ec2_ssm_client, \
  type='linux', \
        instance_id=win_ec2_instance_id, \
        command=cmd)))

В этом примере метод execute_ec2_command() выполняет команду и ждет, пока она не завершится успешно или не истечет время ожидания. Если вы хотите выполнять асинхронно, вы можете удалить ожидание.

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

Статья является переводом сайта medium.com

You may also like

Leave a Comment