1
14 Apr 2016 23:00:36

Как сделать свой сертификат SSL доверенным

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

Содержание:

Информация о проблеме

Само сообщение об ошибке выглядит так:


 

Вступление, как это работает (много деталей, если вы знаете принцип работы можете пропустить эту часть)

Причины такого поведения браузера

  Почему так происходит? Происходит это потомучто вы создали SSL сертификат и этот сертификат либо неподписан никем, либо он все же подписан, но браузер не верит подписи которой подписан ваш сертификат. Т.е. это соединение использует протокол шифрования и оно защищено, но не понятно можно ли доверять удаленному серверу куда вы можете посылать ваши защищенные криптографически важные данные.

Иными словами есть Client SSL сертификат и еще один SSL сертификат который подписывает ваш сертификат (Client) который использует вэб сервер или другое приложение которое защищает свои данные с помощью SSL. Он называется CA - Certificate authority сертификат.

Это значит что есть какое-то сообщество которое поставило свою подпись (своим CA сертификатом) на чей-либо другой сертификат (Client сертификат) и говорит о том что он безопасен и людям или машинам которые используют этот (Client) сертификат (подписанный CA сертификатом) можно верить. Однако ваш браузер не верит этому сообществу если оно не добавлено в начальный список сообществ которым браузер доверяет по умолчанию при установке.

Способы решения проблемы 

Можно сделать просто - сказать браузеру - верь этому сообществу, т.е. ответственность за доверие вы берете на себя, говоря - я верю этому сообществу, браузер или любой другой SSL клиент будет вас слушать и любые сертификаты подписанные CA SSL сертификатом, который вы добавили в браузер будут отображаться зеленым - т.е. как доверенные.

Какая здесь проблема? Проблема в том что другие люди которые пользуются вашим ресурсом через SSL будут по умолчанию не доверять CA сертификату созданному вами и видеть сообщение об ошибке. Однако если у вас корпоративная сеть то этот сертификат можно доверить в одном месте и все клиенты сети не будут испытывать проблемы.

Также если вы хотите чтобы все клиенты сети по умолчанию доверяли вашему ресурсу, то как возможно вы уже догадались вам необходимо иметь SSL сертификат, который подписан сообществом которому браузер по умолчанию доверяет.

Дополнительная информация о возможных способах устранения проблемы

  Возможно, но это не точно - есть способ в Client сертификате сделать так чтобы браузер отправлял запрос о доверии на сервер, который указан в Client SSL сертификате, чтобы не настраивать каждый раз свою сеть, а поднять на сервере сервис который будет говорить что доверяет вашему CA сертификату, но эта информация не точна и выглядит сомнительной. Т.к. это работает немного по другому - изначально браузер верит определенным CA сообществам и когда проверяется SSL тунель, браузер в сертификате который используется тунелем проверят наличие подписи, если она есть он опрашивает все доверенные CA на возможность доверять этому CA сертификату туннеля, который подписал сам SSL Client сертификат который использует туннель. В свою очередь каждое CA сообщетво (предопределенное в браузере) может иметь древовидную систему, т.е. оно может делегировать право подписи (доверия) другому менее значимому CA, а то в свою очередь другому и так далее, и если кто-то из них кому доверяет главное CA говорит что этот сертификат доверен, то запрос отправляется назад по лестнице к изначальному CA и оно отвечает вашему браузеру - да, сертификат безопасен. 

Заключение, или что нужно сделать минимально чтобы решить проблему

  Тоесть, чтобы все работало или локально или глобально нужно для начала иметь Client SSL сертификат, и CA SSL сертификат которым вы должны подписать ваш Client SSL сертификат. Остальное относится к тому как вы будете доверять CA сертификату, через посредников или вручную вносить его в сам браузер, но первые ступени этого процесса общие для этих двух решений.

Поскольку дальшейшее изучение темы - как сделать свой сертификат по умолчанию доверенным для всех пользователей сети (глобально) не входило в мою задачу (да и выглядит это сомнительным, если только не пройти необходимую процедуру в доверенных CA или подписать свой CA их CA сертификатом) я не изучал этот вопрос в этом контексте, но ниже поделюсь с вами как сделать ваши соеденения доверенными (о чем говорилось в первой части вступления - т.е. создать CA, подписать им свой SSL сертификат и вручную добавить CA которым вы подписали свой SSL сертификат в браузер как доверенный).

Практическое руководство для настройки самоподписанного SSL сертификата и устранения проблем с предупреждением браузера


 

mkdir /etc/ssl/openssl

