TLS (Transport Layer Security) и его предшественник SSL (Secure Socket Layers) – это криптографические протоколы, которые используются для защиты передачи данных в Интернете.
Эта технология позволяет защитить обмен данными между сервером и клиентом и предотвратить перехват или несанкционированный доступ к передаваемой информации. Кроме того, эти протоколы предоставляют систему сертификатов, которая помогает пользователям проверить подлинность сайтов, на которые они заходят.
Данное руководство поможет создать самоподписанный SSL-сертификат для веб-сервера Apache в Ubuntu 16.04.
Примечание: Самоподписанный сертификат не сможет подтвердить подлинности сервера, так как он не подписан проверенным центром сертификации (ЦС); тем не менее, такой сертификат позволит шифровать взаимодействие с веб-клиентами. Самоподписанный сертификат подходит пользователям, у которых пока что нет доменного имени. При наличии домена рекомендуется обратиться за подписью сертификата к одному из надёжных ЦС. Также можно получить бесплатный доверенный сертификат от сервиса Let’s Encrypt.
Требования
- Не-root пользователь с доступом к sudo (инструкции по созданию такого пользователя – в этой статье).
- Предварительно установленный веб-сервер Apache. Можно установить стек LAMP, одним из компонентов которого является Apache (для этого следуйте этому руководству); чтобы установить только Apache, выполните только инструкции по установке этого веб-сервера, пропустив остальные разделы.
1: Создание SSL-сертификата
Для работы TLS/SSL использует комбинацию открытого сертификата и закрытого ключа. Закрытый ключ хранится на сервере и не разглашается. SSL-сертификат используется открыто и доступен всем пользователям, запрашивающим контент.
Чтобы создать самоподписанный сертификат и ключ, запустите команду:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
Команда задаст ряд вопросов. Рассмотрим компоненты команды подробнее:
- openssl: базовый инструмент командной строки для создания и управления сертификатами, ключами и другими файлами OpenSSL.
- req: эта подкоманда указывает, что на данном этапе нужно использовать запрос на подпись сертификата X.509 (CSR). X.509 – это стандарт инфраструктуры открытого ключа, которого придерживаются SSL и TLS при управлении ключами и сертификатами. То есть, данная команда позволяет создать новый сертификат X.509.
- -x509: эта опция вносит поправку в предыдущую субкоманду, сообщая утилите о том, что вместо запроса на подписание сертификата необходимо создать самоподписанный сертификат.
- -nodes: пропускает опцию защиты сертификата парольной фразой. Нужно, чтобы при запуске сервер Apache имел возможность читать файл без вмешательства пользователя. Установив пароль, придется вводить его после каждой перезагрузки.
- -days 365: эта опция устанавливает срок действия сертификата (как видите, в данном случае сертификат действителен в течение года).
- -newkey rsa:2048: эта опция позволяет одновременно создать новый сертификат и новый ключ. Поскольку ключ, необходимый для подписания сертификата, не был создан ранее, нужно создать его вместе с сертификатом. Данная опция создаст ключ RSA на 2048 бит.
- -keyout: эта опция сообщает OpenSSL, куда поместить сгенерированный файл ключа.
- -out: сообщает OpenSSL, куда поместить созданный сертификат.
Как уже было сказано, все эти опции сгенерируют ключ и сертификат. Заполните появившиеся поля данными о сервере, которые будут отображаться в сертификате.
Самой важной строкой является Common Name (введите полное доменное имя сервера (FQDN) или свое имя). Как правило, в эту строку вносят доменное имя, с которым нужно связать сервер. В случае если доменного имени нет, внесите в эту строку IP-адрес сервера. В целом эти поля выглядят примерно так:
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.
Organizational Unit Name (eg, section) []:Ministry of Water Slides
Common Name (e.g. server FQDN or YOUR name) []:server_IP_address
Email Address []:admin@your_domain.com
Файлы ключа и сертификата будут помещены в каталог /etc/ssl.
При использовании OpenSSL нужно также создать ключи Диффи-Хеллмана, которые нужны для поддержки PFS (совершенной прямой секретности).
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Этот процесс займёт несколько минут. Ключи DH будут помещены в /etc/ssl/certs/dhparam.pem.
2: Настройка Apache для поддержки SSL
Итак, на данном этапе файлы ключа и сертификата созданы и хранятся в каталоге /etc/ssl. Теперь нужно отредактировать настройки Apache:
- Создать сниппет конфигураций, указывающий место хранения файлов SSL-сертификата и ключа.
- Настроить виртуальный хост Apache для поддержки сертификата SSL.
- Настроить незашифрованные виртуальные хосты для автоматической переадресации запросов на зашифрованный хост (опционально).
Местонахождение ключа и сертификата
Для начала нужно создать сниппет конфигураций Apache, определяющий некоторые параметры SSL; здесь можно выбрать метод шифрования SSL и включить дополнительные функции безопасности. Заданные здесь параметры в дальнейшем могут быть использованы любыми виртуальными хостами для поддержки SSL.
Создайте новый сниппет Apache в каталоге etc/apache2/conf-available.
Рекомендуется указать в названии файла его назначение (к примеру, ssl-params.conf):
sudo nano /etc/apache2/conf-available/ssl-params.conf
Для безопасной настройки SSL обратимся к рекомендациям Remy van Elst на сайте Cipherli.st. Этот сайт предназначен для распространения простых и надёжных параметров шифрования для популярного программного обеспечения. Больше параметров для Apache можно найти здесь.
Примечание: Данный список настроек подходит для более новых клиентов. Чтобы получить настройки для других клиентов, перейдите по ссылке Yes, give me a ciphersuite that works with legacy / old software.
Скопируйте все предложенные параметры.
Также нужно добавить параметр SSLOpenSSLConfCmd DHParameters, чтобы настроить поддержку ключей Диффи-Хеллмана.
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLSessionTickets Off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
Сохраните и закройте файл.
Настройка стандартного виртуального хоста Apache
Теперь нужно настроить стандартный виртуальный хост Apache (/etc/apache2/sites-available/default-ssl.conf) для поддержки SSL.
Примечание: Если вы используете другой виртуальный хост, укажите его имя вместо /etc/apache2/sites-available/default-ssl.conf.
Прежде чем приступить к настройке, создайте резервную копию файла хоста.
sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.bak
Откройте хост в текстовом редакторе:
sudo nano /etc/apache2/sites-available/default-ssl.conf
На данный момент файл виртуального хоста выглядит примерно так (закомментированные строки опущены для удобства):
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# BrowserMatch "MSIE [2-6]" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>
В файл нужно внести несколько небольших поправок: отредактировать директивы ServerAdmin и ServerName, изменить параметры SSL, указав файлы ключа и сертификата, и раскомментировать раздел конфигураций, отвечающих за совместимость с устаревшими версиями браузеров.
В результате файл будет иметь такой вид:
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin your_email@example.com
ServerName server_domain_or_IP
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>
Сохраните и закройте файл.
Настройка переадресации (опционально)
На данный момент сервер поддерживает и HTTP, и HTTPS. Для более надёжной защиты сервера рекомендуется отключить незашифрованный трафик HTTP.
Отредактируйте виртуальный хост, разрешающий HTTP-трафик, и настройте переадресацию. Откройте файл /etc/apache2/sites-available/000-default.conf:
sudo nano /etc/apache2/sites-available/000-default.conf
В блок VirtualHost добавьте директиву Redirect, которая будет переадресовывать весь незашифрованный трафик:
<VirtualHost *:80>
. . .
Redirect "/" "https://your_domain_or_IP"
. . .
</VirtualHost>
Сохраните и закройте файл.
3: Настройка брандмауэра
Если вы включили брандмауэр ufw (согласно руководству по начальной настройке), на данном этапе его нужно настроить для поддержки трафика SSL. К счастью, при установке Apache регистрирует в ufw несколько своих профилей.
Чтобы просмотреть доступные профили, введите:
sudo ufw app list
Available applications:
Apache
Apache Full
Apache Secure
OpenSSH
Текущие настройки можно просмотреть при помощи команды:
sudo ufw status
Если разрешен только трафик HTTP, настройки будут иметь такой вид:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache (v6) ALLOW Anywhere (v6)
Чтобы добавить поддержку трафика HTTPS, нужно включить профиль Apache Full и отключить профиль Apache.
sudo ufw allow 'Apache Full'
sudo ufw delete allow 'Apache'
Проверьте текущее состояние брандмауэра:
sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
4: Обновление настроек Apache
Итак, теперь настройки веб-сервера и брандмауэра откорректированы. Можно включить SSL и настроенный для поддержки сертификата виртуальный хост, а затем перезапустить веб-сервер.
Включите модуль Apache для SSL, mod_ssl, и модуль mod_headers, который необходим для работы сниппета SSL:
sudo a2enmod ssl
sudo a2enmod headers
Включите подготовленный виртуальный хост:
sudo a2ensite default-ssl
Итак, теперь сайт и все необходимые модули включены. Проверьте синтаксис на наличие ошибок:
sudo apache2ctl configtest
Если ошибок нет, команда вернёт:
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
Первая строка вывода сообщает, что директива ServerName установлена не глобально. Чтобы устранить это предупреждение, отредактируйте директиву ServerName в /etc/apache2/apache2.conf, указав доменное имя или IP сервера (это опционально, данное предупреждение устранять необязательно).
Если в синтаксисе обнаружены ошибки, исправьте их. Затем перезапустите веб-сервер:
sudo systemctl restart apache2
5: Тестирование
Теперь нужно убедиться, что трафик между сервером и клиентом шифруется. Откройте в браузере следующую ссылку:
https://домен_или_IP_сервера
Поскольку сертификат был подписан самостоятельно, браузер сообщит о его ненадёжности:
Your connection is not private
Attackers might be trying to steal your information
(for example, passwords, messages, or credit cards). NET::ERR_CERT_AUTHORITY_INVALID
Это нормальное поведение программы в подобной ситуации, поскольку браузер не может проверить подлинность хоста. Однако в данном случае нужно только шифровать трафик, с чем самоподписанный сертификат вполне справляется, потому предупреждение браузера можно пропустить. Для этого нажмите кнопку ADVANCED и кликните по предложенной ссылке.
После этого вы получите доступ к своему сайту.
Если вы настроили два блока server для переадресации трафика HTTP на HTTPS, проверьте, работает ли переадресация:
http://server_domain_or_IP
6: Постоянный редирект
Если все настройки сервера работают должным образом, настройте постоянный редирект вместо временного.
Откройте файл виртуального хоста Apache:
sudo nano /etc/apache2/sites-available/000-default.conf
Найдите ранее добавленную директиву Redirect и установите значение permanent.
<VirtualHost *:80>
. . .
Redirect permanent "/" "https://your_domain_or_IP"
. . .
</VirtualHost>
Сохраните и закройте файл. Проверьте синтаксис:
sudo apache2ctl configtest
Перезапустите Apache:
sudo systemctl restart apache2
Заключение
Теперь сервер Apache может шифровать передаваемые данные, что защитит взаимодействие сервера с клиентами и предотвратит перехват трафика злоумышленниками.
Конечно, при разработке сайта рекомендуется подписать SSL-сертификат в надежном центре сертификации, что позволит избежать появления отпугивающих предупреждений.