В общем, как я уже читал тут в комментах: «целые статьи пишут на то, как добавить 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

Профит! Доливаем себе ром и идем спать! Всем спасибо за внимание, надеюсь кому-то помог.
Поделиться с друзьями
-->

Комментарии (67)


  1. malinichev
    05.11.2016 23:18

    Спасибо большое) Мучался с обновлением nginx на продакшене… Но теперь нормально, вы помогли)


  1. Meklon
    05.11.2016 23:25

    А разве в версии 1.11.5 из mainline нет поддержки http2? Вроде с nginx 1.9.5. работает. Кстати, а зачем вообще его пилить? Скорость?


    1. Andrey_Volk
      05.11.2016 23:41
      +2

      http2 on wiki — полезный ресурс. Только не хейтите, но там действительно ответ на вопрос выше.


    1. gmelikov
      06.11.2016 01:42
      +1

      Chrome с определенного момента перестал поддерживать NPN, и потребовал APLN (Protocol Negotiation extension для TLS), который поддерживается в более свежем openssl.

      Вопрос не в nginx, а в openssl, с которым он собирается.


      1. gmelikov
        06.11.2016 03:59
        -1

        Извиняюсь, неправильно понял вопрос. Судя по чейнджлогам, он там уже есть.


        1. sumanai
          06.11.2016 13:25

          В некоторых (если не в большинстве) репозиториях nginx использует системный openssl, так что не везде вопрос в сборке именно nginx. Я только после обновления на 16.04 получил поддержку APLN, включение его на моей старой 14.04 требовало каких-то лишних свистоплясок, насколько я помню.


          1. gmelikov
            06.11.2016 17:44

            Вы правы, только я бы уточнил — nginx собирается на базе версии openssl, входящей в репозиторий.

            Комментарием выше в общем то я также, как и Вы, указал на openssl.


            1. sumanai
              06.11.2016 20:26

              Просто найти nginx, который собрали на более новой версии- не проблема, а вот openssl- это так сказать системный компонент, на который завязано куча другого ПО, и его обновить не так то просто, проще всю систему сразу обновить, чем разбираться с зависимостями как самого openssl, так и ПО, завязанного на openssl.


              1. gmelikov
                06.11.2016 20:34

                Насколько я знаю, openssl нужен для nginx в момент сборки в виде исходных кодов (статическая линковка). Так что тут вопрос больше организационный для мэйнтейнеров дистрибутива, никто не мешает Вам взять уже собранный с нужной версией openssl пакет nginx и установить его у себя в системе.

                Я так и сделал на Debian Jessie:)


  1. kirill_danshin
    05.11.2016 23:38

    Спасибо за статью.
    Я для сentos7, кстати, делал скрипт автоматической сборки правильного nginx 1.11.3 с патчами от CloudFlare (даёт ALPN http/1.1/spdy/h2), OpenSSL 1.0.2i, ngx_pagespeed, brotli, ngx_small_light, njs и echo-nginx-module.


    1. VBart
      06.11.2016 01:08
      +13

      Не стоит эти патчи от CloudFlare использовать. Почему не стоит я давал подробное разъяснение у нас в багтрекере: http://trac.nginx.org/nginx/ticket/1029#comment:2


      Появление этих патчей было актом самопиара CloudFlare, а не попыткой сделать что-то полезное для общества.


      1. kirill_danshin
        06.11.2016 19:16

        Если посмотреть в код скрипта, можно увидеть, что используются переделанные патчи. Можно посмотреть, что делают они, возможно, эти патчи лучше.


        1. VBart
          06.11.2016 23:18
          +1

          Нет, они такие же. Правки там сделаны только для того, чтобы оно собиралось правильно с новыми версиями.


  1. alexxxst
    05.11.2016 23:39
    +4

    Пожалуйста, checkinstall!


    1. kricha
      06.11.2016 00:08

      я не сильно понял зачем он вам:

      checkinstall
      Installing with make install...
      
      ========================= Installation results ===========================
      make -f objs/Makefile install
      make[1]: Entering directory '/opt/nginx-1.11.5'
      test -d '/etc/nginx' || mkdir -p '/etc/nginx'
      test -d '/usr/sbin' 	|| mkdir -p '/usr/sbin'
      test ! -f '/usr/sbin/nginx' 	|| mv '/usr/sbin/nginx' 		'/usr/sbin/nginx.old'
      cp objs/nginx '/usr/sbin/nginx'
      test -d '/etc/nginx' 	|| mkdir -p '/etc/nginx'
      cp conf/koi-win '/etc/nginx'
      cp conf/koi-utf '/etc/nginx'
      cp conf/win-utf '/etc/nginx'
      test -f '/etc/nginx/mime.types' 	|| cp conf/mime.types '/etc/nginx'
      cp conf/mime.types '/etc/nginx/mime.types.default'
      test -f '/etc/nginx/fastcgi_params' 	|| cp conf/fastcgi_params '/etc/nginx'
      cp conf/fastcgi_params 	'/etc/nginx/fastcgi_params.default'
      test -f '/etc/nginx/fastcgi.conf' 	|| cp conf/fastcgi.conf '/etc/nginx'
      cp conf/fastcgi.conf '/etc/nginx/fastcgi.conf.default'
      test -f '/etc/nginx/uwsgi_params' 	|| cp conf/uwsgi_params '/etc/nginx'
      cp conf/uwsgi_params 	'/etc/nginx/uwsgi_params.default'
      test -f '/etc/nginx/scgi_params' 	|| cp conf/scgi_params '/etc/nginx'
      cp conf/scgi_params 	'/etc/nginx/scgi_params.default'
      test -f '/etc/nginx/nginx.conf' 	|| cp conf/nginx.conf '/etc/nginx/nginx.conf'
      cp conf/nginx.conf '/etc/nginx/nginx.conf.default'
      test -d '/var/run' 	|| mkdir -p '/var/run'
      test -d '/var/log/nginx' 	|| mkdir -p '/var/log/nginx'
      test -d '/etc/nginx/html' 	|| cp -R html '/etc/nginx'
      test -d '/var/log/nginx' 	|| mkdir -p '/var/log/nginx'
      make[1]: Leaving directory '/opt/nginx-1.11.5'
      
      ======================== Installation successful ==========================
      
      Copying files to the temporary directory...OK
      
      Stripping ELF binaries and libraries...OK
      
      Compressing man pages...OK
      
      Building file list...OK
      
      Building Debian package...OK
      
      Installing Debian package...OK
      
      Erasing temporary files...OK
      
      Writing backup package...OK
      OK
      
      Deleting temp dir...OK
      
      
      **********************************************************************
      
       Done. The new package has been installed and saved to
      
       /opt/nginx-1.11.5/nginx_1.11.5-1_amd64.deb
      
       You can remove it from your system anytime using: 
      
            dpkg -r nginx
      
      **********************************************************************
      


      1. alexxxst
        06.11.2016 00:11
        +2

        Ну, как бы пакетами лучше управлять, чем следить за помойкой из файлов.


        1. kricha
          06.11.2016 00:17
          +1

          Ну, спасибо, добавил альтернативный вариант в статью)


  1. VolCh
    06.11.2016 00:17
    +1

    На Убунте как-то сразу завелось из пакетов. А вот подружить haproxy и nginx не получилось пока, так что откатились на 1.1


    1. kricha
      06.11.2016 00:20
      +2

      Это скорее всего по-этому:

      OS and openssl versions
      image


    1. onyxmaster
      07.11.2016 02:13

      А что именно не работает с haproxy? С обработкой POST не связано?


      1. VolCh
        07.11.2016 10:34

        Вообще в связке haproxy(http2+https-endpoint)+nginx(http2) не передаётся много информации о запросе на nginx. На стороне nginx не реально воссоздать GET запрос и реальный IP-адрес клиента (какие данные точно не передаются сейчас не скажу). С телом POST и т. п. запросов проблем как раз не заметил.


        1. VBart
          07.11.2016 13:07
          +1

          Всё должно работать без проблем, если правильно настроить. Реальный IP передается через proxy protocol.


          1. VolCh
            09.11.2016 12:43

            Вот именно с proxy protocol и проблема. В первой версии инфы передаётся мало, на бэкенде не получается восстановить запрос полностью, а вторую nginx (ещё?) не поддерживает. Повторюсь, точно уже не помню, что именно не передаётся, но нам нужен был полный uri (со схемой и портом) и ip-адрес клиента. Что-то из этого по не смогли получить, убедились, что по спекам proxy protocol v1 и не должны, что v2 не поддерживается nginx и откатились.


            1. VBart
              11.11.2016 00:41

              URI никогда не передается по proxy protocol, это уже часть HTTP запроса, которых может быть много в одном соединении. Спецификация тут: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt


              1. VolCh
                11.11.2016 06:46

                Он не передаётся как единая сущность даже в HTTP1.0, но в рамках HTTP > 1.0 его (без хэш-части, конечно) можно восстановить на стороне сервера (в HTTP 1.0 нет HOST и восстановить нельзя). В случае proxy protocol v1 на проксируемый сервер проксирующий не передаёт информации о том SSL-соединение открыл клиент или нет, не говоря о деталях этого соединения типа CN клиента.


                1. VBart
                  12.11.2016 16:48

                  SSL или не SSL, а также детали соединения — не являются частью URI.


                  Типичный HTTP/1.1-запрос выглядит так:


                  GET /blog HTTP/1.1
                  Host: example.com
                  User-Agent: Mozilla...
                  Accept: text/html

                  и он так выглядит вне зависимости от того, по SSL/TLS он сделан или поверх голого TCP.


                  URI в данном случае /blog. POST-запросы с этой точки зрения выглядят точно также, только еще содержат тело. Так что ваша фраза:


                  На стороне nginx не реально воссоздать GET запрос и реальный IP-адрес клиента (какие данные точно не передаются сейчас не скажу). С телом POST и т. п. запросов проблем как раз не заметил

                  вообще лишена смысла.

                  Если вам обязательно знать, используется ли SSL/TLS или нет на соединении с клиентом с haproxy, так разнесите также эти соединения по разным портам. Пусть haproxy проксирует либо на один порт, либо на другой. В чем проблема?

                  Либо можно выкинуть haproxy, поставить nginx на его место — и тогда будет счастье. Всю информацию можно будет передавать в заголовках.


  1. Gasoid
    06.11.2016 00:22
    -1

    Docker в nginx:
    docker run nginx


    и никаких комплиляций


    1. kricha
      06.11.2016 00:25

      И не заработает.

      root@b1263efe36ca:/# nginx -v
      nginx version: nginx/1.11.5
      root@b1263efe36ca:/# openssl 
      OpenSSL> version
      OpenSSL 1.0.1t  3 May 2016
      OpenSSL> 
      


      1. zelenin
        06.11.2016 01:09
        +1

        все работает (в версии alpine)


  1. VBart
    06.11.2016 00:29
    +6

    Забавно наблюдать старательно сконфигурированный A+ в ssllabs и дырку в безопасности в виде:


    resolver 8.8.4.4 8.8.8.8;


    1. random1st
      06.11.2016 00:34

      поясните, пожалуйста


      1. VBart
        06.11.2016 00:45
        +6

        Процитирую документацию:

        Для предотвращения DNS-спуфинга рекомендуется использовать DNS-серверы в защищённой доверенной локальной сети.
        Встроенный резолвер заточен на производительность, для чего пришлось несколько пожертвовать безопасностью. Он не рассчитан на применение в незащищенных сетях. Не говоря уж о том, что задержка при обращении к гугловому серверу может сказаться на скорости обработки запроса, а его недоступность или неправильная работа и вовсе привести к недоступности вашего сервиса.


        1. birdy90
          06.11.2016 02:15

          И как это обходится? В смысле, как правильно?


          1. VBart
            06.11.2016 02:59

            Правильно использовать собственный DNS-сервер. Например, установленный на той же машине:

            resolver 127.0.0.1;
            


            1. birdy90
              06.11.2016 03:07

              благодарю! всегда считал, что dns в той или иной степени глобальны, теперь появился повод пересмотреть свои взгляды)


            1. Meklon
              06.11.2016 14:00

              Как проверить его работоспособность?


              1. kricha
                06.11.2016 14:05

                Цитирую VBart:

                nslookup example.org 127.0.0.1
                

                или
                dig example.org @127.0.0.1
                


                1. Meklon
                  06.11.2016 14:39

                  Спасибо. Логично. А резолвить что именно нужно? У меня на 192.168.100.1 на Mikrotik висит DNS кэширующий.


                  1. kricha
                    06.11.2016 14:45
                    +1

                    попробуй

                    $ cat /etc/resolv.conf 
                    nameserver some.ip
                    

                    а потом через тот ip любой реальный домен проверь.


                    1. Meklon
                      06.11.2016 14:53

                      Да, вроде нормально работает. Как раз Микротик отвечает. Второй ответ уже за 1 мс прилетает из-за кэширования.

                      P.S. Блин, обидно что второй раз в карму плюс бросить не могу) Видимо сделал это еще раньше) Спасибо еще раз.


  1. Vallefor
    06.11.2016 00:59
    +2

    Кстати, openssl 1.0.2 можно было тоже из debian-backports установить.
    И еще вопрос. А certbot теперь делает service nginx reload, после обновления сертификата? А то через 3 месяца может ждать сюрприз. 100% раньше не делал и в кроне приходилось дописывать эту строчку.


    1. xxxTy3uKxxx
      06.11.2016 02:11

      Есть --pre-hook и --post-hook


      1. Sheens
        06.11.2016 11:49

        Не подскажете, как их использовать конкретно в этом случае?


        1. xxxTy3uKxxx
          06.11.2016 13:43
          +2

          certbot-auto renew --pre-hook "service nginx stop" --post-hook "service nginx start"
          

          ну или рестартить на пост хуке


          1. Vallefor
            06.11.2016 14:18

            О, не знал, про хуки, спасибо.
            Останавливать и стартовать слишком жестко. Достаточно будет reload.


    1. kricha
      06.11.2016 08:48

      сам крон нет, только что глянул

      certbot
      $ cat /etc/cron.d/certbot 
      # /etc/cron.d/certbot: crontab entries for the certbot package
      #
      # Upstream recommends attempting renewal twice a day
      #
      # Eventually, this will be an opportunity to validate certificates
      # haven't been revoked, etc.  Renewal will only occur if expiration
      # is within 30 days.
      SHELL=/bin/sh
      PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
      
      0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew
      


    1. Sheens
      06.11.2016 11:47

      Что дописывали, не подскажете?


      1. kricha
        06.11.2016 11:54

        мне кажется вам хватит дописать

        && /etc/init.d/nginx reload
        


      1. Vallefor
        06.11.2016 14:23

        Да, в конце добавить:
        && service nginx reload
        или
        && systemctl reload nginx

        Если есть еще какие-то сервисы, которые используют сертификат (я, например, помнится, забыл про вебсокеты на nodejs), то их тоже надо релоуднуть.


  1. gmelikov
    06.11.2016 01:32
    +9

    Странно, почему в статье даже не сочли нужным объяснить поведение Chrome — чтобы в нём работал HTTP/2, nginx должен быть собран с версией openssl, которая поддерживает ALPN. А произошло это по причине отказа Chrome от поддержки NPN.

    Даже статья на Хабре уже была полгода назад конкретно про эту особенность… Если дублируете, то хотя бы пишите полностью причины.


    1. kricha
      06.11.2016 01:47
      -1

      В начале статьи указано, что беда в отказе Chrome от SPDY и NPN.


      1. gmelikov
        06.11.2016 02:31
        +2

        Спасибо за указание и мой первый минус:) Но я настойчив — стоило бы по подробнее описывать, прочитал всю статью, а это упустил.


        1. kricha
          06.11.2016 08:40
          +1

          Согласен, но у меня была немного другая цель) Но для вашего успокоения добавил пост от хромиум с обьяснениями.
          з.ы. минус не от меня.


        1. KlimovDm
          06.11.2016 09:18

          Может стоило бы просто внимательнее читать? В первом абзаце упоминание об этом было сложно пропустить.


  1. DiverOfDark
    06.11.2016 12:56
    +2

    Для Ubuntu по хорошему стоило бы делать что-то такое:

    apt-get source nginx
    dpkg build-package -b
    dpkg -i our-built-package.deb
    apt-mark hold our-built-package


    Сам развлекался тем что собирал nginx + ngx_pagespeed + ngx_brotli :)


    1. Vallefor
      06.11.2016 15:41

      Чем закончились эксперименты с ngx_pagespeed?


      1. DiverOfDark
        06.11.2016 21:55

        Завелось, работает, используем:)
        пример можно посмотреть на https://escapeteams.ru — позаходить под разными браузерами и посмотреть что он подставляет вместо картинок и стилей.
        в целом довольно прикольно, единственное — есть некоторые сложности с кэшем, иногда проблемы с его инвалидацией при деплое новой версии. Но впринципе решается rm -rf /tmp/ngx_pagespeed && /etc/init.d/nginx restart :).


        1. Vallefor
          07.11.2016 12:36

          Вот да, проблему с кешем тоже обнаружил.
          Но когда я сравнил нагрузку на проц (через apache benchmark) с включенным pagespeed и выключенным, то прям как-то призадумался.
          Я еще тогда экспериментировал с Google PageSpeed Insights и пытался понять, на сколько вообще возможно получить там 100 в скорости для мобил. Самое интересное, что даже на выделенном сервере, с одним сайтом, который в разработке, Google PageSpeed Insights часто ругался на то, что время ответа больше 0.2с. Кстати, у вас такая же проблема иногда появляется.

          100 баллов легкой кровью так и не получилось получить из-за ошибки:
          Удалите код JavaScript и CSS, блокирующий отображение верхней части страницы
          + ошибок на малое время кеширование сторонних скриптов (яндекс метрика, фейсбук и т.д.)

          Не то, что бы я считал Google PageSpeed Insights эталонным измерителем производительности.


          1. DiverOfDark
            07.11.2016 23:24

            У нас вообще адская схема — этот nginx проксирует всё на другой хост(хорошо хотя бы в том же регионе.), где крутится IIS+ASP.NET приложение, а это еще и сетевой лаг.

            Но в целом с точки зрения открытия сайта — на мой взгляд стало лучше. Всё-таки ngx_pagespeed делает всякие полезные вещи типа минификации/конвертации картинок под конкретные браузеры и прочее, это точно не то, о чем хотелось бы постоянно думать :).

            Меня тоже долго останавливало перенос js в днище сайта, но оказалась проблема больше психологическая чем технологическая — большая часть завелась практически без проблем.


            1. sumanai
              08.11.2016 08:39

              Меня тоже долго останавливало перенос js в днище сайта,

              Так для 100% требуется и стили перенести в низ, и часть из них, необходимую для отображения страницы до сгиба, встроить в саму страницу.


    1. Sleuthhound
      08.11.2016 15:25
      +4

      Согласен на все 100%
      Никогда не делайте make install на debian подобных дистрибутивах, вы потом заколебетесь вычищать систему от разного рода говна.

      Все гораздо проще:

      mkdir /opt/nginx && cd /opt/nginx
      wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz && tar -vzxf openssl-1.0.2j.tar.gz && rm openssl-1.0.2j.tar.gz
      apt-get source nginx && apt-get build-dep nginx
      cd nginx-1.11.5

      Открываем файл debian/rules
      в секцию config.status.nginx: config.env.nginx в параметр CFLAGS=
      после --with-stream_ssl_preread_module
      добавляем --with-openssl=/opt/nginx/openssl-1.0.2j
      в секцию config.status.nginx_debug: config.env.nginx_debug в параметр CFLAGS=
      после --with-stream_ssl_preread_module
      добавляем --with-openssl=/opt/nginx/openssl-1.0.2j

      Собираем nginx и модули:
      dpkg-buildpackage -b

      Устанавливаем nginx:
      dpkg -i nginx_1.11.5-1~jessie_amd64.deb

      Profit.


  1. zooks
    06.11.2016 14:38

    В принципе, информация не нова, но автору спасибо. Нужно периодически напоминать сообществу о том, что в вебе уже вовсю шагает HTTP/2. На всех своих проектах включил его больше года назад, с выходом нового Chrome пришлось перекомпилировать новый nginx.


  1. APXEOLOG
    06.11.2016 17:30

    Спасибо за статью, добавил поддержку http2 к своим сайтам. Правда не стал собирать nginx из исходников, ограничился установкой пакета из репозитория nginx (версия 1.11.5 для ubuntu)


  1. Dima4ka
    07.11.2016 06:11

    Кто-нибудь знает, openresty (NGINX + lua + modules) решает проблему?


  1. nikolayvaganov
    07.11.2016 10:20
    +1

    В конфиге правильной сборки много мусорных ключей "--with-http_dav_module --with-http_flv_module -with-mail --with-mail_ssl_module". Зачем они нужны, если в Вашей текущей конфигурации не используются?


    1. kricha
      07.11.2016 10:22

      я брал ключи из debian/rule, кому и что нужно — я не знаю, да и это ведь просто пример. Думаю, при целевом применении данной статьи, люди выбросят все ненужное)


  1. kolu4iy
    07.11.2016 12:53
    +1

    Debian jessie: подключаем debian-backports, ставим оттуда nginx-full и openssl (вместо ветки из main либо собственного репозитория nginx).

    Получаем:
    nginx version: nginx/1.9.10
    built with OpenSSL 1.0.2j 26 Sep 2016
    TLS SNI support enabled
    configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/build/nginx-1.9.10/debian/modules/nginx-auth-pam --add-module=/build/nginx-1.9.10/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-1.9.10/debian/modules/nginx-echo --add-module=/build/nginx-1.9.10/debian/modules/nginx-upstream-fair --add-module=/build/nginx-1.9.10/debian/modules/ngx_http_substitutions_filter_module

    SPDY индикатор в google chrome после этих процедур становится вполне себе синеньким, и рассказывает нам про HTTP/2 enabled.

    Как использовать backports (если кто не знает) — написано в Debian wiki