SSL/TLS-сертификаты — основа маскировки VPN. Без них нет доверия, нет маскировки под HTTPS. Let's Encrypt — бесплатно, self-signed — для теста.
| Тип | Цена | Доверие | Для чего |
|---|---|---|---|
| Let's Encrypt | Бесплатно | ✅ Все браузеры | Production, маскировка VPN |
| Self-signed | Бесплатно | ❌ Предупреждение | Тест, внутренние сервисы |
| Платный CA | $10-200/год | ✅ Все браузеры | Коммерция, EV-сертификаты |
| Cloudflare Origin | Бесплатно | ✅ Через Cloudflare | Если сайт за Cloudflare |
sudo apt update
sudo apt install -y certbot
sudo certbot certonly --standalone -d your-domain.com
Certbot сам поднимает временный сервер на 80 порту. Nginx/Apache должны быть остановлены.
sudo certbot certonly --webroot -w /var/www/html -d your-domain.com
Nginx должен отдавать файлы из
/var/www/html/.well-known/acme-challenge/.
sudo apt install -y python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
sudo certbot certonly --manual --preferred-challenges dns -d your-domain.com -d *.your-domain.com
Добавьте TXT-запись в DNS, которую покажет Certbot.
/etc/letsencrypt/live/your-domain.com/
├── fullchain.pem # сертификат + цепочка (использовать для server-cert)
├── privkey.pem # приватный ключ (использовать для server-key)
├── cert.pem # только сертификат
└── chain.pem # только цепочка CA
# Тест обновления
sudo certbot renew --dry-run
# Cron (проверка каждый день в 3:00)
sudo crontab -e
0 3 * * * certbot renew --quiet --post-hook "systemctl restart nginx trojan xray"
--post-hookперезапускает сервисы после обновления сертификатов.
# Срок действия
sudo openssl x509 -in /etc/letsencrypt/live/your-domain.com/fullchain.pem -noout -dates
# Информация о сертификате
sudo openssl x509 -in /etc/letsencrypt/live/your-domain.com/fullchain.pem -noout -text | head -20
# Тест через curl
curl -vI https://your-domain.com 2>&1 | grep -E "expire|subject|issuer"
Для теста или внутренних сервисов (не для маскировки — браузер будет предупреждать).
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/private/selfsigned.key \
-out /etc/ssl/certs/selfsigned.crt \
-subj "/C=UA/ST=KV/L=Kiev/O=MyVPN/CN=your-domain.com"
sudo nano /tmp/san.cnf
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = UA
ST = KV
L = Kiev
O = MyVPN
CN = your-domain.com
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = your-domain.com
DNS.2 = www.your-domain.com
DNS.3 = vpn.your-domain.com
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/private/selfsigned.key \
-out /etc/ssl/certs/selfsigned.crt \
-config /tmp/san.cnf
{
"ssl": {
"cert": "/etc/ssl/certs/selfsigned.crt",
"key": "/etc/ssl/private/selfsigned.key"
}
}
⚠️ Self-signed не подходит для маскировки! DPI увидит что сертификат не от доверенного CA.
Если сайт за Cloudflare — бесплатный Origin-сертификат (на 15 лет).
cert.pem и key.pem на серверsudo nano /etc/ssl/private/cloudflare-origin.key
# Вставить ключ
sudo nano /etc/ssl/certs/cloudflare-origin.crt
# Вставить сертификат
ssl_certificate /etc/ssl/certs/cloudflare-origin.crt;
ssl_certificate_key /etc/ssl/private/cloudflare-origin.key;
⚠️ Cloudflare Origin работает только если трафик идёт через Cloudflare (оранжевое облако в DNS). Для VPN-сервера с прямыми подключениями — использовать Let's Encrypt.
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request.uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Настройки SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Сайт
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
sudo nginx -t
sudo systemctl reload nginx
# Проверка срока
echo | openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -dates
# Проверка цепочки
echo | openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -text | grep -E "Issuer|Subject|Not After"
# Проверка через curl
curl -vI https://your-domain.com 2>&1 | grep -E "SSL|expire|issuer|subject"
sudo certbot certificates
sudo certbot delete --cert-name your-domain.com
sudo certbot revoke --cert-path /etc/letsencrypt/live/your-domain.com/fullchain.pem
{
"ssl": {
"cert": "/etc/letsencrypt/live/your-domain.com/fullchain.pem",
"key": "/etc/letsencrypt/live/your-domain.com/privkey.pem"
}
}
Reality не требует SSL-сертификат — он использует чужой (microsoft.com).
tls:
cert: /etc/letsencrypt/live/your-domain.com/fullchain.pem
key: /etc/letsencrypt/live/your-domain.com/privkey.pem
ca /etc/letsencrypt/live/your-domain.com/fullchain.pem
cert /etc/letsencrypt/live/your-domain.com/cert.pem
key /etc/letsencrypt/live/your-domain.com/privkey.pem
leftcert=server.pem
# Файлы в /etc/ipsec.d/certs/ и /etc/ipsec.d/private/
→ Порт 80 занят. Остановите Nginx: sudo systemctl stop nginx, или используйте webroot/DNS challenge.
→ Домен не указывает на сервер. Проверьте A-запись: dig your-domain.com A.
→ Проверьте cron, проверьте что порт 80 или webroot доступны.
→ Self-signed сертификат, или истёк Let's Encrypt, или неправильная цепочка. Проверьте fullchain.pem (не cert.pem).
Последнее обновление: 2026-07-18