Перейти к содержимому

Создание своего SSH-бастион-сервера

Зачем нужен бастион и где он живёт

Бастион — единственная точка входа в приватный сегмент сети. Вместо того чтобы открывать SSH на каждом сервере из интернета, вы пускаете трафик через один хост, на котором настроена жёсткая политика доступа. Типичная схема: интернет → bastion (публичный IP) → внутренние серверы (только private subnet, SSH слушает на 127.0.0.1 или private interface).

Бастион живёт в демилитаризованной зоне (DMZ) или публичном подсети провайдера. Внутренние машины не имеют маршрута в интернет через бастион — обратный трафик идёт по инициированным соединениям. Это базовая модель, которую можно развернуть на любом VPS за 15 минут.

Выбор ОС и базовая установка

Бастион не нужен тяжёлый. Debian, Ubuntu Server или AlmaLinux — всё подойдёт. Я обычно беру минимальную установку Ubuntu 22.04 LTS и довожу до рабочего состояния руками.

# Обновление и минимальный набор утилит
sudo apt update && sudo apt upgrade -y
sudo apt install -y fail2ban ufw curl htop
Подсказка

Не ставьте на бастион GUI, базы данных и прочие сервисы. Чем меньше поверхность атаки, тем лучше.

Создайте непривилегированного пользователя для работы:

sudo adduser deploy
sudo usermod -aG sudo deploy

Настройка SSH: ключи, порт, запрет паролей

Генерируйте ключ на рабочей машине, если его ещё нет:

ssh-keygen -t ed25519 -C "bastion-access"
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@bastion_ip

На бастионе правьте /etc/ssh/sshd_config:

Port 22220
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
MaxSessions 5
AllowUsers deploy
Предупреждение

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

Проверьте конфиг и перезапустите:

sudo sshd -t
sudo systemctl restart sshd

Таблица ключей sshd_config и что они делают:

ПараметрЗначениеНазначение
Port22220Нестандартный порт, снижает шум в логах
PermitRootLoginnoЗапрещает прямой вход под root
PasswordAuthenticationnoРазрешает только ключи
MaxAuthTries3Ограничивает попытки аутентификации
AllowUsersdeployБелый список пользователей

Файрвол и ограничение доступа

UFW — простой способ закрыть всё лишнее:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22220/tcp comment "SSH bastion"
sudo ufw enable

Если бастион нужен только для вашего IP, ограничьте ещё жёстче:

sudo ufw allow from YOUR_IP to any port 22220 proto tcp
Примечание

Если IP динамический, используйте VPN вместо открытия порта. Открывать SSH в интернет без ограничений по источнику — плохая практика.

Для внутреннего трафика добавьте правило на бастионе, чтобы он мог маршрутизировать пакеты:

sudo sysctl -w net.ipv4.ip_forward=1

В /etc/sysctl.conf пропишите net.ipv4.ip_forward = 1, чтобы правило сохранилось после перезагрузки.

Fail2ban и защита от брутфорса

Установите и настройте Fail2ban для защиты от перебора:

sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

В /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = 22220
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

Перезапустите:

sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
sudo fail2ban-client status sshd

Логирование и аудит

Бастион должен логировать всё. В Debian/Ubuntu логи SSH идут в /var/log/auth.log. Для централизованного сбора настройте rsyslog на отправку на отдельный SIEM или хотя бы на второй сервер:

# В /etc/rsyslog.conf добавьте:
*.* @logserver_ip:514

Для аудита действий пользователей подключите auditd:

sudo apt install auditd -y
sudo auditctl -w /etc/ssh/sshd_config -p wa -k ssh_config
sudo auditctl -w /home -p r -k user_files

Просмотр событий:

sudo ausearch -k ssh_config
sudo ausearch -k user_files
Предупреждение

Логи на бастионе — первая цель атакующего. Настройте удалённую отправку как можно раньше, иначе при компрометации вы потеряете историю инцидента.

Проброс портов и туннели через бастион

Основная задача бастиона — дать доступ к внутренним машинам без открытия им портов. Три способа:

1. Проброс порта через SSH-туннель:

ssh -L 5432:10.0.1.5:5432 deploy@bastion_ip -p 22220

Теперь локальный порт 5432 на вашей машине проксируется к PostgreSQL на 10.0.1.5.

2. SOCKS-прокси для доступа ко всем внутренним хостам:

ssh -D 1080 deploy@bastion_ip -p 22220

Настройте браузер или proxychains на 127.0.0.1:1080.

3. Reverse tunnel для доступа к вашей локальной машине из сети бастиона:

ssh -R 9090:localhost:8080 deploy@bastion_ip -p 22220

Это позволяет обратиться к локальному сервису на порту 9090 бастиона.

Для постоянных туннелей используйте autossh или настройте ~/.ssh/config:

Host bastion
    HostName bastion_ip
    Port 22220
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
    ServerAliveCountMax 3

Теперь достаточно ssh bastion для подключения, а туннели строятся одной командой.

Подсказка

Для командной работы команды хранят ключи в 1Password или HashiCorp Vault, а доступ к бастиону выдаётся через временные сессии с истекающими токенами. Это снижает риск компрометации ключа.