cd /etc/ssl/openssl

​mkdir private
mkdir certs
mkdir crl
mkdir newcerts

# Создадим файлы которые будет использовать openssl
touch serial
touch index.txt

ls
certs/  crl/  index.txt  newcerts/  openssl.cnf  private/  serial
vim openssl.cnf
 
  • Здесь вы должны указать свои данные, чтобы каждый раз не вводить их при создании ключа, также здесь есть важная строка "commonName_default", она используется при проверке браузером вашего SSL Client сертификата и если домены не совпадают бразуер выдаст ошибку, т.к. будет считать это атакой (попыткой использовать сертификат от другого домена)
  
# OpenSSL root CA configuration file.
# Copy to `/etc/ssl/openssl/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /etc/ssl/openssl
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca.key
certificate       = $dir/certs/ca.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
#policy            = policy_strict

#[ policy_strict ]
## The root CA should only sign intermediate certificates that match.
## See the POLICY FORMAT section of `man ca`.
#countryName             = match
#stateOrProvinceName     = match
#organizationName        = match
#organizationalUnitName  = optional
#commonName              = supplied
#emailAddress            = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca
[ req_distinguished_name ]
# See .
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = RU
stateOrProvinceName_default     = Novosibirskay Oblast
localityName_default            = Novosibirsk
0.organizationName_default      = your_company
organizationalUnitName_default  = company
commonName_default              = your_domain.org
emailAddress_default            = your_mail

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
​# Create CA private key.
openssl genrsa -out private/ca.key 2048
# Create CA certificate for signing client certificates.
openssl req -x509 -config openssl.cnf -new -nodes -key private/ca.key -sha256 -days 1024 -out certs/ca.cert.pem
openssl genrsa -out private/localhost.key 2048
openssl req -config openssl.cnf -new -key private/localhost.key -out certs/localhost.csr
openssl x509 -req -in certs/localhost.csr -CA certs/ca.cert.pem -CAkey private/ca.key -CAcreateserial -out certs/localhost.crt -days 1024 -sha256
openssl x509 -noout -text -in certs/ca.cert.pem
openssl verify -CAfile certs/ca.cert.pem certs/localhost.crt


На этой части наши ключи готовы, приватные ключи никому не нужно передавать иначе вы дадите ключ от своего дома в чужие руки. А вот публичные сертификаты (например CA SSL сертификат) могут быть переданы третьим лицам чтобы они могли добавить этот сертификат как доверенный и когда они будут заходить на ресурс который использует SSL Client сертификат подписанный вашим CA SSL сертификатом, браузер будет обращаться к разрешенным CA находить там заранее добавленный (CA publiс SSL сертификат) и знать что соеденение установлено с доверенным участником.

Настройка nginx и добавление CA SSL сертификата в браузер:

server {
  listen       443;
  server_name  your_domain.loc;

  ssl                  on;
  ssl_certificate      /etc/ssl/openssl/certs/localhost.crt;
  ssl_certificate_key  /etc/ssl/openssl/private/localhost.key;

 


Результат:



Здесь вы можете загрузить мой CA сертификат чтобы внести этот сайт в свой браузер как доверенный: ​http://pavelruban.org/get-and-set-ca-ssl-certificate-for-pavelrubanorg

 

Comments:

аноним
Expected dickbutt! Disappointed!
10 июн 2016 в 11:57
аноним
Мудотень какая-то. Это всем придется добавлять сертификат. Чем let's encrypt не подошел?
10 июн 2016 в 12:05
аноним
«Мой дядя самых честных правил, Когда не в шутку занемог, Он уважать себя заставил И лучше выдумать не мог. Его пример другим наука; Но, боже мой, какая скука С больным сидеть и день и ночь, Не отходя ни шагу прочь! Какое низкое коварство Полуживого забавлять, Ему подушки поправлять, Печально подносить лекарство, Вздыхать и думать про себя: Когда же черт возьмет тебя!»
10 июн 2016 в 12:10
аноним
Свобода! Равенство! Упячка!!однатысячастоадинадцать
10 июн 2016 в 12:30
root
>>> Мудотень какая-то. Это всем придется добавлять сертификат. Чем let's encrypt не подошел? <<< Спасибо за название сервиса, не знал о нем, а так от задачи зависит: например если для разработки надо много хостов, и не хочется каждое утро прожимать TLS нотисы то решение вполне юзабельно, или если для корпоративной сети настроить общий сертификат и добавить его в одно место. Для внешки да - без добавления никак
13 июн 2016 в 03:53

add comment