- Бесплатный HTTPS на VPS получают связкой nginx и certbot: пакеты
certbotиpython3-certbot-nginxиз apt, затем командаsudo certbot --nginx -d example.com -d www.example.com. - Nginx работает как reverse proxy: принимает запросы на портах 80 и 443 и через
proxy_passпередаёт их приложению на127.0.0.1:порт, так что само приложение не торчит в интернет. - Сертификат Let's Encrypt действует 90 дней, а пакет certbot ставит таймер systemd, который продлевает его автоматически; проверка продления -
sudo certbot renew --dry-run. - Certbot получит сертификат, только если домен уже указывает на IP сервера и порт 80 открыт снаружи: в UFW это правило
sudo ufw allow 'Nginx Full'.
Шаг 1. Установите nginx
Nginx есть в стандартных репозиториях Ubuntu и Debian. После установки служба сразу запускается и включается в автозапуск - статус должен быть active (running):
sudo apt update
sudo apt install -y nginx
systemctl status nginx --no-pagerШаг 2. Откройте порты 80 и 443 в UFW
Порт 80 нужен для проверки домена Let's Encrypt и редиректа, 443 - для самого HTTPS. Профиль Nginx Full открывает оба:
sudo ufw allow 'Nginx Full'
sudo ufw statusЕсли UFW ответит, что профиля с таким именем нет (так бывает на Debian), откройте порты напрямую: sudo ufw allow 80,443/tcp. Правило для SSH при этом должно остаться - проверьте его в выводе ufw status.
Шаг 3. Создайте server block для домена
Server block - это описание одного сайта в nginx. Создайте файл /etc/nginx/sites-available/example.com (например, sudo nano /etc/nginx/sites-available/example.com) с таким содержимым - nginx будет принимать запросы на домен и передавать их приложению на 127.0.0.1:3000:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}Hostпередаёт приложению имя домена из запроса - без него приложение увидит127.0.0.1.X-Real-IPиX-Forwarded-Forнесут настоящий IP посетителя, иначе в логах приложения все запросы будут от nginx.X-Forwarded-Protoсообщает, пришёл запрос по HTTP или HTTPS: по нему фреймворки строят правильные ссылки и не уходят в цикл редиректов.UpgradeиConnectionвместе с блокомmapнужны для WebSocket. Блокmapобъявляется один раз на сервер: для второго сайта копируйте толькоserver.
Шаг 4. Включите сайт и проверьте конфигурацию
Сайт включается ссылкой в sites-enabled. Стандартный сайт-заглушку default удалите, чтобы он не перехватывал запросы. nginx -t проверяет синтаксис до перезагрузки - если он пишет syntax is ok и test is successful, конфигурацию можно применять:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
curl -I http://example.comПоследняя команда должна вернуть ответ вашего приложения по HTTP. Ответ 502 Bad Gateway значит, что nginx работает, а приложение на порту 3000 не запущено.
Шаг 5. Получите сертификат Let's Encrypt через certbot
Certbot - официальный клиент Let's Encrypt от EFF, плагин python3-certbot-nginx сам правит конфигурацию nginx. Укажите все имена, на которые должен действовать сертификат, флагом -d; --redirect сразу включает перенаправление с HTTP на HTTPS:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx --redirect -d example.com -d www.example.comПри первом запуске certbot спросит email и попросит принять условия Let's Encrypt. Затем он проверит, что домен ведёт на этот сервер (запрос на порт 80), получит сертификат и допишет в server block строки listen 443 ssl и пути к ключам. Подробнее о параметрах - на certbot.eff.org.
Шаг 6. Проверьте автопродление
Сертификат Let's Encrypt действует 90 дней. Пакет certbot из apt ставит таймер systemd, который дважды в день проверяет сертификаты и продлевает те, срок которых подходит к концу; после продления плагин сам перезагружает nginx. Убедитесь, что продление пройдёт:
sudo certbot renew --dry-run
systemctl list-timers | grep certbot
sudo certbot certificates--dry-run проходит всю процедуру на тестовом сервере Let's Encrypt, не трогая настоящий сертификат. Вторая команда показывает таймер certbot.timer и время следующего запуска, третья - срок действия выпущенных сертификатов.
Шаг 7. Проверьте HTTPS и редирект
Запрос по HTTP должен вернуть 301 Moved Permanently с адресом https:// в заголовке Location, а запрос по HTTPS - ответ приложения без ошибок сертификата:
curl -I http://example.com
curl -I https://example.comЧастые ошибки certbot и nginx
| Что видите | Причина | Что сделать |
|---|---|---|
DNS problem: NXDOMAIN или проверка уходит на чужой IP | DNS ещё не обновился или A-запись указывает не туда | Проверьте dig +short example.com через публичный резолвер и дождитесь, пока он вернёт IP сервера |
Timeout during connect (likely firewall problem) | Порт 80 закрыт снаружи: правило UFW, nginx не слушает 80 или домен проксируется Cloudflare с ошибкой | sudo ufw allow 'Nginx Full', sudo ss -tlnp - nginx должен слушать :80 |
too many certificates или too many failed authorizations | Сработали лимиты Let's Encrypt на число выпусков или неудачных проверок | Эксперименты делайте с --dry-run, подождите снятия лимита; актуальные значения - в документации Let's Encrypt |
502 Bad Gateway | Приложение не запущено или слушает другой порт | curl http://127.0.0.1:3000 на сервере; сверьте порт в proxy_pass |
conflicting server name в nginx -t | Один домен описан в двух server block | Оставьте домен в одном файле в sites-enabled |
За nginx удобно прятать любые приложения: Node.js-сервис, вебхук Telegram-бота (Telegram принимает вебхуки только по HTTPS) или контейнеры Docker. Для nginx с парой небольших сайтов хватает конфигурации с 1 vCPU и 2 ГБ памяти; VPS Tihost с полным root-доступом разворачивается примерно за 2 минуты.
AMD Ryzen 9, NVMe и защита от DDoS в Германии, Финляндии и Польше. Оплата криптовалютой или картой.
Частые вопросы
Сколько стоит сертификат Let's Encrypt?
Сертификат Let's Encrypt бесплатный: его выпускает некоммерческий центр сертификации, а certbot получает и продлевает его автоматически. Браузеры доверяют ему так же, как платным DV-сертификатам.
Как часто нужно продлевать сертификат Let's Encrypt?
Сертификат Let's Encrypt действует 90 дней, но вручную его продлевать не нужно: таймер systemd из пакета certbot продлевает его заранее. Проверить продление можно командой sudo certbot renew --dry-run.
Почему certbot пишет Timeout during connect?
Let's Encrypt не может достучаться до сервера по порту 80. Откройте порты командой sudo ufw allow 'Nginx Full', проверьте, что nginx запущен, и что домен указывает на IP этого сервера.
Можно ли получить сертификат на IP-адрес без домена?
Для обычной схемы с certbot и nginx нужен домен: сертификат выпускается на имя, которое указывает на сервер. Домен можно купить у любого регистратора и привязать A-записью за несколько минут.
Чем certbot из apt отличается от certbot из snap?
Сайт certbot.eff.org рекомендует snap, где certbot обновляется быстрее. Пакеты certbot и python3-certbot-nginx из apt в Ubuntu и Debian тоже работают и обновляются вместе с системой - для одного сайта разницы нет.
Что такое reverse proxy в nginx?
Reverse proxy - сервер, который принимает запросы из интернета и передаёт их приложению внутри сервера. В nginx за это отвечает директива proxy_pass http://127.0.0.1:3000;, а nginx при этом берёт на себя HTTPS, сжатие и статику.