Программы
Как добавить HTTPS в nginx на Ubuntu Server (16.04 и выше)

Как добавить HTTPS в nginx на Ubuntu Server (16.04 и выше)

Наличие HTTPS на веб-сайте долгое время считалось роскошью. Тому много причин: особо за безопасность владельцы блогов и «визиток» не парились, а сам сертификат стоил денег (что-то в районе $100 в год).

Наличие HTTPS на веб-сайте долгое время считалось роскошью. Тому много причин: особо за безопасность владельцы блогов и «визиток» не парились, а сам сертификат стоил денег (что-то в районе $100 в год).

Но всё больше в последнее время давление на владельцев веб-ресурсов:

  • Гугл обещал поднять в выдаче сайты с HTTPS;
  • Браузеры ругаются на страницы полями пароля без HTTPS;
  • В конце концов сертификаты стали бесплатными.

Зачем нужен сертификат сайту

Подробнее остановимся на последнем. Всё ещё можно купить сертификат, в котором будет указано, что домен подписан сертификатом, который принадлежит компании «Roga & Kopyta Int.». Но надо ли это?

Сервис Let’s Encrypt предлагает бесплатные сертификаты типа «Этот сетрификат выдан этому домену». То есть по сути гарантирует лишь то, что никакой шутник не подменил сайт, а значит данные пересылаются безопасно. Большинству сайтов такой защиты — за глаза!

Настраиваем Let’s Encrypt на nginx в Ubuntu

Данный способ несколько раз проверен на PHP-сайтах (в том числе wordpress) и Django-сайтах (через uwsgi).

Для начала установим необходимые пакеты для добавления ppa-репозиториев:

apt update
apt install -y \
    python-software-properties software-properties-common

Добавим программу certbot, которая будет обновлять нам сертификаты. Замечу, что Let’s Encrypt выдаёт сертификаты на 2 месяца, поэтому его надо обновлять автоматически — этим и займётся certbot.

add-apt-repository ppa:certbot/certbot
apt update

Ну и поставим сам certbot — репозиторий его ведь добавили!

apt install -y \
    certbot

Дальше нам понадобиться добавить путь, по которому сервис Let’s Encrypt будет проверять — мы ли это.

server {
    ...

    # Let's Encrypt
    location ^~ /.well-known/acme-challenge/ {
        root /path/to/static/;
        add_header Cache-Control public;
        allow all;
    }
    ...
}

Многие руководства советуют добавлять location /.well-known, но certbot и letsencrypt используют именно /.well-known/acme-challenge. В связи с этим у меня были определённые трудности, когда я это настраивал для Django-сервиса.

Перезагрузим конфиги nginx:

systemctl reload nginx

И теперь мы можем уже запустить генерацию сертификатов:

certbot certonly -a webroot --webroot-path=/path/to/static/ -d имя-домена.ru -d www.имя-домена.ru

В этот момент certbot положит специальные файлы в /path/to/static, которые будут доступны по урлу http://имя-домена.ru/.well-know/acme-challenge. Сервер let’s encrypt сходит по этому url и проверит — мы ли это, никто не подменил наш сайт. После того, как проверка завершится, certbot положит сертификаты, подписанные letsencrypt в директорию /etc/letsrncrypt/live/имя-домена.ru (их мы и будем использовать).

После чего мы можем включить https:

server {
    listen 443 ssl;

    server_name имя-домена.ru
                www.имя-домена.ru;

    # SSL cert
    ssl_certificate /etc/letsencrypt/live/имя-домена.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/имя-домена.ru/privkey.pem;

    # Let's Encrypt
    location ^~ /.well-known/acme-challenge/ {
        root /path/to/static/;
        add_header Cache-Control public;
        allow all;
    }
}

И снова перечитаем конфигурацию nginx:

systemctl reload nginx

Теперь проверяем — работает ли https (заходим на сайт по https).

Ну и чтобы всегда использовать https — настроим перенаправление с http на https:

server {
    listen 80;
    server_name имя-домена.ru
                www.имя-домена.ru;
    return 301 https://имя-домена.ru$request_uri;
    access_log off;
}

В очередной раз перечитаем конфигурацию nginx:

systemctl reload nginx

Теперь должно всё работать.

Забодьтесь о безопасности своих пользователей — теперь это ещё и «бесплатно».

Ответы на вопросы читателей

Q: Я правильно понимаю, что бот certbot будет сам заходить на сервис Let’s Encrypt и продлевать сертификаты каждые 2 месяца?

A: Современные версии certbot добавляют в crontab запись для автоматического обновления.

Если же не хотите пологаться на то, что кто-то позаботится об обновлении, можете добавить сами в cron команду /usr/bin/letsencrypt renew && nginx -s reload. Раз в день / неделю – впролне себе нормально. Например, от юзера, у которого есть права на letsencrypt renew и nginx -s reload выполнить:

echo "0 0 * * * /usr/bin/letsencrypt renew && nginx -s reload" | crontab

– каждый день в полночь по времени сервера.

Q: Эту /.well-known/acme-challenge/ директорию надо создавать или нет?

