Программист PHP, GoLang, Python
0,0
рейтинг
27 марта 2015 в 17:34

Разработка → Добиваемся OCSP stapling = Yes для сертификатов от WoSign на Nginx

Доброго времени суток, Хабражители.
Прочитав статьи №1 и №2 (про бесплатные SSL сертификаты от китайских друзей WoSign столкнулся с тем, что многие не могут добиться OCSP stapling = Yes для этих сертификатов.
Хочу рассказать как этого добился я.

Мы получили сертификат WoSign, залили на сервер.
И так, приступим.

Во-первых — получаем промежуточные сертификаты.
cd /path/to/your/ssl/
wget -O - https://www.startssl.com/certs/ca.pem | tee -a ca-certs.pem > /dev/null 
wget -O - https://www.startssl.com/certs/sub.class1.server.ca.pem | tee -a ca-certs.pem > /dev/null 
wget -O - http://aia.startssl.com/certs/ca.crt | openssl x509 -inform DER -outform PEM | tee -a ca-certs.pem > /dev/null 
wget -O - http://aia1.wosign.com/ca1g2-server1-free.cer | openssl x509 -inform DER -outform PEM | tee -a ca-certs.pem > /dev/null 
wget -O - http://aia6.wosign.com/ca6.server1.free.cer | openssl x509 -inform DER -outform PEM | tee -a ca-certs.pem > /dev/null 


Во-вторых — в коняги Nginx'а добавляем
#########################################################
#
#
 ssl_session_cache shared:SSL:10m;
 ssl_session_timeout 5m;
 ssl_prefer_server_ciphers on;

 ssl_stapling on;
 ssl_stapling_verify on;
 ssl_trusted_certificate "/path/to/your/ssl/ca-certs.pem";

 resolver 8.8.8.8 8.8.4.4 valid=300s;
 resolver_timeout 5s;
#
#
#########################################################


В-третьих — в коняги домена прописываем для 443 порта в раздел server следующее:
        ssl on;
        ssl_certificate /path/to/your/ssl/ssl.crt;
        ssl_certificate_key /path/to/your/ssl/ssl.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        ssl_ciphers 'HIGH:!aNULL:!MD5:!kEDH';
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";


И напоследок — перезапускаем Nginx
service nginx restart


Теперь при проверке на SSL-тестере мы видим результат А+ и включенный OCSP stapling.
Так же можно проверить это прямо на сервере командой
openssl s_client -connect YourDomain.com:443 -tls1  -tlsextdebug  -status

Если в результате есть следующее,
то значит всё отлично!
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: C = CN, O = WoSign CA Limited, CN = WoSign Free SSL OCSP Responder(G2)
Produced At: Mar 27 14:30:05 2015 GMT
Responses:
Certificate ID:
Hash Algorithm: sha1
Issuer Name Hash: A06661F16CBCC23E98BC71914830B85AAA8D0A6B
Issuer Key Hash: D2A716207CAFD9959EEB430A19F2E0B9740EA8C7
Serial Number: 4C306486969BCBC1AE555A1D8C117B87
Cert Status: good
This Update: Mar 27 14:30:05 2015 GMT
Next Update: Mar 29 14:30:05 2015 GMT

Signature Algorithm: sha1WithRSAEncryption
7c:d8:e8:28:37:a3:2b:44:d2:30:f3:e5:a6:fa:9d:ff:1c:4a:
d9:33:43:a2:75:d6:f5:da:a1:47:f4:46:22:af:a2:54:a8:30:
cb:c8:6a:f9:1f:85:18:ee:c1:70:43:c9:08:61:cb:eb:b1:d6:
42:70:0f:e4:7b:dc:81:fb:f5:47:d1:02:b9:f4:bb:e4:5d:32:
57:75:8e:ca:15:95:4c:50:f3:2b:8f:94:ab:53:2d:a7:0a:b0:
3e:ab:d4:2b:fa:f1:8c:2e:00:46:e5:9b:d3:31:9f:e6:54:9d:
35:eb:20:95:b4:1a:12:7c:58:f2:f3:38:6b:fb:a6:1f:3c:cf:
fa:bc:f2:bb:92:e8:b0:41:37:84:31:ca:8c:44:73:60:8c:2f:
60:1f:7c:97:a8:7f:f0:b2:b3:8f:68:ce:3c:1d:9d:91:c9:88:
a7:bc:6e:91:93:68:de:6b:84:91:3e:34:7c:46:de:eb:71:9a:
76:f7:f8:87:d1:be:12:1b:7a:f0:3c:37:98:41:92:7a:6c:40:
87:3f:a1:f5:ef:d7:a3:1e:d2:34:3b:5d:f5:de:b9:a7:1d:a8:
da:f6:c0:2e:19:6f:e7:9c:96:78:3e:c7:a1:9d:f8:9d:09:81:
f0:5d:16:be:53:0c:cb:82:28:05:08:b2:cd:d6:5d:46:3c:ea:
cd:a1:e7:55


Вот результаты теста моего блога
В комментариях к вышеупомянутым статьям были попытки (очень похожие на мою), но неуспешные.
Я не навязываю бесплатные сертификаты, но всё же если платить не хочется — пользуйтесь!
Спасибо.
Максим Ковалёв @kovalyov_makc
карма
2,2
рейтинг 0,0
Программист PHP, GoLang, Python
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

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

  • 0
    wget -O - https://www.startssl.com/certs/ca.pem | tee -a ca-certs.pem > /dev/null

    я, может, придираюсь и вообще не в тему, но кусок выше режет глаза своей бессмысленностью. возможно, лучше так:
    wget -O ca-certs.pem https://www.startssl.com/certs/ca.pem
    • +1
      Все эти команды дописывают в конец файла содержимое сертификатов. Конечно, в первой команде можно сделать всё и так.
      • +1
        действительно. ну тогда, хотя бы так:
        wget -O - https://www.startssl.com/certs/sub.class1.server.ca.pem >> ca-certs.pem
        • –7
          За основу была взята ещё и статья из DigitalOcean
          • +2
            Коли уж даёте рефералки, давайте две ссылки — чистую и с реферальным кодом. Просто чтобы был выбор.
            • 0
              Спасибо, на будущее учту.
  • 0
    Прежде всего, спасибо за статью!
    Однако, не работает.
    По вашей ссылке, где проверка вашего блога на ssllabs:
    OCSP stapling No


    Я попробовал у себя ваш способ. Результат такой же.
    При обращении к серверу в error.log nginx пишет следующее:
    OCSP responder prematurely closed connection while requesting certificate status, responder: ocsp6.wosign.com

    Я еще пробовал в ручную запрашивать ocsp-ответ от китайцев и подсовывать в nginx ocsp-файл примерно так:
    ssl_stapling_file /opt/cert/example.com.ocsp;
    Вот в таком случае ssllabs говорит YES, но вот Firefox отказывается ходить на такой сайт со словами «в ocsp-ответе нет информации о запрашиваемом сертификате».
    Еще я пробовал в ручную заставить nginx ходить за ocsp-запросами по урлу:
    ssl_stapling_responder ocsp6.wosign.com/ca6/server1/free;

    Этот урл я взял, из сертификата.
    В таком случае он ругается в логах так:
    OCSP responder sent invalid «Content-Type» header: «text/html» while requesting certificate status, responder: ocsp6.wosign.com
    OCSP responder prematurely closed connection while requesting certificate status, responder: ocsp6.wosign.com

    Ну и соответственно, результат отрицательный.

    У кого еще есть идеи? Может быть у кого получилось сделать правильный ocsp-файл?

    P.S.: Кстати, wosign отсылает промежуточные сертификаты вместе с запрошенным в одном zip файле, так что качать их со startssl не обязательно.
    • 0
      Перепроверил блог — всё нормально. Yes. Видимо всё же китайские сервера не всегда отдают ответ. Какая версия Nginx и ОС у вас установлена?
      • 0
        nginx/1.4.6 (Ubuntu)
        • 0
          На этой версии Nginx действительно не работает. Обновите до 1.6.2 (стабильной) или 1.7.11(mainline)
  • +3
    Тоже решил завести OCSP Stapling для на своем тестовом сервере для WoSign, но ничего не помогало.
    nginx в error.log'е ругался на не правильный тип ответа:
    2015/03/27 21:07:18 [error] 21722#0: OCSP responder sent invalid "Content-Type" header: "text/html" while requesting certificate status, responder: ocsp6.wosign.com

    Не долго думая, решил посмотреть на трафик к OCSP Responder'у:
    $ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    00:00:00.000000 IP (tos 0x0, ttl 64, id 51790, offset 0, flags [DF], proto TCP (6), length 60)
        10.0.0.234.34479 > 104.192.110.199.80: Flags [S], cksum 0xe29f (incorrect -> 0x42a6), seq 3856552277, win 29200, options [mss 1460,sackOK,TS val 1468635931 ecr 0,nop,wscale 7], length 0
    00:00:00.164134 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 52)
        104.192.110.199.80 > 10.0.0.234.34479: Flags [S.], cksum 0x756a (correct), seq 3408811202, ack 3856552278, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 7], length 0
    00:00:00.000018 IP (tos 0x0, ttl 64, id 51791, offset 0, flags [DF], proto TCP (6), length 40)
        10.0.0.234.34479 > 104.192.110.199.80: Flags [.], cksum 0xe28b (incorrect -> 0xee57), seq 1, ack 1, win 229, length 0
    00:00:00.000213 IP (tos 0x0, ttl 64, id 51792, offset 0, flags [DF], proto TCP (6), length 213)
        10.0.0.234.34479 > 104.192.110.199.80: Flags [P.], cksum 0xe338 (incorrect -> 0x1006), seq 1:174, ack 1, win 229, length 173: HTTP, length: 173
       GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d HTTP/1.0
       Host: ocsp6.wosign.com
       
    00:00:00.163712 IP (tos 0x0, ttl 50, id 16259, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.80 > 10.0.0.234.34479: Flags [.], cksum 0xee14 (correct), seq 1, ack 174, win 123, length 0
    00:00:00.000377 IP (tos 0x0, ttl 50, id 16260, offset 0, flags [DF], proto TCP (6), length 365)
        104.192.110.199.80 > 10.0.0.234.34479: Flags [P.], cksum 0xc7d3 (correct), seq 1:326, ack 174, win 123, length 325: HTTP, length: 325
       HTTP/1.1 502 Bad Gateway
       Server: nginx/1.0.15
       Date: Fri, 27 Mar 2015 18:25:22 GMT
       Content-Type: text/html
       Content-Length: 173
       Connection: close
       
       <html>
       <head><title>502 Bad Gateway</title></head>
       <body bgcolor="white">
       <center><h1>502 Bad Gateway</h1></center>
       <hr><center>nginx/1.0.15</center>
       </body>
       </html>
    00:00:00.000012 IP (tos 0x0, ttl 64, id 51793, offset 0, flags [DF], proto TCP (6), length 40)
        10.0.0.234.34479 > 104.192.110.199.80: Flags [.], cksum 0xe28b (incorrect -> 0xec5d), seq 174, ack 326, win 237, length 0
    00:00:00.000006 IP (tos 0x0, ttl 50, id 16261, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.80 > 10.0.0.234.34479: Flags [F.], cksum 0xecce (correct), seq 326, ack 174, win 123, length 0
    00:00:00.000604 IP (tos 0x0, ttl 64, id 51794, offset 0, flags [DF], proto TCP (6), length 40)
        10.0.0.234.34479 > 104.192.110.199.80: Flags [F.], cksum 0xe28b (incorrect -> 0xec5b), seq 174, ack 327, win 237, length 0
    00:00:00.163723 IP (tos 0x0, ttl 50, id 16262, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.80 > 10.0.0.234.34479: Flags [.], cksum 0xeccd (correct), seq 327, ack 175, win 123, length 0

    Отлично:-( Смотрим в RFC 6960:
    HTTP-based OCSP requests can use either the GET or the POST method to
    submit their requests. To enable HTTP caching, small requests (that
    after encoding are less than 255 bytes) MAY be submitted using GET.
    If HTTP caching is not important or if the request is greater than
    255 bytes, the request SHOULD be submitted using POST. Where privacy
    is a requirement, OCSP transactions exchanged using HTTP MAY be
    protected using either Transport Layer Security/Secure Socket Layer
    (TLS/SSL) or some other lower-layer protocol.

    An OCSP request using the GET method is constructed as follows:

    GET {url}/{url-encoding of base-64 encoding of the DER encoding of
    the OCSPRequest}

    where {url} may be derived from the value of the authority
    information access extension in the certificate being checked for
    revocation, or other local configuration of the OCSP client.

    An OCSP request using the POST method is constructed as follows: The
    Content-Type header has the value «application/ocsp-request», while
    the body of the message is the binary value of the DER encoding of
    the OCSPRequest.

    С виду запрос от nginx полностью соответствует RFC. Немного поиграем:
    # Пробуем запрос полученный от nginx
    $ http -v http://ocsp6.wosign.com/ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d
    GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Host: ocsp6.wosign.com
    User-Agent: HTTPie/0.9.2
    
    
    
    HTTP/1.1 502 Bad Gateway
    Connection: keep-alive
    Content-Length: 173
    Content-Type: text/html
    Date: Sat, 28 Mar 2015 09:14:25 GMT
    Server: nginx/1.0.15
    
    <html>
    <head><title>502 Bad Gateway</title></head>
    <body bgcolor="white">
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.0.15</center>
    </body>
    </html>
    
    
    # Пробуем запрос без урлкодирвоания
    $ http -v http://ocsp6.wosign.com/ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY\=
    GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY= HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Host: ocsp6.wosign.com
    User-Agent: HTTPie/0.9.2
    
    
    
    HTTP/1.0 200 OK
    Connection: close
    Content-Length: 1514
    Content-Transfer-Encoding: Binary
    Content-Type: application/ocsp-response
    Date: Mar 28 09:14:29 2015 GMT
    Expires: Mar 30 09:14:29 2015 GMT
    
    
    
    +-----------------------------------------+
    | NOTE: binary data not shown in terminal |
    +-----------------------------------------+
    
    
    # Пробуем отправить POST запрос вместо GET
    $ http -v post http://ocsp6.wosign.com/ca6/server1/free/ < ocsp
    POST /ca6/server1/free/ HTTP/1.1
    Accept: application/json
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Content-Length: 83
    Content-Type: application/json
    Host: ocsp6.wosign.com
    User-Agent: HTTPie/0.9.2
    
    
    
    +-----------------------------------------+
    | NOTE: binary data not shown in terminal |
    +-----------------------------------------+
    
    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 1514
    Content-Transfer-Encoding: Binary
    Content-Type: application/ocsp-response
    Date: Sat, 28 Mar 2015 09:14:37 GMT
    Expires: Mar 30 09:14:37 2015 GMT
    Server: nginx/1.0.15
    
    
    
    +-----------------------------------------+
    | NOTE: binary data not shown in terminal |
    +-----------------------------------------+
    


    Хм, любопытно. Похоже на расхождение логики nginx и OCSP Responder'а WoSign — первый считает OCSPRequest компонентом URI, поэтому закодировал не только основные разделители но и дополнительные (= в нашем случае), вторые же на это видимо не расчитывают.
    Я нашел два варианта решения этой проблемы:
    1. Скучный — исправить урл. Просто заменить ssl_stapling_responder на свой и с него уже запроксировать на ocsp6.wosign.com.
    Добавляем сервер:
    server {
            listen 9000;
            server_name ocsp.localhost;
    
            location / {
                return 503;
            }
    
            location ~ ^/request/(.*)$ {
                allow 127.0.0.1;
                deny  all;
                proxy_pass http://ocsp6.wosign.com/ca6/server1/free/$1;
            }
     }
    

    В настройках заменяем адрес OCSP Responder'а:
    ssl_stapling_responder 'http://127.0.0.1:9000/request/';
    

    Делаем тестовый запрос и смотрим на трафик:
    $ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    09:51:34.631598 IP (tos 0x0, ttl 64, id 27478, offset 0, flags [DF], proto TCP (6), length 60)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [S], cksum 0xe29f (incorrect -> 0x44ab), seq 2011672765, win 29200, options [mss 1460,sackOK,TS val 4709355 ecr 0,nop,wscale 7], length 0
    09:51:34.801707 IP (tos 0x0, ttl 51, id 0, offset 0, flags [DF], proto TCP (6), length 52)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [S.], cksum 0x40b8 (correct), seq 187184398, ack 2011672766, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 7], length 0
    09:51:34.801728 IP (tos 0x0, ttl 64, id 27479, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb9a5), seq 1, ack 1, win 229, length 0
    09:51:34.802596 IP (tos 0x0, ttl 64, id 27480, offset 0, flags [DF], proto TCP (6), length 230)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [P.], cksum 0xe349 (incorrect -> 0xe51a), seq 1:191, ack 1, win 229, length 190: HTTP, length: 190
      GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY= HTTP/1.0
      Host: ocsp6.wosign.com
      Connection: close
      
    09:51:34.972743 IP (tos 0x0, ttl 51, id 22415, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xb951 (correct), seq 1, ack 191, win 123, length 0
    09:51:34.974872 IP (tos 0x0, ttl 51, id 22416, offset 0, flags [DF], proto TCP (6), length 1500)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xbf3d (correct), seq 1:1461, ack 191, win 123, length 1460: HTTP, length: 1460
      HTTP/1.1 200 OK
      Server: nginx/1.0.15
      Date: Sat, 28 Mar 2015 09:51:34 GMT
      Content-Type: application/ocsp-response
      Connection: close
      Content-Transfer-Encoding: Binary
      Content-Length: 1514
      Expires: Mar 30 09:51:34 2015 GMT
      
    09:51:34.974887 IP (tos 0x0, ttl 64, id 27481, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb31d), seq 191, ack 1461, win 251, length 0
    09:51:34.975080 IP (tos 0x0, ttl 51, id 22417, offset 0, flags [DF], proto TCP (6), length 324)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [P.], cksum 0xb6de (correct), seq 1461:1745, ack 191, win 123, length 284: HTTP
    09:51:34.975089 IP (tos 0x0, ttl 64, id 27482, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb1ea), seq 191, ack 1745, win 274, length 0
    09:51:34.975096 IP (tos 0x0, ttl 51, id 22418, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [F.], cksum 0xb280 (correct), seq 1745, ack 191, win 123, length 0
    09:51:34.977809 IP (tos 0x0, ttl 64, id 27483, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [F.], cksum 0xe28b (incorrect -> 0xb1e8), seq 191, ack 1746, win 274, length 0
    09:51:35.147834 IP (tos 0x0, ttl 51, id 22419, offset 0, flags [DF], proto TCP (6), length 40)
        104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xb27f (correct), seq 1746, ack 192, win 123, length 0
    

    Выглядит работоспособным. Тест так же говорит что OCSP Stapling работает

    2. Интересный:) Будучи программистом — мне больше нравится исправлять код, нежели раставлять костыли в конфигах. Поэтому я сделал простой патч gist.github.com/buglloc/6f14a16ab702478d23e3 который добавляет булевую опцию ssl_stapling_force_post по которой nginx начинает делать POST запрос вместо GET.
    # Скачиваем nginx. Я пользую последнюю стабильную версию
    $ wget http://nginx.org/download/nginx-1.6.2.tar.gz
    
    # Распаковываем
    $ tar -xzf nginx-1.6.2.tar.gz
    
    # Скачиваем патч
    $ wget https://gist.githubusercontent.com/buglloc/6f14a16ab702478d23e3/raw/4779a940a0040857ecbc7eea410f7f34fc1f5627/post-ocsp-nginx.patch
    
    # Применяем патчик
    $ patch -p 1 -d nginx-1.6.2 < post-ocsp-nginx.patch
    patching file src/event/ngx_event_openssl.h
    patching file src/event/ngx_event_openssl_stapling.c
    patching file src/http/modules/ngx_http_ssl_module.c
    patching file src/http/modules/ngx_http_ssl_module.h
    
    
    # Смотрим как собран текущий nginx
    $ nginx -V
    nginx version: nginx/1.6.2
    built by gcc 4.9.2 20150304 (prerelease) (GCC) 
    TLS SNI support enabled
    configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-imap --with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module
    
    # Собираем и ставим
    $ cd nginx-1.6.2
    
    $ ./configure --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-imap --with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module
    
    $ make
    
    $ sudo make install
    

    После этого идем в настройки и добавляем:
    ssl_stapling_force_post on;

    Перезапускаем nginx и опять смотрим на трафик:
    $ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    10:04:04.626853 IP (tos 0x0, ttl 64, id 23709, offset 0, flags [DF], proto TCP (6), length 60)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [S], cksum 0xbd23 (incorrect -> 0x32b9), seq 3842006142, win 29200, options [mss 1460,sackOK,TS val 4784355 ecr 0,nop,wscale 7], length 0
    10:04:05.016292 IP (tos 0x0, ttl 46, id 0, offset 0, flags [DF], proto TCP (6), length 52)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [S.], cksum 0xea1a (correct), seq 1986999145, ack 3842006143, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 9], length 0
    10:04:05.016324 IP (tos 0x0, ttl 64, id 23710, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x630a), seq 1, ack 1, win 229, length 0
    10:04:05.017243 IP (tos 0x0, ttl 64, id 23711, offset 0, flags [DF], proto TCP (6), length 243)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [P.], cksum 0xbdda (incorrect -> 0x121b), seq 1:204, ack 1, win 229, length 203: HTTP, length: 203
      POST /ca6/server1/free/ HTTP/1.0
      Host: ocsp6.wosign.com
      Content-Type: application/ocsp-request
      Content-Length: 83
      
    10:04:05.409413 IP (tos 0x0, ttl 46, id 13576, offset 0, flags [DF], proto TCP (6), length 40)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x6305 (correct), seq 1, ack 204, win 31, length 0
    10:04:05.411395 IP (tos 0x0, ttl 46, id 13577, offset 0, flags [DF], proto TCP (6), length 133)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [P.], cksum 0xc2f9 (correct), seq 1:94, ack 204, win 31, length 93: HTTP, length: 93
      HTTP/1.0 200 OK
      Content-Type: application/ocsp-response
      Content-Transfer-Encoding: Binary
    10:04:05.411412 IP (tos 0x0, ttl 64, id 23712, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x61e2), seq 204, ack 94, win 229, length 0
    10:04:05.411551 IP (tos 0x0, ttl 46, id 13578, offset 0, flags [DF], proto TCP (6), length 1500)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x2eea (correct), seq 94:1554, ack 204, win 31, length 1460: HTTP
    10:04:05.411561 IP (tos 0x0, ttl 64, id 23713, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x5c18), seq 204, ack 1554, win 251, length 0
    10:04:05.411587 IP (tos 0x0, ttl 46, id 13579, offset 0, flags [DF], proto TCP (6), length 204)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [FP.], cksum 0x9869 (correct), seq 1554:1718, ack 204, win 31, length 164: HTTP
    10:04:05.414802 IP (tos 0x0, ttl 64, id 23714, offset 0, flags [DF], proto TCP (6), length 40)
        ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [F.], cksum 0xbd0f (incorrect -> 0x5b5b), seq 204, ack 1719, win 274, length 0
    10:04:05.802684 IP (tos 0x0, ttl 46, id 13580, offset 0, flags [DF], proto TCP (6), length 40)
        111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x5c4e (correct), seq 1719, ack 205, win 31, length 0
    

    Выглядит корректным, проверяем:
    $ echo QUIT | openssl s_client -connect www.buglloc.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:'
    OCSP response: 
    ======================================
    OCSP Response Data:
        OCSP Response Status: successful (0x0)
        Response Type: Basic OCSP Response
        Version: 1 (0x0)
        Responder Id: C = CN, O = WoSign CA Limited, CN = WoSign Free SSL OCSP Responder(G2)
        Produced At: Mar 28 10:04:05 2015 GMT
        Responses:
        Certificate ID:
          Hash Algorithm: sha1
          Issuer Name Hash: A06661F16CBCC23E98BC71914830B85AAA8D0A6B
          Issuer Key Hash: D2A716207CAFD9959EEB430A19F2E0B9740EA8C7
          Serial Number: 46F19D5B9022E620E1CA4236955C9476
        Cert Status: good
        This Update: Mar 28 10:04:05 2015 GMT
        Next Update: Mar 30 10:04:05 2015 GMT
    


    Надеюсь кому-то поможет. Я старался обойтись минимальными правками и вроде достаточно внимательно поправил код. Конечно, скорее более правильно было бы сделать как современные браузеры (которые славятся своей «приспосабливаемостью»;) — они зачастую сначала шлют GET и в случае провала пытаются сделать POST запрос. Но патч получился бы менее легким и читабельным, поэтому я не стал этого делать.
    • 0
      Странно то, что у меня как на иностранном (DigitalOcean), так и на отечественном (InfoBox) серверах всё завелось без проблем.
      • 0
        Мне кажется, что вы просто этого не замечаете за счет некого везения:-) И поэтому у вас в тестах иногда все хорошо (в ваших), а иногда (как писали выше в комментах) плохо:-)

        Вот сейчас для вашего домена у меня получается запрос к WoSign без доп. символов "/+=" (подлежащий кодированию при NGX_ESCAPE_URI_COMPONENT) алфавита base64, поэтому все и работает:
        $ openssl ocsp -issuer chain.pem -cert kai.pem -text -url http://ocsp6.wosign.com/ca6/server1/free -header "HOST" "ocsp6.wosign.com" -reqout ocsp_req -respout ocsp_rep > /dev/null
        
        $ cat ocsp_req | base64 -w 0
        MHYwdDBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQUTgvvGqRAW6UXaYcwyjRoQ9BBrvICEEwwZIaWm8vBrlVaHYwRe4eiIzAhMB8GCSsGAQUFBzABAgQSBBCvSssLj9nA8Qe1nuXN8yry
        
        $ http http://ocsp6.wosign.com/ca6/server1/free/MHYwdDBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQUTgvvGqRAW6UXaYcwyjRoQ9BBrvICEEwwZIaWm8vBrlVaHYwRe4eiIzAhMB8GCSsGAQUFBzABAgQSBBCnEPCW98JQIKmStIdgyEP4
        HTTP/1.1 200 OK
        Connection: keep-alive
        Content-Length: 1514
        Content-Transfer-Encoding: Binary
        Content-Type: application/ocsp-response
        Date: Sat, 28 Mar 2015 10:35:35 GMT
        Expires: Mar 30 10:35:35 2015 GMT
        Server: nginx/1.0.15
        
        
        
        +-----------------------------------------+
        | NOTE: binary data not shown in terminal |
        +-----------------------------------------+
        
        

        Поэтому за счет периодического везения у вас сложилось впечатление что все работает, т.к. nginx кеширует валидный ocsp-ответ на 1 час, а не валидный на 5 минут.
    • 0
      Спасибо огромное!
      Первый(скучный) вариант работает на ура.
      Патчить nginx не стал.

      Кой что добавлю:
      listen 127.0.0.1:9000;
      access_log off;


      Первое — чтобы порт наружу не светился, второе — чтобы не мусорило в логи.
      • 0
        Должен попросить у вас прощения. Скучное решение будет работать не во всех кейсах (в частности если в base64-кодированной строке будет "/").

        Лучшим решением проблемы с OCSP Stapling'ом и WoSign — обновить nginx 1.7.11 (можно и ниже, просто не имеет смысла, ибо если уж обновлять до mainline то до текущего), там судя по коду все должно завестить без патчей и костылей (если не вылазить за 255 байт в закодированном OCSP-запросе) :-)
        • 0
          Может вы предложите свой патч в багтрекере nginx?
        • 0
          Продолжаем разговор. (ц) Карлсон.

          Хоть скучное решение и работало вчера, но…
          Обновился до 1.7.11. Теперь openssl s_client показывает
          ocsp-response, но вот ssllabs все равно говорит NO.
          При этом openssl показывает ocsp-response только
          со второго(после рестарта) коннекта, но это, как я
          понимаю изза очень медленных китайцев.
          Тем не менее, не понимаю почему ssllabs его не видит…

          Кстати, а globalsign говорит YES…
          • 0
            а вы вернули обратно настройки, как было до конфиг-костыля?
            • 0
              да
              • 0
                SSL Labs делает запрос с указанием -servername без www, может в этом дело?

                true | openssl s_client -servername example.com -connect www.example.com:443 -status
                true | openssl s_client -servername www.example.com -connect www.example.com:443 -status


                Сравните вывод.
                • 0
                  Нет, дело было не в этом.
                  Вот тут: habrahabr.ru/post/254231/#comment_8351591 ответили в чем дело.
                  Nginx асинхронно отправляет ocsp-запрос, по этому первые коннекты идут без ocsp-response.
                  Сейчас уже все работает как нужно.
                  • 0
                    Понятно. Это как раз таки известное дело.

                    Другой глюк есть (был?) если на умолчальном виртуальном хосте нет OCSP, а на вторичных есть.
                    • 0
                      На stable nginx он есть.
          • 0
            При этом openssl показывает ocsp-response только
            со второго(после рестарта) коннекта, но это, как я
            понимаю изза очень медленных китайцев.
            Если вы имеете ввиду ocsp response в рамках ssl_stapling от nginx'а, то после перезапуска запрос надо делать 2 раза не из-за медленных китайцев/американцев/кого-нибудь ещё.
            Это стандартное поведение nginx'а, которое описано в каждой первой инструкции. При первом запросе nginx отвечает без ocsp_stapling и асинхронно пытается его получить. Если ему это удается, то в следующий раз он отдаёт ocsp response.
    • 0
      Спасибо большое за ответ на вопрос почему все-таки оно не работает:)
      Попробывал вариант 1.
      Тоже не помогло.

      В логах он рапортует, что URL все-равно заканчивается на злосчастные '...%3d'
      Замена вручную на '\=' или '=' дает желаемый результат.

      т.е. в ocsp прокси параметр уже попадает неправильным и неправильным передается на ocsp6.wosign.com/ca6/server1/free/, соответственно получаем исходный результат.

      Интересно, на основе чего и как он формируется?
  • 0
    А не у кого не наблюдается нашествия китайцев после получения и установки такого бесплатного сертификата?
    Сегодня поставил на сайт проактивка битрикса часа через 4 взвыла. 17 ip уже заблокировано.
    • 0
      Не больше, чем обычно — denyhosts пять-десять айпишников в течение пары часов как банил, так и банит. В основном, лезут в ssh.
  • 0
    Что-то вы зря, КМК, выписали столько поддоменов в один сертификат, тем самым, сдав их все.
    • 0
      Хм, а как же золотое правило избегания «sequrity by obscurity»?
      • 0
        Да я не про то — можно было несколько сертификатов выписать, чтобы не палить все поддомены.
        На худой конец, на фронт можно было выписать StartSSL, а на остальное — WoSign. Колхоз, зато лишний раз не палимся.
        • 0
          Да, Вы правы. Один сертификат на много доменов — не айс. Но я делал это ради эксперимента. в ближайшее время верну всё на место.
        • 0
          лишний раз не палимся

          Так это и есть obscurity, разве не так?

          StartSSL и WoSign имеют разные политики аннулирования сертификатов. У StartSSL — оно платное, у WoSign как мне кажется — нет.

          Если уж и выписывать разные сертификаты, то к разным ключам и эти ключи должны соответствовать разным группам безопасности доменов. Таким образом, если будет скомпрометирован ключ тех доменов, по которым ходят пользователи, то трафик, например, администраторов останется в безопасности.
          • 0
            У StartSSL можно с другого имейла заверифаить домен, и выписать новый сертификат.
            Они никак не проверяют существование другого сертификата на этот же хост. Проверял лично.
            • 0
              У WoSign тоже можно на один домен несколько сертификатов заказывать. Проверено лично.
            • 0
              У StartSSL можно с другого имейла заверифаить домен, и выписать новый сертификат.

              Таким образом вы никак не улучшите ситуацию со скомпрометированным и неотозванным сертификатом. Разве что вы не используете Public Key Pinning для своих конечных сертификатов, что вроде как не очень рекомендуется…
            • 0
              Они никак не проверяют существование другого сертификата на этот же хост

              Кстати, недавно пробовал получить второй сертификат на другие поддомены, и как ни странно у меня ничего не получилось (правда использовал тот-же имейл). Получил письмо с сообщением, что у вас что-то странное и мы с вами свяжемся. В результате никто не связался…

              У WoSign тоже можно на один домен несколько сертификатов заказывать

              Подтверждаю.
              • 0
                Главное, просто другой брать имейл для проверки (hostmaster вместо postmaster, например), с одновременной выдачей нового приватного ключа. Тогда — прокатывает.
                • 0
                  Спасибо, буду иметь в виду.

                  В любом случае, платность отзыва в StartSSL меня лично не очень устраивает. Хотя при серьезной атаке, отзыв сертификата вроде как не очень поможет
          • 0
            А доменные имена можно и так при желании узнать при помощи брутфорс атаки по словарю.
            Для этого даже писать ничего не надо, гугл выдает вагон софта по запросу «bruteforce subdomains»
            • 0
              Мы с вами про разные вещи говорим.
              Проводя аналогию, я утверждаю, что даже в российского производства машине стоит закрывать двери на замок, в то время как вы указываете на бесполезность сего мероприятия, ибо дверь всё равно открывается куском жёсткой проволоки.
              • 0
                Мы с вами про разные вещи говорим.

                Не думаю…

                Если пользоваться вашей аналогией, я скорее имею в виду, что не стоит на машине закрашивать замок краской цвета остальной двери, чтобы злоумышленник его не смог заметить. Замок-то все-равно есть.
  • 0
    del
  • 0
    Советую провериться через sslcheck.globalsign.com/ru
    Мне помогло выявить проблему с цепочкой (Chain issues). Там объясняет почему так и выдаёт рекомендации.

    Теперь у меня:
    В ssl_trusted_certificate 4 серта.
    В ssl_certificate 3 серта.
    Все они расположены в порядке который рекомендует globalsign.
    После этого ssllabs.com начал отдавать Chain issues: none.
    Что касается OCSP stapling Yes, то у wosign бывают проблемы и ssllabs говорит что No, но стоит пару раз обновить результат как скажет Yes.

    Единственно, когда я выполняю
    openssl s_client -connect домен:443 -tls1 -tlsextdebug -status
    мне показывает:
    verify error:num=20:unable to get local issuer certificate
    verify return:0
    А так всё нормально.
    • 0
      verify error:num=20:unable to get local issuer certificate
      Оказывается надо просто было добавить путь до сертификатов в запросе openssl и ошибка исчезнет, в общем это не касается правильности и всё хорошо.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.