Оптимизация SSH-аутентификации: Ускорение в 178 раз
Каждое SSH-подключение, замедляющееся на несколько секунд, со временем накапливает часы потерянного времени. Это особенно актуально для тех, кто постоянно взаимодействует с серверами для автоматизации рутинных задач. В моем случае расшифровка SSH-ключа при каждом соединении занимала 4.6508 секунды. После оптимизации этот показатель сократился до впечатляющих 0.0261 секунды. В этой статье я подробно расскажу, как мне удалось добиться такого значительного ускорения.
Почему процесс был таким медленным?
🔹 OpenSSH + пароль (passphrase)
Изначально я использовал SSH-ключи в формате OpenSSH, защищенные паролем (passphrase). OpenSSH применяет для шифрования алгоритм bcrypt (или аналогичный KDF) с очень большим числом итераций. Хотя это обеспечивает высокий уровень безопасности, это также приводит к чрезвычайно медленной расшифровке. Когда исполняющий сервер пытался расшифровать ключ, процесс занимал более 4 секунд.
🔹 Постоянная загрузка ключа
При каждом деплое, выполнении задач или тестировании ключ расшифровывался снова и снова. Это не только раздражало, но и существенно замедляло общую производительность работы.
Как ускорить SSH-аутентификацию?
1. Переход с OpenSSH на PKCS8
Ключевым шагом стало изменение формата хранения приватного ключа. Я отказался от шифрования bcrypt внутри OpenSSH в пользу формата PKCS8 с использованием PBKDF2. PKCS8 позволяет задать разумное количество итераций или использовать значения по умолчанию, что значительно ускоряет процесс.
📌 Основное различие:
- ❌ OpenSSH (bcrypt, cost=16–18): Секунды на расшифровку.
- ✅ PKCS8 (PBKDF2, 10k–20k итераций | дефолт): Миллисекунды на расшифровку.
Важно отметить, что публичная часть ключа по-прежнему остается в формате OpenSSH (для файла authorized_keys), но приватная часть теперь хранится в формате PKCS8.
2. Дополнительное шифрование AES-256
Чтобы приватный ключ не хранился в открытом виде, я добавил поверх него дополнительное шифрование AES-256. Эта операция требует минимальных вычислительных ресурсов и гарантирует, что ключ не будет лежать в незашифрованном виде на диске (даже если это S3).
Теперь процесс расшифровки выглядит так:
- AES-256: ≈0.001 секунды
- PKCS8 (PBKDF2): <0.02 секунды
Таким образом, общее время расшифровки составляет менее 0.03 секунды, вместо исходных 4.6508 секунд.
Итог: Ускорение в 178 раз 🚀
Бенчмарк показал разницу в 17 739%. Теперь SSH-аутентификация выполняется в сотни раз быстрее, что значительно ускоряет процессы деплоя и управления серверами.
Дополнительные рекомендации по оптимизации:
- Отключите
UseDNSиGSSAPIAuthenticationв файлеsshd_config, если наблюдаются задержки на этапе handshake. - Убедитесь, что вы используете оптимизированные криптографические библиотеки, такие как gmp/openssl/sodium, а не чистые реализации на уровне языка программирования, которые могут значительно замедлять процесс.
Даже такая, казалось бы, небольшая оптимизация может дать огромный прирост скорости. Если вы сталкиваетесь с долгим временем SSH-авторизации, попробуйте применить этот подход.