Эта статья не претендует на инструкцию и была написана как черновик, чтобы потом мог вспомнить как это делается.
За основу взяты материалы из разных источников, как говориться, с миру по нитке.
Итак, начнем!
Я буду настраивать NGINX как шлюз для нескольких серверов с своей локальной сети.
Имеем:
Ubuntu server 18.04.3
Обновляем и устанавливаем Web-сервер
sudo apt install nginx -y
Далее потребуется создать директорию для сайта, например: /var/www/mysite.ru
sudo mkdir /var/www/misite.ru
И создадим файл конфига для нашего сайта
sudo nano /etc/nginx/sites-available/mysite.ru
Заполним его следующим содержимым:
upstream mysite.ru {
server 192.168.0.6;
}
server {
listen 80; # прослушиваемый порт
server_name mysite.ru; # здесь можно указать несколько сайтов, например
# mysite.ru www.mysite.ru mail.mysite.ru
# в следующей секции указывается суб-директория для добавления / обновления
# сертификатов для папки созданной на предыдущем шаге
# данная директория проксироваться не будет
location /.well-known {
alias /var/www/mysite.ru/.well-known;
}
location / {
proxy_pass https://192.168.0.6;
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;
}
}
Далее активируем сайт
sudo ln -s /etc/nginx/sites-available/mysite.ru /etc/nginx/sites-enabled/mysite.ru
И перезапускаем службу сервера
sudo service nginx restart
Затем устанавливаем Letsencrypt
sudo apt-get install letsencrypt
И выпускаем сертификат для нашего сайта (сайтов)
sudo letsencrypt certonly --webroot -w /var/www/mysite.ru -d mysite.ru
Или так, для нескольких доменных имен
sudo letsencrypt certonly --webroot -w /var/www/mysite.ru -d mysite.ru -d www.mysite.ru -d mail.mysite.ru
Чтобы сертбот мог выпустить сертификат, публичные DNS-сервера должны знать о доменных именах указываемых сертботу.
Далее, нужно сгенерировать dhparam сертификат для нашего сайта, чтобы было удобнее, лучше создать отдельную папку для каждого сайта
sudo mkdir /etc/nginx/ssl/mysite.ru
sudo openssl dhparam -out dhparam.pem 2048
Теперь надо переключить сайт на SSL
upstream mysite.domain.ru {
server 192.168.0.6;
}
server {
listen 80;
server_name mysite.ru;
return 301 https://$host$request_uri; #правило перенаправления с http на https
}
server {
listen 443 ssl http2;
server_name mysite.ru;
ssl_certificate /etc/letsencrypt/live/mysite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.ru/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/mysite.ru/chain.pem;
ssl_dhparam /etc/nginx/ssl/mysite.ru/dhparam.pem;
#Настройки ssl ниже оставляю без изменений для большинства сайтов
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers On;
#Параметр ниже нужно раскомментировать после проверки сайта
#add_header Strict-Transport-Security "max-age=31536000";
#Для обновления сертификатов
location /.well-known {
alias /var/www/mysite.ru/.well-known;
}
location / {
proxy_pass https://192.168.0.6;
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;
#В этот файл складываю общие настройки прокси (см ниже)
include /etc/nginx/sites-available/proxy.cfg;
}
}
И добавляем общий прокси конфиг
proxy_buffers 32 4m;
proxy_busy_buffers_size 25m;
proxy_buffer_size 512k;
proxy_ignore_headers "Cache-Control" "Expires";
proxy_max_temp_file_size 0;
client_max_body_size 1024m;
client_body_buffer_size 4m;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
proxy_intercept_errors off;
Для исключения возможности подключения к серверу по IP, достаточно добавить в конфигурацию первого сайта по алфавиту (сразу после блока upstream):
server {
return 444;
}
Это заблокирует доступ по http, но если добавить https перед ip — доступ останется. Если попробовать заблокировать также https — перестают работать корректно https сайты. Поэтому, в блок сервера https добавить условие сразу после строки с server_name:
..
server_name example.com
if ($host != "example.com") {
return 444;
}
..
Для обновления сертификатов, на мой взгляд удобнее обновлять все сразу, используем команду certbot renew
Поскольку сертификаты выдаются на три месяца и обновлять сертификаты можно уже через неделю, проще добавить задание в планировщик
sudo crontab -e
...
0 1 * * 6 certbot renew
Данная команда будет запускать обновление всех сертификатов каждую субботу в час ночи
Если сертификат уже не нужен, его удалить нельзя, можно просто отключить обновление удалив файл сертификата /etc/letsencrypt/renewal/mysite.ru.conf предварительно сохранив его копию
sudo letsencrypt renew --dry-run --agree-tos
Проверить, что сертификат не будет обновляться можно запустив тестовое обновление:
sudo letsencrypt renew --dry-run --agree-tos
ЕСЛИ НА BACK-END СЕРВЕРЕ УСТАНОВЛЕН APACHE2
Если на сервер в локальной сети работает апач, для корректной работы https, сайт должен иметь SSL сертификаты.
Установи Letcencrypt
sudo apt update
sudo apt install python-letsencrypt-apache -y
Система установит все необходимые пакеты, после чего надо активировать SSL модуль апача
sudo a2enmod ssl
Далее, активируем дефолтный SSL конфиг или создадим свой
sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/mysite-ssl.ru.conf
И поправим его
sudo nano /etc/apache2/sites-available/mysite-ssl.ru.conf
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerName mysite.ru
ServerAlias www.mysite.ru
ServerAdmin webmaster@localhost
DocumentRoot /var/www/mysite.ru
# Available loglevels: trace8, ..., trace1, debug, info, notice$
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For exam$
# following line enables the CGI configuration for this host on$
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# A self-signed (snakeoil) certificate can be created by inst$
# the ssl-cert package. See
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, on$
# SSLCertificateFile directive is needed.
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
# Note: Inside SSLCACertificatePath you need hash symlinks
# to point to the certificate files. Use the pro$
# Makefile to update the hash symlinks after cha$
#SSLCACertificatePath /etc/ssl/certs/
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
# Certificate Revocation Lists (CRL):
# Set the CA revocation path where to find CA CRLs for client
# authentication or alternatively one huge file containing all
# of them (file must be PEM encoded)
# Note: Inside SSLCARevocationPath you need hash symlinks
# to point to the certificate files. Use the pro$
# Makefile to update the hash symlinks after cha$
#SSLCARevocationPath /etc/apache2/ssl.crl/
#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation.$
# the standard Auth/DBMAuth methods can be used for acce$
# user name is the `one line' version of the client's X.$
# Note that no password is obtained from the user. Every$
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL$
# SSL_SERVER_CERT. These contain the PEM-encoded certifi$
# server (always existing) and the client (only existing$
# authentication is used). This can be used to import th$
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' envi$
# Per default this exportation is switched off for perfo$
# because the extraction step is an expensive operation $
# useless for serving static content. So one usually ena$
# exportation for CGI and SSI requests only.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation ha$
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant s$
# approach is that mod_ssl sends the close notify alert but d$
# the close notify alert from client. When you need a differe$
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is$
# SSL close notify alert is send or allowed to received.$
# the SSL/TLS standard but is needed for some brain-dead$
# this when you receive I/O errors because of the standa$
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection i$
# SSL close notify alert is send and mod_ssl waits for t$
# alert of the client. This is 100% SSL/TLS standard com$
# practice often causes hanging connections with brain-d$
# this only for browsers where you know that their SSL i$
# works correctly.
# Notice: Most problems of broken clients are also related to$
# keep-alive facility, so you usually additionally want to di$
# keep-alive for those clients, too. Use variable "nokeepaliv$
# Similarly, one has to force some clients to use HTTP/1.0 to$
# their broken HTTP/1.1 implementation. Use variables "downgr$
# "force-response-1.0" for this.
# BrowserMatch "MSIE [2-6]" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Так же создадим файл виртуального хоста
sudo nano /etc/apache2/sites-available/mysite.ru.conf
<VirtualHost *:80>
ServerName mysite.ru
ServerAlias www.mysite.ru
ServerAdmin webmaster@mysite.ru
DocumentRoot /var/www/mysite.ru
<Directory /var/www/mysite.ru>
AllowOverride All
</Directory>
ErrorLog /var/www/mysite.ru/logs/error.log
CustomLog /var/www/mysite.ru/logs/access.log combined
Include conf-available/serve-cgi-bin.conf
</VirtualHost>
Активируем наши конфиги
sudo a2ensite mysite-ssl.ru.conf
sudo a2ensite mysite.ru.conf
sudo service apache2 reload
Выпускаем сертификат
sudo letsencrypt --apache -d mysite.ru -d www.mysite.ru
Служба задаст несколько вопросов, потребуется зарегистрировать почту, без этого ни как, согласиться на отправку спама от EFF (главного спонсора) и выбрать, будет ли осуществляться автоматическая переадресация на SSL, в результате мы получим такой конфиг
<VirtualHost *:80>
ServerName mysite.ru
ServerAlias www.mysite.ru
ServerAdmin webmaster@mysite.ru
DocumentRoot /var/www/mysite.ru
<Directory /var/www/mysite.ru>
AllowOverride All
</Directory>
ErrorLog /var/www/mysite.ru/logs/error.log
CustomLog /var/www/mysite.ru/logs/access.log combined
Include conf-available/serve-cgi-bin.conf
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.mysite.ru [OR]
RewriteCond %{SERVER_NAME} =mysite.ru
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Все, после этих манипуляций наш сайт будет работать по безопасному протоколу HTTPS