WireGuard
WireGuard — результат исследований автора проекта Джейсона Доненфилда (Jason A. Donenfeld), главы компании Edge Security. Продукт со встроенной криптографией, одновременно простой в использовании и в реализации (чуть более 4000 строк кода), что существенно выделяет его среди остальных решений. Например, его код легче проанализировать, чем все, что написано в рамках *Swan/IPsec или OpenVPN. Самый молодой проект обзора. О нем заговорили в середине лета 2016-го после публикации анонса в списке рассылки разработчиков ядра Linux, где был представлен патч к ядру. Хотя сам проект развивается уже несколько лет и прошел стадию рецензирования криптографии, то есть его можно внедрять в основное ядро.
VPN-соединение инициализируется (handshake) путем обмена открытыми ключами и напоминает подход, применяемый в SSH. Все остальное прозрачно обрабатывается WireGuard, нет необходимости беспокоиться о ключах, роутинге, контроле состояния и прочем, это все забота WireGuard. Возможно использование симметричного шифрования, но это потребует чуть больших настроек. Маршрутизация производится по ключам шифрования, для этого к каждому сетевому интерфейсу привязывается закрытый ключ. Для обновления ключей handshake происходит через определенное время или по сигналу, что ключи устарели. Для согласования ключей и соединения вместо собственного демона в пространстве пользователя используется механизм Noise_IK из Noise Protocol Framework, похожий на поддержание authorized_keys в SSH, без усложнений в виде поддержки x509 и ASN.1.
Для шифрования применяются потоковый шифр ChaCha20 и алгоритм аутентификации сообщений (MAC) Poly1305. Для генерации совместного секретного ключа — протокол Диффи — Хеллмана на эллиптических кривых в реализации Curve25519, предложенной Дэниелом Бернштейном. Для хеширования используются BLAKE2s (RFC 7693) и SipHash-2-4. Избежать replay-атаки позволяет метка времени TAI64N, пакеты с меньшей меткой времени отбрасываются.
Передача данных осуществляется на третьем уровне ISO через инкапсуляцию в пакеты UDP. Поддерживаются IPv4 и IPv6, инкапсуляция v4 в v6 и v6 в v4. Может работать за NAT и файрволом. Поддерживается смена IP-адреса VPN-сервера без разрыва соединения с автоматической перенастройкой клиента.
После установки в системе появляется новый сетевой интерфейс wg0, который может быть настроен штатными инструментами ipconfig/ip-address и route/ip-route. Специальная утилита wg позволяет установить секретный ключ устройства и указать список ассоциаций для клиентов (его публичный ключ, разрешенный IP).
Для установки понадобится дистрибутив с ядром Linux >4.1. Пакет можно найти в репозиториях основных дистрибутивов Linux. Для Ubuntu 16.04 есть PPA.
$ sudo add-apt-repository ppa:hda-me/wireguard
$ sudo apt update
$ sudo apt install wireguard-dkms wireguard-tools
Самостоятельная сборка из исходных текстов также несложна. Поднимаем интерфейс, генерируем пару ключей (для примера сохраняем в файлах privatekey и publickey):
$ sudo ip link add dev wg0 type wireguard
$ wg genkey | tee privatekey | wg pubkey > publickey
Получаем публичный ключ от клиента и создаем соединение.
$ sudo wg set wg0 listen-port 1234 private-key ~/privatekey peer IKy1eCE9pP1w... allowed-ips 192.168.0.0/24 endpoint 1.2.3.4:9876
Возможно использование PresharedKey (генерируется командой wg genpsk), который добавляет еще один уровень симметричного шифрования к имеющемуся шифрованию с открытым ключом. Для пира можно указать PersistentKeepalive, позволяющий поддерживать соединение из-за NAT и файрвола. Поднимаем интерфейс:
$ sudo ip address add dev wg0 192.168.0.1
Смотрим настройки:
$ sudo wg
Для удобства лучше заранее подготовить конфигурационный файл, содержащий секцию interface и секции peer. Формат можно увидеть, введя wg showconf.
$ sudo wg setconf wg0 myconfig.conf
Подходит как для небольших встроенных устройств вроде смартфонов, так и для магистральных маршрутизаторов. Тесты показали, что WireGuard имеет примерно в четыре раза лучшую пропускную способность и в 3,8 раза более отзывчив по сравнению с OpenVPN (256-bit AES c HMAC-SHA-2–256). Здесь сказывается не только реализация в виде модуля ядра, тогда как OpenVPN работает в userspace. Повышение производительности обусловлено отказом от использования CryptoAPI ядра, работающего достаточно медленно. Вместо него в WireGuard задействованы собственные реализации ChaCha20, Poly1305, BLAKE2s и Curve25519, которые позиционируются как быстрые и безопасные аналоги AES-256-CTR и HMAC, их программная реализация позволяет добиться фиксированного времени выполнения без аппаратной поддержки.
Также WireGuard благодаря меньшим задержкам чуть лучше выглядит в производительности по сравнению с IPsec (256-bit ChaCha20 + Poly1305 и AES-256-GCM-128), но вот настройки гораздо проще.
Пока WireGuard доступен только для Linux, после тестирования предполагается портировать в другие ОС. Код распространяется под лицензией GNU GPLv2.
Только патчи накладывать не стоит - Kconf ломает.