A: В описанном location есть директива root. Она указывает на директорию, куда будет направлять данный URL. Эту же директорию мы указываем certbot-у как --webroot-path - он её сам создаст и будет генерить нужные файлы для подтверждения, что это действительно тот домен, которым представляется.

Q: Ладно, все заработало - но есть нюанс - по http показывает обычный рабочий сайт, но стоит зайти по https - выдает заглушку nginx - типа он установлен бла-бла-бла

A: Нужно все локейшены продублировать в сервере, который с https (тот что listen 443), ведь это отдельный сервер, который сидит на отдельном порту.

Есть вариант всё это proxy_pass-ом завернуть на http-шный сервер, но я бы советовал нормально все локейшены и директивы а ля "gzip on" и тд перенести в https сервер. После этого - проверить и сам http редиректить на https. Например, вот так:

server {
  listen 80;
  server_name 900913.ru
              www.900913.ru;
  return 301 https://900913.ru$request_uri;
  access_log off;
}

Вообще, весь конфиг сайта может выглядеть вот так (в примере – uwsgi-приложение):

# Редирект с http на https
server {
    listen 80;
    server_name 900913.ru
                www.900913.ru;
    return 301 https://900913.ru$request_uri;
    access_log off;
}

# Редирект с www на домен без www
server {
    listen 443 ssl;
    server_name www.900913.ru;
    return 301 https://900913.ru$request_uri;
    ssl_certificate /path/to/file/fullchain.pem;
    ssl_certificate_key /path/to/file/privkey.pem;
    access_log off;
}

server {
    listen 443 ssl;
    server_name 900913.ru;

    ssl_certificate /path/to/file/fullchain.pem;
    ssl_certificate_key /path/to/file/privkey.pem;

    gzip on;
    gzip_comp_level 7;
    gzip_vary on;
    gzip_static on;
    gzip_types  text/plain text/css text/javascript application/javascript
                application/x-javascript image/svg+xml image/png image/jpeg;

    client_max_body_size 20m;
    fastcgi_pass_request_body on;

    # Let's Encrypt
    location ^~ /.well-known/acme-challenge/ {
        root /certbot/webroot-path/;
        add_header Cache-Control public;
        allow all;
    }

    location ~ /\. {
        deny  all;
    }

    location = /robots.txt {
        alias /path/to/file/robots.txt;
    }

    # static
    location ~* \.(html|txt|jpg|jpeg|gif|png|pdf|ico|css|bmp|js|swf|otf|woff|ttf|gz|svg|ogg)$ {
        root /path/to/static-files;
        expires 1M;
        add_header Cache-Control public;
    }

    location / {
        uwsgi_pass 127.0.0.1:{{ UWSGI PORT }};
        include uwsgi_params;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $http_host;
    }
}
Также может быть вам интересно:

Как в MacOS создать текстовый документ

Иной раз интересно узнать, что интересно другим. Звучит как ерунда, но часто сложно понять, чем живут другие люди. Все мы имеем разные знания, но я не ожидал такого. Я набрал в поисковой строке «как в mac os»…

Читать »

Как работать с Android в MacOS (поддержка MTP)

Казалось бы — используешь MacOS — используй iPhone… Да только то ли не «дорос», то ли мне нафиг не впился iPhone.

Читать »
Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

Современные сайты редко ограничиваются только текстом и вёрсткой. Часто в заметках красуются фотографии, а рядом с описанием товаров - их изображения.

Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

Во время работы программы часто нужно сохранять некоторые важные записи о процессе выполнения команды. В Python есть довольно мощный модуль для работы с логами - давайте разберёмся с тем, как его использовать.

Фото Шаблон разработки ПО — Model View Controller (MVC)

Шаблон разработки ПО — Model View Controller (MVC)

MVC - один из самых распространённых архитектурных шаблонов разработки. Часто используется в различных фреймворках. В том числе и в Django.

Фото Пользователи и их создание в Django - своя регистрация на сайте

Пользователи и их создание в Django - своя регистрация на сайте

Если вашим сайтом должны активно пользоваться несколько человек, то полезно их различать, а значит - надо уметь создавать пользователей, либо предоставлять возможность регистрации Django пользователей.

Фото Пользователи и авторизация (логин) в Django, кастомизация пользователя

Пользователи и авторизация (логин) в Django, кастомизация пользователя

В Django есть множество встроенных возможностей, которые позволяют не реализовывать многие классы для стандартных операций. Среди них - авторизация. Django изначально предоставляет пользовательскую систему. Но её можно использовать лучше, чем по умолчанию.

Фото Панель администрирования Django - настройка вида (шаблона)

Панель администрирования Django - настройка вида (шаблона)

Простой способ подключить админку к сайту на Django, как сконфигурировать адмиин-панель, как изменить оформление администрационной панели Django фреймворка.

Фото Панель администрирования Django - подключение, настройка, поиск, фильтрация

Панель администрирования Django - подключение, настройка, поиск, фильтрация

Простой способ подключить админку к сайту на Django, как сконфигурировать адмиин-панель и добавить функциональность поиска, массовых действий, как изменить оформление администраторской панели Django фреймворка.