Pull to refresh

Как я пытался включить http2 у себя на проекте с nginx

Reading time5 min
Views36K
В общем, как я уже читал тут в комментах: «целые статьи пишут на то, как добавить 5 символов и пробел в конфиг». Все бы хорошо, если бы не google chrome. Они решили прекратить поддержку SPDY и NPN(кому интересно, вот комментарий chromium по этому поводу).

Для примера берем debian 8 на google cloud engine, ставим nginx, с помощью letsencrypt делаем сертификаты.

Для тех, кто не умеет:


echo "deb http://ftp.debian.org/debian jessie-backports main" >> /etc/apt/sources.list
apt-get update
apt-get install certbot -t jessie-backports -y
certbot certonly --webroot -w /var/www/html -d domain.tld --email=your@email.tld --agree-tos #где /var/www/html - корень вашего сайта, который виден из вне

По итогу получаем такое:
IMPORTANT NOTES:
— Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/http2.kricha.info/fullchain.pem. Your cert
will expire on 2017-02-03. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run «certbot
renew»

то есть все ваши ключи будут лежать здесь /etc/letsencrypt/live/domain.tld/

# ls -la /etc/letsencrypt/live/http2.kricha.info/
total 8
drwxr-xr-x 2 root root 4096 Nov  5 17:53 .
drwx------ 3 root root 4096 Nov  5 17:53 ..
lrwxrwxrwx 1 root root   41 Nov  5 17:53 cert.pem -> ../../archive/http2.kricha.info/cert1.pem
lrwxrwxrwx 1 root root   42 Nov  5 17:53 chain.pem -> ../../archive/http2.kricha.info/chain1.pem
lrwxrwxrwx 1 root root   46 Nov  5 17:53 fullchain.pem -> ../../archive/http2.kricha.info/fullchain1.pem
lrwxrwxrwx 1 root root   44 Nov  5 17:53 privkey.pem -> ../../archive/http2.kricha.info/privkey1.pem

Добавляем всю эту красоту в конфиг nginx:

#let's encrypt certificates
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
ssl_trusted_certificate	/etc/letsencrypt/live/domain.tld/chain.pem;

В итоге у вас должно получиться что-то такое:

server {

	server_name domain.tld;
	listen 443 ssl http2;

	server_tokens off;
	keepalive_timeout   70;

	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 127.0.0.1;
	resolver_timeout 10s;
	ssl on;

	#let's encrypt certificates
	ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
	ssl_trusted_certificate	/etc/letsencrypt/live/domain.tld/chain.pem;
	ssl_dhparam /etc/nginx/ssl/dhparam.pem;

	ssl_session_timeout 1h;
	ssl_session_cache shared:SSL:10m;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

	ssl_prefer_server_ciphers on;
	ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;

	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
	add_header X-Frame-Options DENY;
	add_header X-Content-Type-Options nosniff;

	root /var/www/html;
    index index.nginx-debian.html;

	location / {
        	try_files $uri $uri/ =404;
   	 }

    error_log /var/log/nginx/domain.tld.error.log;
    access_log /var/log/nginx/domain.tld.access.log;
}

server {
	listen 80;
	listen [::]:80;
	server_name domain.tld;
	return 301 https://$host$request_uri;
}

VBart:
В документации указано: nginx.org/ru/docs/http/ngx_http_core_module.html#resolver
Для предотвращения DNS-спуфинга рекомендуется использовать DNS-серверы в защищённой доверенной локальной сети.
Встроенный резолвер заточен на производительность, при этом в жертву принесена безопасность.

еще можете взглянуть в файл
cat /etc/resolv.conf
nameserver 127.0.0.1

Возможно там указан уже сконфигурированный DNS-сервер. Проверить как он работает можно так:
nslookup example.org 127.0.0.1
или
dig example.org @127.0.0.1

VBart:
Обычно не установлен. Вместо полноценного DNS-сервера можно использовать DNS-форвардер, типа dnsmasq.


Чтоб сделать DHE:
cd  /etc/nginx
mkdir ssl
openssl dhparam -out ssl/dhparam.pem 2048

Вроде бы все и можно делать service nginx reload но фиг нам :) Вы получите в ответ это: Job for nginx.service failed. See 'systemctl status nginx.service' and 'journalctl -xn' for details., а в деталях:

ov 05 18:01:15 http2 systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Nov 05 18:01:15 http2 systemd[1]: Started A high performance web server and a reverse proxy server.
Nov 05 18:14:27 http2 systemd[1]: Reloading A high performance web server and a reverse proxy server.
Nov 05 18:14:27 http2 nginx[24507]: nginx: [emerg] invalid parameter "http2" in /etc/nginx/sites-enabled/default:4
Nov 05 18:14:27 http2 systemd[1]: nginx.service: control process exited, code=exited status=1
Nov 05 18:14:27 http2 systemd[1]: Reload failed for A high performance web server and a reverse proxy server.

В общем, nginx вообще не понял чего мы от него хотели и хотим. Смотрим версию и оказывается nginx version: nginx/1.6.2, ладно, поставим последнюю версию.

Установим свежую версию nginx


echo -e "deb http://nginx.org/packages/mainline/debian/ jessie nginx\ndeb-src http://nginx.org/packages/mainline/debian/ jessie nginx" >>/etc/apt/sources.list
rm -rf /var/lib/dpkg/info/nginx*
apt-get update
apt-get upgrade --force-yes -y
service nginx restart

Заходим в браузер, проверяем:

image
Видим Статус HTTP/2.0 200, радуемся, проверяем в хроме:

image
Видим Protocol http/1.1, грустим и уходим плакать. Нет, конечно, не сдаемся, доливаем в стаканчик ром и продолжаем.

Собираем правильный nginx


apt-get install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev
cd /opt
wget http://nginx.org/download/nginx-1.11.5.tar.gz
wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz
tar xf nginx-1.11.5.tar.gz
tar xf openssl-1.0.2j.tar.gz
cd nginx-1.11.5
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-openssl=/opt/openssl-1.0.2j
make
make install
service nginx restart

Вместо make install можно собрать пакет:

apt-get install checkinstall -y
dpkg -i nginx_1.11.5-1_amd64.deb

Проверяем в хроме:

image

В сафари:

image

Везде видим, что используется протокол http2, проверяем еще на www.ssllabs.com, получаем:

image

Профит! Доливаем себе ром и идем спать! Всем спасибо за внимание, надеюсь кому-то помог.
Tags:
Hubs:
Total votes 65: ↑56 and ↓9+47
Comments68

Articles