"Быстрый
<br />
IKEv2/IPsec через StrongSwan — единственный протокол с нативной поддержкой на Windows 10/11, iOS, Android и macOS одновременно. Никаких сторонних приложений.</p>
<p>Что нужно для запуска:</p>
<ul>
<li>Ubuntu 24.04 с белым IP</li>
<li>Открытые порты 500/udp и 4500/udp</li>
<li>Домен или статический IP для CN сертификата</li>
<li>Около 30 минут времени</li>
</ul>
<p>Порядок: установка пакетов → генерация PKI → конфиг strongswan → UFW + NAT → проверка → подключение клиентов.<br />
<h2>Диагноз: почему именно IKEv2</h2>
<p>Тебе нужен корпоративный VPN. Пользователи — люди с айфонами, андроидами, рабочими ноутами на <a class="wpil_keyword_link" href="https://it-apteka.com/category/windows-server/" target="_blank" rel="noopener" title="Windows Server" data-wpil-keyword-link="linked" data-wpil-monitor-id="2737">Windows</a>. Ты поднял OpenVPN. Теперь пишешь инструкции «как установить клиент», отвечаешь на вопросы в чате и объясняешь бухгалтерии что такое tun-адаптер. Знакомо?</p>
<p><a href="https://it-apteka.com/install-asterisk-full-manual/" title="Asterisk с нуля: установка, настройка и запуск IP-телефонии на сервере" target="_blank" rel="noopener" data-wpil-monitor-id="2738">Настройка IKEv2 VPN сервера</a> на Ubuntu решает эту проблему. IKEv2 встроен во все мажорные ОС — Windows 10+, iOS 9.1+, Android 11+, macOS 10.11+. Пользователь заходит в системные настройки, добавляет VPN, вводит логин и пароль. Всё.</p>
<p>Что получишь в итоге:</p>
<ul>
<li>VPN сервер с EAP-аутентификацией по логину/паролю</li>
<li>Нативное подключение с любой платформы без сторонних приложений</li>
<li>AES-256-GCM + ChaCha20 — современные алгоритмы шифрования</li>
<li>Автовосстановление соединения через MOBIKE при смене <a class="wpil_keyword_link" href="https://it-apteka.com/category/networks/" target="_blank" rel="noopener" title="Сети" data-wpil-keyword-link="linked" data-wpil-monitor-id="2735">сети</a></li>
</ul>
<p>Уйдёт 25-35 минут. Нужен root или sudo на сервере.</p>
<h2>Матрица совместимости: что работает без клиента</h2>
<p>Перед тем как разворачивать — смотри реальность:</p>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<thead>
<tr style="background-color: #f2f2f2;">
<th style="border: 1px solid #ddd; padding: 10px; text-align: left;">Протокол</th>
<th style="border: 1px solid #ddd; padding: 10px; text-align: center;">Windows 10/11</th>
<th style="border: 1px solid #ddd; padding: 10px; text-align: center;">iOS 17+</th>
<th style="border: 1px solid #ddd; padding: 10px; text-align: center;">Android 11+</th>
<th style="border: 1px solid #ddd; padding: 10px; text-align: center;">macOS 12+</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>IKEv2/IPsec</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>L2TP/IPsec</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>PPTP</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #fff3cd;">Устарел</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Удалён в iOS 10</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #fff3cd;">Устарел</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Удалён</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>SSTP</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #d4edda;">Нативно</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нет</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нет</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нет</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>OpenVPN</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>WireGuard</strong></td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
<td style="border: 1px solid #ddd; padding: 10px; text-align: center; background-color: #f8d7da;">Нужен клиент</td>
</tr>
</tbody>
</table>
<p>L2TP тоже везде есть, но медленнее и содержит известные уязвимости в реализациях PSK. IKEv2 — единственный правильный выбор для 2025 года, если нужен нативный клиент без вопросов от пользователей.</p>
<h2>Системные требования</h2>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<thead>
<tr style="background-color: #f2f2f2;">
<th style="border: 1px solid #ddd; padding: 10px;">Параметр</th>
<th style="border: 1px solid #ddd; padding: 10px;">Минимум</th>
<th style="border: 1px solid #ddd; padding: 10px;">Рекомендуется</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">ОС</td>
<td style="border: 1px solid #ddd; padding: 10px;"><a href="https://it-apteka.com/linux-v-aprele-2026-jadro-7-0-ubuntu-26-04-lts-i-francija-brosaet-windows/" title="Linux в апреле 2026: ядро 7.0, Ubuntu 26.04 LTS и Франция бросает Windows" target="_blank" rel="noopener" data-wpil-monitor-id="2739">Ubuntu 22.04 LTS</a></td>
<td style="border: 1px solid #ddd; padding: 10px;">Ubuntu 24.04 LTS</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">StrongSwan</td>
<td style="border: 1px solid #ddd; padding: 10px;">5.9.x</td>
<td style="border: 1px solid #ddd; padding: 10px;">5.9.13+ (из репо Ubuntu 24.04)</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">RAM</td>
<td style="border: 1px solid #ddd; padding: 10px;">512 MB</td>
<td style="border: 1px solid #ddd; padding: 10px;">1 GB+</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">IP</td>
<td style="border: 1px solid #ddd; padding: 10px;">Статический публичный IP</td>
<td style="border: 1px solid #ddd; padding: 10px;">IP + домен (для Let’s Encrypt)</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">Порты</td>
<td style="border: 1px solid #ddd; padding: 10px;">500/udp, 4500/udp</td>
<td style="border: 1px solid #ddd; padding: 10px;">500/udp, 4500/udp, 22/tcp</td>
</tr>
</tbody>
</table>
<p>На момент публикации актуальна StrongSwan 5.9.13. Перед установкой проверь актуальную версию в репозитории: <code>apt-cache policy strongswan</code>.</p>
<h2>Таблица портов</h2>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<thead>
<tr style="background-color: #f2f2f2;">
<th style="border: 1px solid #ddd; padding: 10px;">Порт</th>
<th style="border: 1px solid #ddd; padding: 10px;">Протокол</th>
<th style="border: 1px solid #ddd; padding: 10px;">Назначение</th>
<th style="border: 1px solid #ddd; padding: 10px;">Снаружи</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">500</td>
<td style="border: 1px solid #ddd; padding: 10px;">UDP</td>
<td style="border: 1px solid #ddd; padding: 10px;">IKE/ISAKMP — обмен ключами IKEv2</td>
<td style="border: 1px solid #ddd; padding: 10px;">Да</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">4500</td>
<td style="border: 1px solid #ddd; padding: 10px;">UDP</td>
<td style="border: 1px solid #ddd; padding: 10px;">IPsec NAT-T — туннель за NAT</td>
<td style="border: 1px solid #ddd; padding: 10px;">Да</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">22</td>
<td style="border: 1px solid #ddd; padding: 10px;">TCP</td>
<td style="border: 1px solid #ddd; padding: 10px;">SSH — управление сервером</td>
<td style="border: 1px solid #ddd; padding: 10px;">Да (ограничь по IP)</td>
</tr>
</tbody>
</table>
<h2>Архитектура решения</h2>
<pre class="mermaid">
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#ffffff',
'primaryTextColor': '#1e293b',
'primaryBorderColor': '#94a3b8',
'lineColor': '#64748b',
'fontSize': '15px',
'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
},
'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
A["Клиент Windows/iOS/Android/macOS"] -->|"IKE_SA_INIT UDP:500"| B["StrongSwan charon"]
B -->|"IKE_AUTH EAP-MSCHAPv2"| C["ipsec.secrets - проверка credentials"]
C -->|"OK"| D["IPsec SA - туннель ESP"]
D -->|"10.10.10.x/24"| E["IP-пул клиентов"]
E -->|"NAT MASQUERADE"| F["Интернет / корпоративная сеть"]
style A fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
style B fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style C fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style D fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style E fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
style F fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
</pre>
<h2>Причины почему IKEv2 может не работать после установки</h2>
<p>Перед тем как делать — пойми что ломается чаще всего. Сэкономишь час дебага.</p>
<ul>
<li><strong>Неверный CN/SAN в сертификате.</strong> Указал IP, клиент подключается по домену — не совпадает, отказ. Или наоборот. SAN обязателен — современные клиенты без него сертификат не примут.</li>
<li><strong>DEFAULT_FORWARD_POLICY=»DROP» в UFW.</strong> Классика. Клиент подключается, пинги до сервера идут, интернета нет. NAT работает, форвардинг заблокирован на уровне политики.</li>
<li><strong>Не включён IP forwarding в ядре.</strong> Без <code>net.ipv4.ip_forward=1</code> трафик между туннелем и внешней сетью не пойдёт даже при правильном UFW.</li>
<li><strong>Слабые или несовместимые алгоритмы шифрования.</strong> Конфиг с только <code>aes256-sha256-modp2048</code> отвалится на iOS или свежем macOS — они требуют современные DH-группы.</li>
<li><strong>Неверный сетевой интерфейс в правилах NAT.</strong> Хардкодишь <code>eth0</code>, а у тебя <code>ens3</code> или <code>enp3s0</code>. NAT не работает, трафик не идёт.</li>
<li><strong>CA-сертификат не импортирован на клиенте.</strong> <a href="https://it-apteka.com/ssh-kljuchi-podkljuchaemsja-bez-parolja-i-ne-panikuem/" title="SSH-ключи: подключение без пароля — полный гайд для Linux, Windows и macOS" target="_blank" rel="noopener" data-wpil-monitor-id="2740">Windows и macOS</a> требуют его в системном хранилище доверенных сертификатов.</li>
</ul>
<h2>Установка пакетов</h2>
<p>Обновляем систему и ставим всё что нужно:</p>
<pre><code class="language-bash">
sudo apt update && sudo apt upgrade -y
sudo apt install -y \
strongswan \
strongswan-pki \
libcharon-extra-plugins \
libcharon-extauth-plugins \
libstrongswan-extra-plugins
</code></pre>
<p>Зачем каждый пакет:</p>
<ul>
<li><code>strongswan-pki</code> — утилита <code>pki</code> для генерации CA и сертификатов</li>
<li><code>libcharon-extauth-plugins</code> — поддержка EAP-аутентификации (логин/пароль для клиентов)</li>
<li><code>libcharon-extra-plugins</code> — дополнительные протоколы, включая EAP-MSCHAPv2</li>
<li><code>libstrongswan-extra-plugins</code> — поддержка эллиптических кривых (Curve25519), нужна для современных cipher suites</li>
</ul>
<p>Проверяем установку:</p>
<pre><code class="language-bash">
ipsec version
</code></pre>
<p>Должно вернуть что-то вроде <code>Linux strongSwan 5.9.13</code>.</p>
<h2>Генерация PKI: сертификаты без которых никуда</h2>
<p>Создаём рабочую директорию и генерируем всю цепочку: CA → серверный сертификат.</p>
<pre><code class="language-bash">
mkdir -p ~/pki/{cacerts,certs,private}
chmod 700 ~/pki
cd ~/pki
</code></pre>
<p>Генерируем ключ и самоподписанный CA-сертификат:</p>
<pre><code class="language-bash">
# Приватный ключ CA
pki --gen --type rsa --size 4096 --outform pem > private/ca-key.pem
# CA-сертификат, действует 10 лет
pki --self --ca --lifetime 3650 \
--in private/ca-key.pem \
--type rsa \
--dn "CN=VPN Root CA" \
--outform pem > cacerts/ca-cert.pem
</code></pre>
<p>Теперь серверный ключ и сертификат. Замени <code>vpn.example.com</code> на свой домен или IP:</p>
<pre><code class="language-bash">
# Ключ сервера
pki --gen --type rsa --size 4096 --outform pem > private/server-key.pem
# Серверный сертификат - подписываем нашим CA
pki --pub --in private/server-key.pem --type rsa \
| pki --issue \
--lifetime 1825 \
--cacert cacerts/ca-cert.pem \
--cakey private/ca-key.pem \
--dn "CN=vpn.example.com" \
--san vpn.example.com \
--flag serverAuth \
--flag ikeIntermediate \
--outform pem > certs/server-cert.pem
</code></pre>
"Важно:
<br />
Параметр —san (Subject Alternative Name) — это не опция. Современные клиенты на iOS, <a href="https://it-apteka.com/punto-switcher-i-analogi-dlja-windows-macos-i-linux/" title="Punto Switcher и аналоги для Windows, macOS и Linux" target="_blank" rel="noopener" data-wpil-monitor-id="2743">macOS и Windows</a> 11 проверяют SAN, а не только CN. Без него увидишь "Certificate validation failed" и потратишь время на поиск причины. Если подключаешься по IP, а не домену — добавь и IP: —san @1.2.3.4 —san 1.2.3.4 (@ перед IP означает IP-адрес в формате SAN).<br />
<p>Копируем сертификаты в системные директории StrongSwan:</p>
<pre><code class="language-bash">
sudo cp cacerts/ca-cert.pem /etc/ipsec.d/cacerts/
sudo cp certs/server-cert.pem /etc/ipsec.d/certs/
sudo cp private/server-key.pem /etc/ipsec.d/private/
sudo chmod 600 /etc/ipsec.d/private/server-key.pem
</code></pre>
<h2>Настройка StrongSwan: конфиг ipsec.conf</h2>
<p>Бэкапим оригинал и пишем свой:</p>
<pre><code class="language-bash">
sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
sudo tee /etc/ipsec.conf > /dev/null << 'EOF'
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
mobike=yes
# Алгоритмы шифрования - современные + совместимые со старыми клиентами
ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha1-modp2048!
esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,aes128-sha1!
# Dead peer detection
dpdaction=clear
dpddelay=300s
rekey=no
# Сервер (левая сторона)
left=%any
leftid=@vpn.example.com
leftauth=pubkey
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
# Клиенты (правая сторона)
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
eap_identity=%identity
EOF
</code></pre>
<p>Три момента которые важны:</p>
<p><code>leftauth=pubkey</code> - обязательная директива. В оригинальных статьях её часто забывают. Без неё StrongSwan не знает как аутентифицировать серверную сторону.</p>
<p><code>mobike=yes</code> - включает MOBIKE (RFC 4555). Клиент переключается между Wi-Fi и мобильной сетью без разрыва VPN-сессии. Очень актуально для мобильных пользователей.</p>
<p>Набор алгоритмов в <code>ike=</code> - здесь есть и ChaCha20-Poly1305 для современных устройств, и классический AES-256 для совместимости со старыми клиентами. Без этого macOS или старый iOS может выдать "No proposal chosen".</p>
<h2>Добавление пользователей: ipsec.secrets</h2>
<pre><code class="language-bash">
sudo tee /etc/ipsec.secrets > /dev/null << 'EOF'
# Ключ сервера
: RSA "server-key.pem"
# Пользователи: username : EAP "password"
ivan : EAP "SecurePass2025!"
maria : EAP "AnotherPass456@"
EOF
sudo chmod 600 /etc/ipsec.secrets
</code></pre>
<p>Чтобы добавить пользователя без перезапуска сервиса - вставь строку и выполни:</p>
<pre><code class="language-bash">
sudo ipsec rereadsecrets
</code></pre>
<h2>Настройка UFW и NAT: три места где всё ломается</h2>
<p>Сначала определяем интерфейс. Не хардкоди eth0 - проверь:</p>
<pre><code class="language-bash">
ip route show default
# Смотри поле "dev": dev eth0, dev ens3, dev enp3s0 и т.д.
IFACE=$(ip route show default | awk '/default/ {print $5}')
echo "Интерфейс: $IFACE"
</code></pre>
<p>Включаем форвардинг на уровне ядра:</p>
<pre><code class="language-bash">
sudo tee -a /etc/sysctl.conf << 'EOF'
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
EOF
sudo sysctl -p
</code></pre>
<p>Теперь UFW. Вот тут три места где ошибаются:</p>
<p><strong>Место 1.</strong> Меняем политику форвардинга в <code>/etc/default/ufw</code>:</p>
<pre><code class="language-bash">
sudo sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
</code></pre>
<p><strong>Место 2.</strong> Добавляем NAT-правила в начало <code>/etc/ufw/before.rules</code> - строго до блока <code>*filter</code>:</p>
"Перед
<br />
Замени eth0 на свой интерфейс из команды выше. Это самая частая причина "подключился, интернета нет". Проверь переменную IFACE перед вставкой.<br />
<pre><code class="language-bash">
sudo tee /tmp/ufw-nat.txt << 'EOF'
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT
*mangle
:FORWARD ACCEPT [0:0]
-A FORWARD -m policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
EOF
# Вставляем перед первой строкой *filter
sudo sed -i '/*filter/e cat /tmp/ufw-nat.txt' /etc/ufw/before.rules
</code></pre>
<p>Либо - если sed с heredoc не нравится - открой файл вручную и вставь блок выше в начало, перед строкой <code>*filter</code>:</p>
<pre><code class="language-bash">
sudo nano /etc/ufw/before.rules
</code></pre>
<p><strong>Место 3.</strong> Добавляем разрешение форвардинга для VPN-подсети. В том же файле <code>/etc/ufw/before.rules</code>, внутри блока <code>*filter</code>, после строки <code>:ufw-before-forward</code>:</p>
<pre><code class="language-bash">
# Добавить в секцию *filter блока ufw-before-forward:
-A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT
</code></pre>
<p>Открываем порты и применяем:</p>
<pre><code class="language-bash">
sudo ufw allow 500/udp
sudo ufw allow 4500/udp
sudo ufw allow OpenSSH
sudo ufw disable && sudo ufw enable
</code></pre>
<h2>Запуск и проверка</h2>
<pre><code class="language-bash">
sudo systemctl restart strongswan-starter
sudo systemctl enable strongswan-starter
sudo systemctl status strongswan-starter
</code></pre>
<p>Проверяем что демон поднялся и конфиг загружен:</p>
<pre><code class="language-bash">
sudo ipsec status
sudo ipsec listconn
</code></pre>
<p>Вывод <code>ipsec listconn</code> должен показать <code>ikev2-vpn</code> в списке. Если соединений нет - это нормально до первого подключения клиента.</p>
<p>Проверяем форвардинг:</p>
<pre><code class="language-bash">
sysctl net.ipv4.ip_forward
# Ожидаем: net.ipv4.ip_forward = 1
</code></pre>
<p>Проверяем NAT:</p>
<pre><code class="language-bash">
sudo iptables -t nat -L POSTROUTING -v -n
# Должна быть строка с MASQUERADE и 10.10.10.0/24
</code></pre>
<h2>Подключение клиентов</h2>
<h3>Windows 10/11</h3>
<p>Сначала импортируй CA-сертификат. Без этого Windows выдаст ошибку проверки сертификата:</p>
<pre><code class="language-powershell">
# Запусти PowerShell от администратора
# Скопируй ca-cert.pem на машину и выполни:
Import-Certificate -FilePath "ca-cert.pem" -CertStoreLocation Cert:\LocalMachine\Root
</code></pre>
<p>Теперь добавляем VPN через <a class="wpil_keyword_link" href="https://it-apteka.com/tag/powershell/" target="_blank" rel="noopener" title="PowerShell" data-wpil-keyword-link="linked" data-wpil-monitor-id="2736">PowerShell</a> (быстрее чем через GUI):</p>
<pre><code class="language-powershell">
Add-VpnConnection -Name "Corporate VPN" `
-ServerAddress "vpn.example.com" `
-TunnelType IKEv2 `
-AuthenticationMethod EAP `
-EncryptionLevel Required `
-RememberCredential
</code></pre>
<p>Или через GUI: Параметры - Сеть и Интернет - VPN - Добавить VPN-подключение. Тип: IKEv2, адрес: <code>vpn.example.com</code>, тип входа: имя пользователя и пароль.</p>
"Windows:
<br />
Windows по умолчанию предлагает слабые алгоритмы. После добавления соединения выполни в PowerShell от администратора для принудительного использования AES-256:<br />
<pre><code class="language-powershell">
Set-VpnConnectionIPsecConfiguration -ConnectionName "Corporate VPN" `
-AuthenticationTransformConstants SHA256128 `
-CipherTransformConstants AES256 `
-DHGroup Group14 `
-EncryptionMethod AES256 `
-IntegrityCheckMethod SHA256 `
-PfsGroup None `
-Force
</code></pre>
<h3>iOS / iPadOS</h3>
<p>Настройки - Основные - VPN и управление устройством - VPN - Добавить конфигурацию VPN.</p>
<p>Заполняй:</p>
<ul>
<li>Тип: IKEv2</li>
<li>Описание: любое</li>
<li>Сервер: <code>vpn.example.com</code></li>
<li>Удалённый ID: <code>vpn.example.com</code></li>
<li>Локальный ID: оставить пустым</li>
<li>Аутентификация: имя пользователя</li>
<li>Имя пользователя и пароль: из <code>ipsec.secrets</code></li>
</ul>
<p>Если используешь самоподписанный CA - нужно установить его как профиль. Отправь <code>ca-cert.pem</code> по почте или положи на веб-сервер, открой на iPhone, установи через Настройки - Профиль загружен - Установить.</p>
<h3>Android</h3>
<p>Нативный клиент IKEv2 есть в Android 11+. <a href="https://it-apteka.com/10-oshibok-pri-nastrojke-domashnego-wi-fi-iz-za-kotoryh-tormozit-internet/" title="10 ошибок при настройке домашнего Wi-Fi, из-за которых тормозит интернет" target="_blank" rel="noopener" data-wpil-monitor-id="2744">Настройки - Сеть и интернет</a> - VPN - добавить.</p>
<p>На Android 12 и новее путь может отличаться в зависимости от оболочки. Тип соединения - IKEv2/IPSec MSCHAPv2 или IKEv2/IPSec PSK. Вводи адрес сервера, логин, пароль.</p>
<p>На старых версиях Android или если нативный клиент капризничает - официальное приложение StrongSwan из Play Store решает проблему. Там же импортируй CA-сертификат.</p>
<h3>macOS</h3>
<p>Системные настройки - Сеть - кнопка "+" - VPN - тип IKEv2.</p>
<p>Адрес сервера и удалённый ID: <code>vpn.example.com</code>. Аутентификация: имя пользователя. CA-сертификат импортируй в Keychain Access в категорию "Системные" с уровнем доверия "Всегда доверять".</p>
<p>macOS хорошо работает с IKEv2, но иногда требует принудительного указания DH-группы. Если не подключается - добавь в конфиг StrongSwan в строку <code>ike=</code> вариант <code>aes256gcm16-sha256-ecp256</code>.</p>
<h2>Осложнения: ошибки и как их чинить</h2>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<thead>
<tr style="background-color: #f2f2f2;">
<th style="border: 1px solid #ddd; padding: 10px;">Ошибка</th>
<th style="border: 1px solid #ddd; padding: 10px;">Причина</th>
<th style="border: 1px solid #ddd; padding: 10px;">Решение</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">Certificate validation failed</td>
<td style="border: 1px solid #ddd; padding: 10px;">CA не импортирован на <a href="https://it-apteka.com/nastrojka-ntp-na-mikrotik-klient-i-server-shpargalka-dlja-ros-6-i-7/" title="Настройка NTP MikroTik: клиент, сервер и всё что ломается без него" target="_blank" rel="noopener" data-wpil-monitor-id="2745">клиенте</a> или CN/SAN не совпадает с адресом сервера</td>
<td style="border: 1px solid #ddd; padding: 10px;">Импортируй ca-cert.pem в системное хранилище. Проверь что адрес в SAN совпадает с адресом подключения</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">No proposal chosen</td>
<td style="border: 1px solid #ddd; padding: 10px;">Клиент предлагает алгоритмы которых нет в конфиге сервера</td>
<td style="border: 1px solid #ddd; padding: 10px;">Добавь в ike= и esp= более широкий набор алгоритмов. Посмотри что предлагает клиент в логах: journalctl -fu strongswan-starter</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">Подключается, интернета нет</td>
<td style="border: 1px solid #ddd; padding: 10px;">Форвардинг или NAT не работает</td>
<td style="border: 1px solid #ddd; padding: 10px;">Проверь sysctl net.ipv4.ip_forward = 1. Проверь DEFAULT_FORWARD_POLICY=ACCEPT в /etc/default/ufw. Проверь правило MASQUERADE с правильным интерфейсом</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">Authentication failed</td>
<td style="border: 1px solid #ddd; padding: 10px;">Неверные credentials или не перечитан secrets</td>
<td style="border: 1px solid #ddd; padding: 10px;">Проверь /etc/ipsec.secrets, запусти ipsec rereadsecrets</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><a href="https://it-apteka.com/doh-server-connection-error-prichiny-i-reshenija-mikrotik-ssl-timeout/" title="DoH Server Connection Error: причины и решения (MikroTik, SSL, Timeout)" target="_blank" rel="noopener" data-wpil-monitor-id="2741">Connection reset / timeout</a></td>
<td style="border: 1px solid #ddd; padding: 10px;">Порты 500/udp или 4500/udp закрыты</td>
<td style="border: 1px solid #ddd; padding: 10px;">sudo ufw status. Проверь firewall на уровне хостера/облака - там может быть отдельный security group</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;">iOS не подключается после обновления</td>
<td style="border: 1px solid #ddd; padding: 10px;">Apple ужесточила требования к алгоритмам</td>
<td style="border: 1px solid #ddd; padding: 10px;">Добавь в ike= строку aes256gcm16-sha384-prfsha384-ecp384 - Apple предпочитает именно этот набор</td>
</tr>
</tbody>
</table>
<p>Главный инструмент диагностики - лог charon в реальном времени:</p>
<pre><code class="language-bash">
sudo journalctl -fu strongswan-starter
</code></pre>
<p>Смотри на IKE_SA_INIT и IKE_AUTH пакеты. По ним видно где именно обрывается рукопожатие.</p>
<h2>Альтернативы и когда их выбирать</h2>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<thead>
<tr style="background-color: #f2f2f2;">
<th style="border: 1px solid #ddd; padding: 10px;">Решение</th>
<th style="border: 1px solid #ddd; padding: 10px;">Плюсы</th>
<th style="border: 1px solid #ddd; padding: 10px;">Минусы</th>
<th style="border: 1px solid #ddd; padding: 10px;">Когда использовать</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>IKEv2 + StrongSwan</strong></td>
<td style="border: 1px solid #ddd; padding: 10px;">Нативные клиенты на всех ОС</td>
<td style="border: 1px solid #ddd; padding: 10px;">Нужна PKI</td>
<td style="border: 1px solid #ddd; padding: 10px;">Корпоративный VPN, смешанный парк устройств</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>WireGuard</strong></td>
<td style="border: 1px solid #ddd; padding: 10px;">Максимальная скорость, минимальный код</td>
<td style="border: 1px solid #ddd; padding: 10px;">Нужен клиент на каждой платформе</td>
<td style="border: 1px solid #ddd; padding: 10px;">IT-команды, разработчики, технари</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>OpenVPN</strong></td>
<td style="border: 1px solid #ddd; padding: 10px;">Гибкость, зрелость</td>
<td style="border: 1px solid #ddd; padding: 10px;">Клиент везде, сложная настройка</td>
<td style="border: 1px solid #ddd; padding: 10px;">Когда нужна нестандартная маршрутизация</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 10px;"><strong>L2TP/IPsec</strong></td>
<td style="border: 1px solid #ddd; padding: 10px;">Нативно везде, простая настройка с PSK</td>
<td style="border: 1px solid #ddd; padding: 10px;">Медленно, известные уязвимости в PSK</td>
<td style="border: 1px solid #ddd; padding: 10px;">Legacy-совместимость, последний вариант</td>
</tr>
</tbody>
</table>
<p>WireGuard быстрее IKEv2 - это факт. Но бухгалтер с iPhone не будет устанавливать приложение из App Store по твоей инструкции в 12 шагов. IKEv2 решает эту проблему на уровне ОС.</p>
<h2>Профилактика и безопасность</h2>
<h3>Мониторинг активных сессий</h3>
<pre><code class="language-bash">
# Активные Security Associations
sudo ipsec statusall
# Смотреть подключения в реальном времени
sudo journalctl -fu strongswan-starter | grep "IKE_SA"
</code></pre>
<h3>Ротация пользовательских паролей</h3>
<pre><code class="language-bash">
# Редактируем secrets
sudo nano /etc/ipsec.secrets
# Применяем без перезапуска
sudo ipsec rereadsecrets
</code></pre>
<h3>Обновление сертификатов</h3>
<p>Серверный сертификат выдан на 1825 дней (5 лет). Поставь напоминание. За 30 дней до истечения:</p>
<pre><code class="language-bash">
# Проверяем срок действия
openssl x509 -in /etc/ipsec.d/certs/server-cert.pem -noout -dates
</code></pre>
<p>Для продакшна - используй Let's Encrypt вместо самоподписанного CA. Тогда клиентам не нужно импортировать CA-сертификат, он уже в системном хранилище. Скрипт для этого: <a href="https://github.com/jawj/IKEv2-setup" rel="nofollow" target="_blank">jawj/IKEv2-setup</a>.</p>
<h3>Ограничение доступа по IP для SSH</h3>
<pre><code class="language-bash">
sudo ufw delete allow OpenSSH
sudo ufw allow from 1.2.3.4 to any port 22
</code></pre>
<h3>Автоматический запуск</h3>
<pre><code class="language-bash">
sudo systemctl enable strongswan-starter
</code></pre>
<p>Проверь что в <code>/etc/ipsec.conf</code> стоит <code>auto=add</code>, а не <code>auto=start</code>. С <code>auto=add</code> сервер ждёт входящих подключений. С <code>auto=start</code> будет пытаться сам инициировать туннель, что для road warrior-конфигурации не нужно.</p>
<h2>Резервное копирование</h2>
<p>Что бэкапить:</p>
<ul>
<li><code>/etc/ipsec.conf</code> - конфигурация</li>
<li><code>/etc/ipsec.secrets</code> - учётные данные пользователей</li>
<li><code>/etc/ipsec.d/</code> - вся PKI (сертификаты и ключи)</li>
<li><code>/etc/ufw/before.rules</code> - NAT-правила</li>
</ul>
<pre><code class="language-bash">
# Архив всего необходимого
sudo tar -czf vpn-backup-$(date +%Y%m%d).tar.gz \
/etc/ipsec.conf \
/etc/ipsec.secrets \
/etc/ipsec.d/ \
/etc/ufw/before.rules
# Храни ключи CA в надёжном месте - без них не восстановишь PKI
</code></pre>
<p>Особенно береги <code>private/ca-key.pem</code>. Это корень доверия всей твоей инфраструктуры. Потеряешь - придётся перевыпускать все сертификаты и переконфигурировать клиентов.</p>
<h2>FAQ</h2>
<h3>Почему IKEv2 VPN не подключается после настройки?</h3>
<p>Четыре самые частые причины: несовпадение CN/SAN в сертификате с адресом сервера, CA-сертификат не импортирован на клиенте, закрытые порты 500/udp или 4500/udp, неверный пароль в <code>ipsec.secrets</code>. Смотри лог: <code>sudo journalctl -fu strongswan-starter</code> во время попытки подключения - там будет конкретная причина.</p>
<h3>Как проверить что StrongSwan VPN работает правильно?</h3>
<p>После подключения клиента выполни <code>sudo ipsec statusall</code>. Должна появиться активная Security Association. Клиент должен получить IP из пула 10.10.10.0/24. Проверь <code>ip addr</code> на клиенте и пингани 8.8.8.8 через туннель. Если пинг идёт, <a class="wpil_keyword_link" href="https://it-apteka.com/tag/dns/" target="_blank" rel="noopener" title="DNS" data-wpil-keyword-link="linked" data-wpil-monitor-id="2734">DNS</a> разрешает имена - всё работает.</p>
<h3>Что делать если пишет No proposal chosen?</h3>
<p>Это несовпадение алгоритмов между <a href="https://it-apteka.com/vpn-na-mikrotik-polnyj-gajd-2026-wireguard-l2tp-ipsec-ikev2-nastrojka-servera-i-klienta/" title="VPN на MikroTik: полный гайд 2026 — WireGuard, L2TP/IPsec, IKEv2, настройка сервера и клиента" target="_blank" rel="noopener" data-wpil-monitor-id="2742">клиентом и сервером</a>. Смотри в логе какие алгоритмы предлагает клиент. Расшири список в <code>ike=</code> и <code>esp=</code> в <code>/etc/ipsec.conf</code>. Для старых Windows-клиентов добавь <code>aes256-sha1-modp1024</code>. Для macOS - <code>aes256gcm16-sha256-ecp256</code>. После изменения: <code>sudo ipsec reload</code>.</p>
<h3>Чем IKEv2 отличается от OpenVPN для корпоративного VPN?</h3>
<p>IKEv2 встроен в ОС - не нужен клиент. OpenVPN требует установки приложения на каждое устройство. IKEv2 работает на уровне ядра, чуть быстрее OpenVPN в userspace. OpenVPN гибче в маршрутизации и работает через 443/tcp там где UDP заблокирован. Для корпоративного VPN с обычными пользователями IKEv2 выигрывает по удобству развёртывания.</p>
<h3>Как удалить пользователя из VPN?</h3>
<p>Удали или закомментируй строку в <code>/etc/ipsec.secrets</code> и выполни <code>sudo ipsec rereadsecrets</code>. Активную сессию пользователя разорви: <code>sudo ipsec down ikev2-vpn[имя_сессии]</code>. Имя сессии видно в выводе <code>ipsec statusall</code>.</p>
<h3>Можно ли использовать IKEv2 VPN через 443 порт?</h3>
<p>Нет. IKEv2 работает на UDP:500 и UDP:4500 - это фиксированные порты стандарта. Если UDP заблокирован у пользователя, IKEv2 не поможет. В таком случае нужен OpenVPN на TCP:443 как fallback.</p>
<h2>Итог</h2>
<p>Сервер поднят. Клиенты подключаются нативно с Windows, iOS, Android и macOS. Никаких инструкций «установите приложение», никаких тикетов «у меня не работает».</p>
<p>Один нюанс на будущее: раз в год проверяй срок действия серверного сертификата. Когда он истечёт, все клиенты перестанут подключаться одновременно, в пятницу вечером. Murphy's law - это не теория, это производственный стандарт.</p>
<p>Если что-то не поднялось - пиши в комментарии. Разберёмся.</p>
Быстрый ответ
IKEv2/IPsec через StrongSwan — единственный протокол с нативной поддержкой на Windows 10/11, iOS, Android и macOS одновременно. Никаких сторонних приложений.
Что нужно для запуска:
- Ubuntu 24.04 с белым IP
- Открытые порты 500/udp и 4500/udp
- Домен или статический IP для CN сертификата
- Около 30 минут времени
Порядок: установка пакетов → генерация PKI → конфиг strongswan → UFW + NAT → проверка → подключение клиентов.
Диагноз: почему именно IKEv2
Тебе нужен корпоративный VPN. Пользователи — люди с айфонами, андроидами, рабочими ноутами на Windows. Ты поднял OpenVPN. Теперь пишешь инструкции «как установить клиент», отвечаешь на вопросы в чате и объясняешь бухгалтерии что такое tun-адаптер. Знакомо?
Настройка IKEv2 VPN сервера на Ubuntu решает эту проблему. IKEv2 встроен во все мажорные ОС — Windows 10+, iOS 9.1+, Android 11+, macOS 10.11+. Пользователь заходит в системные настройки, добавляет VPN, вводит логин и пароль. Всё.
Что получишь в итоге:
- VPN сервер с EAP-аутентификацией по логину/паролю
- Нативное подключение с любой платформы без сторонних приложений
- AES-256-GCM + ChaCha20 — современные алгоритмы шифрования
- Автовосстановление соединения через MOBIKE при смене сети
Уйдёт 25-35 минут. Нужен root или sudo на сервере.
Матрица совместимости: что работает без клиента
Перед тем как разворачивать — смотри реальность:
| Протокол |
Windows 10/11 |
iOS 17+ |
Android 11+ |
macOS 12+ |
| IKEv2/IPsec |
Нативно |
Нативно |
Нативно |
Нативно |
| L2TP/IPsec |
Нативно |
Нативно |
Нативно |
Нативно |
| PPTP |
Устарел |
Удалён в iOS 10 |
Устарел |
Удалён |
| SSTP |
Нативно |
Нет |
Нет |
Нет |
| OpenVPN |
Нужен клиент |
Нужен клиент |
Нужен клиент |
Нужен клиент |
| WireGuard |
Нужен клиент |
Нужен клиент |
Нужен клиент |
Нужен клиент |
L2TP тоже везде есть, но медленнее и содержит известные уязвимости в реализациях PSK. IKEv2 — единственный правильный выбор для 2025 года, если нужен нативный клиент без вопросов от пользователей.
Системные требования
| Параметр |
Минимум |
Рекомендуется |
| ОС |
Ubuntu 22.04 LTS |
Ubuntu 24.04 LTS |
| StrongSwan |
5.9.x |
5.9.13+ (из репо Ubuntu 24.04) |
| RAM |
512 MB |
1 GB+ |
| IP |
Статический публичный IP |
IP + домен (для Let’s Encrypt) |
| Порты |
500/udp, 4500/udp |
500/udp, 4500/udp, 22/tcp |
На момент публикации актуальна StrongSwan 5.9.13. Перед установкой проверь актуальную версию в репозитории: apt-cache policy strongswan.
Таблица портов
| Порт |
Протокол |
Назначение |
Снаружи |
| 500 |
UDP |
IKE/ISAKMP — обмен ключами IKEv2 |
Да |
| 4500 |
UDP |
IPsec NAT-T — туннель за NAT |
Да |
| 22 |
TCP |
SSH — управление сервером |
Да (ограничь по IP) |
Архитектура решения
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#ffffff',
'primaryTextColor': '#1e293b',
'primaryBorderColor': '#94a3b8',
'lineColor': '#64748b',
'fontSize': '15px',
'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
},
'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
A["Клиент Windows/iOS/Android/macOS"] -->|"IKE_SA_INIT UDP:500"| B["StrongSwan charon"]
B -->|"IKE_AUTH EAP-MSCHAPv2"| C["ipsec.secrets - проверка credentials"]
C -->|"OK"| D["IPsec SA - туннель ESP"]
D -->|"10.10.10.x/24"| E["IP-пул клиентов"]
E -->|"NAT MASQUERADE"| F["Интернет / корпоративная сеть"]
style A fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
style B fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style C fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style D fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
style E fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
style F fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
Причины почему IKEv2 может не работать после установки
Перед тем как делать — пойми что ломается чаще всего. Сэкономишь час дебага.
- Неверный CN/SAN в сертификате. Указал IP, клиент подключается по домену — не совпадает, отказ. Или наоборот. SAN обязателен — современные клиенты без него сертификат не примут.
- DEFAULT_FORWARD_POLICY=»DROP» в UFW. Классика. Клиент подключается, пинги до сервера идут, интернета нет. NAT работает, форвардинг заблокирован на уровне политики.
- Не включён IP forwarding в ядре. Без
net.ipv4.ip_forward=1 трафик между туннелем и внешней сетью не пойдёт даже при правильном UFW.
- Слабые или несовместимые алгоритмы шифрования. Конфиг с только
aes256-sha256-modp2048 отвалится на iOS или свежем macOS — они требуют современные DH-группы.
- Неверный сетевой интерфейс в правилах NAT. Хардкодишь
eth0, а у тебя ens3 или enp3s0. NAT не работает, трафик не идёт.
- CA-сертификат не импортирован на клиенте. Windows и macOS требуют его в системном хранилище доверенных сертификатов.
Установка пакетов
Обновляем систему и ставим всё что нужно:
sudo apt update && sudo apt upgrade -y
sudo apt install -y \
strongswan \
strongswan-pki \
libcharon-extra-plugins \
libcharon-extauth-plugins \
libstrongswan-extra-plugins
Зачем каждый пакет:
strongswan-pki — утилита pki для генерации CA и сертификатов
libcharon-extauth-plugins — поддержка EAP-аутентификации (логин/пароль для клиентов)
libcharon-extra-plugins — дополнительные протоколы, включая EAP-MSCHAPv2
libstrongswan-extra-plugins — поддержка эллиптических кривых (Curve25519), нужна для современных cipher suites
Проверяем установку:
ipsec version
Должно вернуть что-то вроде Linux strongSwan 5.9.13.
Генерация PKI: сертификаты без которых никуда
Создаём рабочую директорию и генерируем всю цепочку: CA → серверный сертификат.
mkdir -p ~/pki/{cacerts,certs,private}
chmod 700 ~/pki
cd ~/pki
Генерируем ключ и самоподписанный CA-сертификат:
# Приватный ключ CA
pki --gen --type rsa --size 4096 --outform pem > private/ca-key.pem
# CA-сертификат, действует 10 лет
pki --self --ca --lifetime 3650 \
--in private/ca-key.pem \
--type rsa \
--dn "CN=VPN Root CA" \
--outform pem > cacerts/ca-cert.pem
Теперь серверный ключ и сертификат. Замени vpn.example.com на свой домен или IP:
# Ключ сервера
pki --gen --type rsa --size 4096 --outform pem > private/server-key.pem
# Серверный сертификат - подписываем нашим CA
pki --pub --in private/server-key.pem --type rsa \
| pki --issue \
--lifetime 1825 \
--cacert cacerts/ca-cert.pem \
--cakey private/ca-key.pem \
--dn "CN=vpn.example.com" \
--san vpn.example.com \
--flag serverAuth \
--flag ikeIntermediate \
--outform pem > certs/server-cert.pem
Важно: SAN обязателен
Параметр —san (Subject Alternative Name) — это не опция. Современные клиенты на iOS,
macOS и Windows 11 проверяют SAN, а не только CN. Без него увидишь «Certificate validation failed» и потратишь время на поиск причины. Если подключаешься по IP, а не домену — добавь и IP: —san @1.2.3.4 —san 1.2.3.4 (@ перед IP означает IP-адрес в формате SAN).
Копируем сертификаты в системные директории StrongSwan:
sudo cp cacerts/ca-cert.pem /etc/ipsec.d/cacerts/
sudo cp certs/server-cert.pem /etc/ipsec.d/certs/
sudo cp private/server-key.pem /etc/ipsec.d/private/
sudo chmod 600 /etc/ipsec.d/private/server-key.pem
Настройка StrongSwan: конфиг ipsec.conf
Бэкапим оригинал и пишем свой:
sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
sudo tee /etc/ipsec.conf > /dev/null << 'EOF'
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
mobike=yes
# Алгоритмы шифрования - современные + совместимые со старыми клиентами
ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha1-modp2048!
esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,aes128-sha1!
# Dead peer detection
dpdaction=clear
dpddelay=300s
rekey=no
# Сервер (левая сторона)
left=%any
leftid=@vpn.example.com
leftauth=pubkey
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
# Клиенты (правая сторона)
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
eap_identity=%identity
EOF
Три момента которые важны:
leftauth=pubkey - обязательная директива. В оригинальных статьях её часто забывают. Без неё StrongSwan не знает как аутентифицировать серверную сторону.
mobike=yes - включает MOBIKE (RFC 4555). Клиент переключается между Wi-Fi и мобильной сетью без разрыва VPN-сессии. Очень актуально для мобильных пользователей.
Набор алгоритмов в ike= - здесь есть и ChaCha20-Poly1305 для современных устройств, и классический AES-256 для совместимости со старыми клиентами. Без этого macOS или старый iOS может выдать "No proposal chosen".
Добавление пользователей: ipsec.secrets
sudo tee /etc/ipsec.secrets > /dev/null << 'EOF'
# Ключ сервера
: RSA "server-key.pem"
# Пользователи: username : EAP "password"
ivan : EAP "SecurePass2025!"
maria : EAP "AnotherPass456@"
EOF
sudo chmod 600 /etc/ipsec.secrets
Чтобы добавить пользователя без перезапуска сервиса - вставь строку и выполни:
sudo ipsec rereadsecrets
Настройка UFW и NAT: три места где всё ломается
Сначала определяем интерфейс. Не хардкоди eth0 - проверь:
ip route show default
# Смотри поле "dev": dev eth0, dev ens3, dev enp3s0 и т.д.
IFACE=$(ip route show default | awk '/default/ {print $5}')
echo "Интерфейс: $IFACE"
Включаем форвардинг на уровне ядра:
sudo tee -a /etc/sysctl.conf << 'EOF'
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
EOF
sudo sysctl -p
Теперь UFW. Вот тут три места где ошибаются:
Место 1. Меняем политику форвардинга в /etc/default/ufw:
sudo sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
Место 2. Добавляем NAT-правила в начало /etc/ufw/before.rules - строго до блока *filter:
Перед редактированием
Замени eth0 на свой интерфейс из команды выше. Это самая частая причина «подключился, интернета нет». Проверь переменную IFACE перед вставкой.
sudo tee /tmp/ufw-nat.txt << 'EOF'
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT
*mangle
:FORWARD ACCEPT [0:0]
-A FORWARD -m policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
EOF
# Вставляем перед первой строкой *filter
sudo sed -i '/*filter/e cat /tmp/ufw-nat.txt' /etc/ufw/before.rules
Либо - если sed с heredoc не нравится - открой файл вручную и вставь блок выше в начало, перед строкой *filter:
sudo nano /etc/ufw/before.rules
Место 3. Добавляем разрешение форвардинга для VPN-подсети. В том же файле /etc/ufw/before.rules, внутри блока *filter, после строки :ufw-before-forward:
# Добавить в секцию *filter блока ufw-before-forward:
-A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT
Открываем порты и применяем:
sudo ufw allow 500/udp
sudo ufw allow 4500/udp
sudo ufw allow OpenSSH
sudo ufw disable && sudo ufw enable
Запуск и проверка
sudo systemctl restart strongswan-starter
sudo systemctl enable strongswan-starter
sudo systemctl status strongswan-starter
Проверяем что демон поднялся и конфиг загружен:
sudo ipsec status
sudo ipsec listconn
Вывод ipsec listconn должен показать ikev2-vpn в списке. Если соединений нет - это нормально до первого подключения клиента.
Проверяем форвардинг:
sysctl net.ipv4.ip_forward
# Ожидаем: net.ipv4.ip_forward = 1
Проверяем NAT:
sudo iptables -t nat -L POSTROUTING -v -n
# Должна быть строка с MASQUERADE и 10.10.10.0/24
Подключение клиентов
Windows 10/11
Сначала импортируй CA-сертификат. Без этого Windows выдаст ошибку проверки сертификата:
# Запусти PowerShell от администратора
# Скопируй ca-cert.pem на машину и выполни:
Import-Certificate -FilePath "ca-cert.pem" -CertStoreLocation Cert:\LocalMachine\Root
Теперь добавляем VPN через PowerShell (быстрее чем через GUI):
Add-VpnConnection -Name "Corporate VPN" `
-ServerAddress "vpn.example.com" `
-TunnelType IKEv2 `
-AuthenticationMethod EAP `
-EncryptionLevel Required `
-RememberCredential
Или через GUI: Параметры - Сеть и Интернет - VPN - Добавить VPN-подключение. Тип: IKEv2, адрес: vpn.example.com, тип входа: имя пользователя и пароль.
Windows: дополнительно усиливаем шифрование
Windows по умолчанию предлагает слабые алгоритмы. После добавления соединения выполни в PowerShell от администратора для принудительного использования AES-256:
Set-VpnConnectionIPsecConfiguration -ConnectionName "Corporate VPN" `
-AuthenticationTransformConstants SHA256128 `
-CipherTransformConstants AES256 `
-DHGroup Group14 `
-EncryptionMethod AES256 `
-IntegrityCheckMethod SHA256 `
-PfsGroup None `
-Force
iOS / iPadOS
Настройки - Основные - VPN и управление устройством - VPN - Добавить конфигурацию VPN.
Заполняй:
- Тип: IKEv2
- Описание: любое
- Сервер:
vpn.example.com
- Удалённый ID:
vpn.example.com
- Локальный ID: оставить пустым
- Аутентификация: имя пользователя
- Имя пользователя и пароль: из
ipsec.secrets
Если используешь самоподписанный CA - нужно установить его как профиль. Отправь ca-cert.pem по почте или положи на веб-сервер, открой на iPhone, установи через Настройки - Профиль загружен - Установить.
Android
Нативный клиент IKEv2 есть в Android 11+. Настройки - Сеть и интернет - VPN - добавить.
На Android 12 и новее путь может отличаться в зависимости от оболочки. Тип соединения - IKEv2/IPSec MSCHAPv2 или IKEv2/IPSec PSK. Вводи адрес сервера, логин, пароль.
На старых версиях Android или если нативный клиент капризничает - официальное приложение StrongSwan из Play Store решает проблему. Там же импортируй CA-сертификат.
macOS
Системные настройки - Сеть - кнопка "+" - VPN - тип IKEv2.
Адрес сервера и удалённый ID: vpn.example.com. Аутентификация: имя пользователя. CA-сертификат импортируй в Keychain Access в категорию "Системные" с уровнем доверия "Всегда доверять".
macOS хорошо работает с IKEv2, но иногда требует принудительного указания DH-группы. Если не подключается - добавь в конфиг StrongSwan в строку ike= вариант aes256gcm16-sha256-ecp256.
Осложнения: ошибки и как их чинить
| Ошибка |
Причина |
Решение |
| Certificate validation failed |
CA не импортирован на клиенте или CN/SAN не совпадает с адресом сервера |
Импортируй ca-cert.pem в системное хранилище. Проверь что адрес в SAN совпадает с адресом подключения |
| No proposal chosen |
Клиент предлагает алгоритмы которых нет в конфиге сервера |
Добавь в ike= и esp= более широкий набор алгоритмов. Посмотри что предлагает клиент в логах: journalctl -fu strongswan-starter |
| Подключается, интернета нет |
Форвардинг или NAT не работает |
Проверь sysctl net.ipv4.ip_forward = 1. Проверь DEFAULT_FORWARD_POLICY=ACCEPT в /etc/default/ufw. Проверь правило MASQUERADE с правильным интерфейсом |
| Authentication failed |
Неверные credentials или не перечитан secrets |
Проверь /etc/ipsec.secrets, запусти ipsec rereadsecrets |
| Connection reset / timeout |
Порты 500/udp или 4500/udp закрыты |
sudo ufw status. Проверь firewall на уровне хостера/облака - там может быть отдельный security group |
| iOS не подключается после обновления |
Apple ужесточила требования к алгоритмам |
Добавь в ike= строку aes256gcm16-sha384-prfsha384-ecp384 - Apple предпочитает именно этот набор |
Главный инструмент диагностики - лог charon в реальном времени:
sudo journalctl -fu strongswan-starter
Смотри на IKE_SA_INIT и IKE_AUTH пакеты. По ним видно где именно обрывается рукопожатие.
Альтернативы и когда их выбирать
| Решение |
Плюсы |
Минусы |
Когда использовать |
| IKEv2 + StrongSwan |
Нативные клиенты на всех ОС |
Нужна PKI |
Корпоративный VPN, смешанный парк устройств |
| WireGuard |
Максимальная скорость, минимальный код |
Нужен клиент на каждой платформе |
IT-команды, разработчики, технари |
| OpenVPN |
Гибкость, зрелость |
Клиент везде, сложная настройка |
Когда нужна нестандартная маршрутизация |
| L2TP/IPsec |
Нативно везде, простая настройка с PSK |
Медленно, известные уязвимости в PSK |
Legacy-совместимость, последний вариант |
WireGuard быстрее IKEv2 - это факт. Но бухгалтер с iPhone не будет устанавливать приложение из App Store по твоей инструкции в 12 шагов. IKEv2 решает эту проблему на уровне ОС.
Профилактика и безопасность
Мониторинг активных сессий
# Активные Security Associations
sudo ipsec statusall
# Смотреть подключения в реальном времени
sudo journalctl -fu strongswan-starter | grep "IKE_SA"
Ротация пользовательских паролей
# Редактируем secrets
sudo nano /etc/ipsec.secrets
# Применяем без перезапуска
sudo ipsec rereadsecrets
Обновление сертификатов
Серверный сертификат выдан на 1825 дней (5 лет). Поставь напоминание. За 30 дней до истечения:
# Проверяем срок действия
openssl x509 -in /etc/ipsec.d/certs/server-cert.pem -noout -dates
Для продакшна - используй Let's Encrypt вместо самоподписанного CA. Тогда клиентам не нужно импортировать CA-сертификат, он уже в системном хранилище. Скрипт для этого: jawj/IKEv2-setup.
Ограничение доступа по IP для SSH
sudo ufw delete allow OpenSSH
sudo ufw allow from 1.2.3.4 to any port 22
Автоматический запуск
sudo systemctl enable strongswan-starter
Проверь что в /etc/ipsec.conf стоит auto=add, а не auto=start. С auto=add сервер ждёт входящих подключений. С auto=start будет пытаться сам инициировать туннель, что для road warrior-конфигурации не нужно.
Резервное копирование
Что бэкапить:
/etc/ipsec.conf - конфигурация
/etc/ipsec.secrets - учётные данные пользователей
/etc/ipsec.d/ - вся PKI (сертификаты и ключи)
/etc/ufw/before.rules - NAT-правила
# Архив всего необходимого
sudo tar -czf vpn-backup-$(date +%Y%m%d).tar.gz \
/etc/ipsec.conf \
/etc/ipsec.secrets \
/etc/ipsec.d/ \
/etc/ufw/before.rules
# Храни ключи CA в надёжном месте - без них не восстановишь PKI
Особенно береги private/ca-key.pem. Это корень доверия всей твоей инфраструктуры. Потеряешь - придётся перевыпускать все сертификаты и переконфигурировать клиентов.
FAQ
Почему IKEv2 VPN не подключается после настройки?
Четыре самые частые причины: несовпадение CN/SAN в сертификате с адресом сервера, CA-сертификат не импортирован на клиенте, закрытые порты 500/udp или 4500/udp, неверный пароль в ipsec.secrets. Смотри лог: sudo journalctl -fu strongswan-starter во время попытки подключения - там будет конкретная причина.
Как проверить что StrongSwan VPN работает правильно?
После подключения клиента выполни sudo ipsec statusall. Должна появиться активная Security Association. Клиент должен получить IP из пула 10.10.10.0/24. Проверь ip addr на клиенте и пингани 8.8.8.8 через туннель. Если пинг идёт, DNS разрешает имена - всё работает.
Что делать если пишет No proposal chosen?
Это несовпадение алгоритмов между клиентом и сервером. Смотри в логе какие алгоритмы предлагает клиент. Расшири список в ike= и esp= в /etc/ipsec.conf. Для старых Windows-клиентов добавь aes256-sha1-modp1024. Для macOS - aes256gcm16-sha256-ecp256. После изменения: sudo ipsec reload.
Чем IKEv2 отличается от OpenVPN для корпоративного VPN?
IKEv2 встроен в ОС - не нужен клиент. OpenVPN требует установки приложения на каждое устройство. IKEv2 работает на уровне ядра, чуть быстрее OpenVPN в userspace. OpenVPN гибче в маршрутизации и работает через 443/tcp там где UDP заблокирован. Для корпоративного VPN с обычными пользователями IKEv2 выигрывает по удобству развёртывания.
Как удалить пользователя из VPN?
Удали или закомментируй строку в /etc/ipsec.secrets и выполни sudo ipsec rereadsecrets. Активную сессию пользователя разорви: sudo ipsec down ikev2-vpn[имя_сессии]. Имя сессии видно в выводе ipsec statusall.
Можно ли использовать IKEv2 VPN через 443 порт?
Нет. IKEv2 работает на UDP:500 и UDP:4500 - это фиксированные порты стандарта. Если UDP заблокирован у пользователя, IKEv2 не поможет. В таком случае нужен OpenVPN на TCP:443 как fallback.
Итог
Сервер поднят. Клиенты подключаются нативно с Windows, iOS, Android и macOS. Никаких инструкций «установите приложение», никаких тикетов «у меня не работает».
Один нюанс на будущее: раз в год проверяй срок действия серверного сертификата. Когда он истечёт, все клиенты перестанут подключаться одновременно, в пятницу вечером. Murphy's law - это не теория, это производственный стандарт.
Если что-то не поднялось - пиши в комментарии. Разберёмся.