Проблема
Legacy remote access часто растёт слоями: старые профили, временные ключи, разные протоколы, забытые панели, несколько мест генерации конфигов. В итоге никто не уверен, какой путь действительно используется и кто имеет доступ.
Атакующие любят такие узлы не из-за красоты протокола, а из-за близости к управлению: SSH, панели, monitoring, billing, CI/CD, DNS и сертификаты.
Решение
VPN-аудит должен проверять не только handshake. Нужна карта клиентов, сроков подписок, ключей, allowed IP, endpoint, fallback-профилей, логов ошибок и изменения конфигов.
Для SSH и админских портов нормальная модель - key-only, allowlist, Fail2Ban, запрет паролей, отдельные сервисные ключи, аудит fingerprint и periodic removal устаревших записей.
Что проверить руками
- Какие VPN-профили реально выдаёт бот и совпадают ли они с активными сервисами.
- Есть ли публичные management ports, которые должны быть только через VPN/allowlist.
- Откуда приходили успешные SSH-входы за неделю и какие key fingerprints использовались.
- Не истёк ли TLS-сертификат на edge и не сломано ли автообновление из-за ручного PEM.
Как это должно попадать в отчёт
- Отчёт по edge/VPN должен показывать доступность сервиса для пользователя и безопасность management plane отдельно. Работает туннель - хорошо, но это не доказывает, что доступы чистые.
- Ретест: внешний SSH закрыт для недоверенных IP, админские панели недоступны публично, VPN-клиент подключается, а alert появляется при drift конфигурации.
Безопасный пример: короткий read-only health-check edge/VPN узла
#!/usr/bin/env bash
set -euo pipefail
echo "[services]"
for svc in ssh xray awg-quick@awg0 nginx caddy fail2ban; do
systemctl is-active "$svc" >/dev/null 2>&1 && echo "$svc=active" || true
done
echo "[ssh policy]"
sshd -T | awk '/passwordauthentication|permitrootlogin|pubkeyauthentication/ {print}'
echo "[recent accepted keys]"
journalctl -u ssh -u sshd --since "7 days ago" --no-pager \
| grep "Accepted publickey" \
| awk '{print $1,$2,$3,$9,$11,$NF}' \
| tail -20
echo "[vpn link]"
ip -brief addr show awg0 2>/dev/null || true
wg show awg0 latest-handshakes 2>/dev/null || true