Contents

Выпуск самоподписанного сертификата с помощью openssl.

Contents

Для выпуска сертификата локального домена сначала нужно сгенерировать корневой сертификат, на его основе будут выпускаться все остальные сертификаты.

Для каждого нового уровня домена, нужно будет выпускать свой сертификат. Для теста работы всего этого использовал docker контейнер nginx:latest

Сформируем закрытый ключ и сертификат центра сертификации. (Certification authority)

1
2
3
4
# DOMAIN=dodcaf.sweethome
# SUBJ="/C=RU/ST=someobl/L=somesity/O=somecompany/CN=$DOMAIN"
# openssl genrsa -out rootCA.key 2048
# openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -subj "$SUBJ" -out rootCA.pem

Здесь я определил 2 переменные, чтобы не проходить через интерактивный режим заполнения настроек.

Пояснения по ключам:

  • openssl help genrsa
  • openssl help req

Сформируем запрос на сертификат - csr (Certificate Signing Request), на основе ключа:

1
# openssl req -new -newkey rsa:2048 -sha256 -nodes -keyout "$DOMAIN.key" -subj "$SUBJ" -out "$DOMAIN.csr"

При последующих генерациях запросов на сертификат не нужно создавать новый ключ, можно использовать уже сгенерированный, использовав вместо параметра -keyout параметр -key.

Пояснения по ключам:

  • openssl help req

Понадобится создать файл с параметрами, чтобы передать их openssl. Подробнее тут.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# cat <<- EOF | tee ./additional.info
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @dns_names

[dns_names]
DNS.1 = $DOMAIN
DNS.2 = *.$DOMAIN
EOF

Выпустим сертификат:

1
# openssl x509 -req -in "$DOMAIN.csr" -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out "$DOMAIN.crt" -days 365 -sha256 -extfile ./additional.info

Теперь серфтикат и ключ можно использовать, для nginx это выглядит так:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
server {
  listen 443 ssl;
  server_name dodcaf.sweethome;

  ssl_certificate /root/data/dodcaf.sweethome.crt;
  ssl_certificate_key /root/data/dodcaf.sweethome.key;

  location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
  }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Нужно чтобы была dns-запись, связывающая ip-адрес и имя dodcaf.sweethome. Для теста это можно решить добавлением строки в /etc/hosts.

Так же нужно добавить CA сертификат в браузер:

  • google chrome: Настройки - Конфиденциальность и безопасность - Безопасность - Настроить сертификаты - выбрать Центры сертификации - импорт - выбрать rootCA.pem.
  • firefox: Settings - Privacy & Security - View Certificates - Authorities - Import - выбрать rootCA.pem - перезапустить firefox.

Можно ограничить вход только тем, у кого есть сертификат. Для этого нужно изменить конфиг nginx следующим образом:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
  listen 443 ssl;
  server_name dodcaf.sweethome;

  ssl_certificate /root/data/dodcaf.sweethome.crt;
  ssl_certificate_key /root/data/dodcaf.sweethome.key;
  ssl_client_certificate /root/data/rootCA.pem;
  ssl_verify_client on;
  # ssl_crl /path/to/nginx/conf/crl.pem;

  keepalive_timeout 70;
  fastcgi_param SSL_VERIFIED $ssl_client_verify;
  fastcgi_param SSL_CLIENT_SERIAL $ssl_client_serial;
  fastcgi_param SSL_CLIENT_CERT $ssl_client_cert;
  fastcgi_param SSL_DN $ssl_client_s_dn;

  location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
  }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Проверим - работает. Порт 8443 указан, т.к. nginx запущен внутри docker контейнера и наружу выброшен этот порт. Перед curl стоит sudo, т.к. папка volume мапится из контейнера и в ней файлы с UID и GUID равны 0.

1
$ sudo curl -k --key dodcaf.sweethome.key --cert dodcaf.sweethome.crt --url "https://dodcaf.sweethome:8443"

Для работы из браузера нужно сделать единый .p12 файл, который будет содержать в себе: сертификат клиента, ключ клиента и сертификат CA. Я не стал генерировать новые ключ и сертификат для клиента.

1
# openssl pkcs12 -export -in dodcaf.sweethome.crt -inkey dodcaf.sweethome.key -certfile rootCA.pem -out client01.p12 -passout pass:Qaz123

Так же нужно поменять владельца на системного пользователя. У моего UID=1000, поменяю права из контейнера:

1
# chown 1000:1000 dodcaf.sweethome-client01.p12

Так же нужно добавить CA сертификат в браузер:

  • google chrome: Настройки - Конфиденциальность и безопасность - Безопасность - Настроить сертификаты - выбрать Ваши сертификаты - импорт - выбрать dodcaf.sweethome-client01.p12 - ввести пароль.
  • firefox: Settings - Privacy & Security - View Certificates - Your Certificates - Import - выбрать dodcaf.sweethome-client01.p12 - ввести пароль - перезапустить firefox.

Полезные ссылки: