Введение
Немного расскажу своими словами о том, как работает модуль ngx_http_proxy_module. Именно он реализует весь функционал, о котором пойдет речь. Допустим, у вас в локальной или виртуальной сети есть какие-то сервисы, не имеющие прямого доступа из интернета. А вы хотите таковой иметь. Можно пробрасывать нужные порты на шлюзе, можно что-то еще придумывать. А можно сделать проще всего — настроить единую точку входа на все свои сервисы в виде nginx сервера и с него проксировать различные запросы к нужным серверам.
Расскажу на конкретных примерах, где я это использую. Для наглядности и простоты буду прям по порядку перечислять эти варианты:
- Ранее я рассказывал о настройке чат серверов — matrix и mattermost. В этих статьях я как раз рассказывал о том, как проксировать запросы в чат с помощью nginx. Прошелся по теме вскользь, не останавливаясь подробно. Суть в том, что вы настраиваете на любом виртуальном сервере эти чаты, помещаете их в закрытые периметры сети без лишних доступов и просто проксируете запросы на эти сервера. Они идут через nginx, который у вас смотрит во внешний интернет и принимает все входящие соединения.
- Допустим, у вас есть большой сервер с множеством контейнеров, например докера. На нем работает множество различных сервисов. Вы устанавливаете еще один контейнер с чистым nginx, на нем настраиваете проксирование запросов на эти контейнеры. Сами контейнеры мапите только к локальному интерфейсу сервера. Таким образом, они будут полностью закрыты извне, и при этом вы можете гибко управлять доступом.
- Еще один популярный пример. Допустим, у вас есть сервер с гипервизором proxmox или любым другим. Вы настраиваете на одной из виртуальных машин шлюз, создаете локальную сеть только из виртуальных машин без доступа в нее извне. Делаете в этой локальной сети для всех виртуальных машин шлюз по-умолчанию в виде вашей виртуальной машины со шлюзом. На виртуальных серверах в локальной сети размещаете различные сервисы и не заморачиваетесь с настройками фаервола на них. Вся их сеть все равно не доступна из интернета. А доступ к сервисам проксируете с помощью nginx, установленным на шлюз или на отдельной виртуальной машине с проброшенными на нее портами.
- Мой личный пример. У меня дома есть сервер synology. Я хочу организовать к нему простой доступ по https из браузера по доменному имени. Нет ничего проще. Настраиваю на сервере nginx получение бесплатного сертификата , настраиваю проксирование запросов на мой домашний ip, там на шлюзе делаю проброс внутрь локалки на synology сервер. При этом я могу фаерволом ограничить доступ к серверу только одним ip, на котором работает nginx. В итоге на самом synology вообще ничего не надо делать. Он и знать не знает, что к нему заходят по https, по стандартному порту 443.
- Допустим, у вас большой проект, разбитый на составные части, которые живут на разных серверах. К примеру, на отдельном сервере живет форум, по пути /forum от основного домена. Вы просто берете и настраиваете проксирование всех запросов по адресу /forum на отдельный сервер. Точно так же можно без проблем все картинки перенести на другой сервер и проксировать к ним запросы. То есть вы можете создать любой location и переадресовывать запросы к нему на другие сервера.
Надеюсь в общем и целом понятно, о чем идет речь. Вариантов использования много. Я привел самые распространенные, которые пришли в голову и которые использую сам. Из плюсов, которые считаю наиболее полезными именно из своих кейсов, отмечу 2:
- Без проблем можете настроить https доступ к сервисам, при этом совершенно не трогая эти сервисы. Вы получаете и используете сертификаты на nginx сервере, используете https соединение с ним, а сам nginx уже передает информацию на сервера со службами, которые могут работать по обычному http и знать не знают о https.
- Вы очень легко можете менять адреса, куда проксируете запросы. Допустим у вас есть сайт, его запросы проксируются на отдельный сервер. Вы подготовили обновление или переезд сайта. Отладили все на новом сервере. Теперь вам достаточно на сервере nginx изменить адрес старого сервера на новый, куда будут перенаправляться запросы. И все. Если что-то пойдет не так, можете оперативно вернуть все обратно.
С теорией закончил. Перейдем теперь к примерам настройки. В своих примерах я буду использовать следующие обозначения:
blog.zeroxzed.ru | доменное имя тестового сайта |
nginx_srv | имя внешнего сервера с установленным nginx |
blog_srv | локальный сервер с сайтом, куда проксируем соединения |
94.142.141.246 | внешний ip nginx_srv |
192.168.13.31 | ip адрес blog_srv |
77.37.224.139 | ip адрес клиента, с которого я буду заходить на сайт |
Что такое самоподписанный сертификат SSL?
Самозаверяющий сертификат SSL — это сертификат, подписанный лицом, создавшим его, а не доверенным центром сертификации. Самозаверяющие сертификаты могут иметь тот же уровень шифрования, что и доверенный сертификат SSL, подписанный ЦС.
Веб-браузеры не распознают самозаверяющие сертификаты как действительные. При использовании самозаверяющего сертификата веб-браузер показывает посетителю предупреждение о том, что сертификат веб-сайта не может быть проверен.
Обычно самозаверяющие сертификаты используются для целей тестирования или внутреннего использования. Вы не должны использовать самозаверяющий сертификат в производственных системах, подключенных к Интернету.
Закрытые ключи
Создание закрытого ключа
Чтобы создать закрытый 2048-битный ключ, защищённый паролем, введите:
По запросу введите пароль, чтобы продолжить.
Проверка закрытого ключа
Эта команда подтвердит валидность закрытого ключа:
Если ключ зашифрован, программа запросит парольную фразу. Предоставьте пароль от ключа, чтобы просмотреть его в незашифрованном формате.
Совпадение ключа с сертификатом и запросом
Эта команда позволяет узнать, относится ли закрытый ключ (domain.key) к тому или иному сертификату (domain.crt) и запросу (domain.csr):
Если команды вернули одинаковый вывод, то, скорее всего, этот ключ, запрос и сертификат связаны.
Шифрование закрытого ключа
Следующая команда возьмёт незашифрованный ключ (unencrypted.key) и зашифрует его (encrypted.key):
Введите пароль, чтобы зашифровать ключ.
Express.js
const https = require("https");const fs = require("fs");const express = require("express");// прочитайте ключиconst key = fs.readFileSync("localhost.key");const cert = fs.readFileSync("localhost.crt");// создайте экспресс-приложениеconst app = express();// создайте HTTPS-серверconst server = https.createServer({ key, cert }, app);// добавьте тестовый роутapp.get("/", (req, res) => { res.send("this is an secure server");});// запустите сервер на порту 8000server.listen(8000, () => { console.log("listening on 8000");});
Как только вы настроите обслуживающий ваше приложение инструмент на работу с вашим сертификатом, ваше приложение будет доступно по URL’у с HTTPS.
Следуя приведенному выше примеру с Express, вы можете открыть вкладку браузера по адресу https://localhost:8000 и увидеть ваш контент:
Погодите секунду! Где же сообщение «это защищенный сервер»?
Вы рассчитывали увидеть кое-что другое, но именно этого и следовало ожидать — потому что источник сертификата еще не входит в число доверенных.
Доверие к сертификатам
Чтобы получить обозначение безопасного доступа, ваш новый источник сертификата должен считаться доверенным на вашей машине. Процесс присваивания этого статуса различается в зависимости от операционной системы и удовлетворит большинство браузеров. Если вы используете Firefox, процесс имеет некоторые отличия.
Подготовка конфигурационных файлов
Необходимо создать конфигурационный файл для OpenSSL. Создадим файл , скопируем в него следующее содержимое root-config.txt.
Раздел является обязательным. Здесь мы говорим OpenSSL использовать параметры из раздела :
Раздел содержит ряд значений по умолчанию:
Policy_strict будет применяться для всех подписей корневого центра сертификации, и корневой центр сертификации будет использоваться только для создания промежуточных центров сертификации.
Применим для всех подписей промежуточных центров серфтификации, так как промежуточные центры сертификации это подписывающие серверы, и клиентские сертификаты могут приходить от различных третьих лиц.
Параметры из секции применяются когда создаются сертификаты или запросы на подписывание сертификатов.
Секция определяет информацию, которая обычно требуется при запросе на подписывание сертификата. Можно указать некоторые значения по умолчанию.
Следующие несколько секций являются расширениями, которые могут применять при подписывании сертификатов. Например, при указании аргумента командной строки -extensions v3_ca будут применены расширения из секции . Эти расширения будут применяться при создании корневого сертификата.
При создании сертификата промежуточного центра сертификации будут применяться расширения из . Параметр указывает, что не может быть никаких дальнейших центров сертификации ниже промежуточного центра сертификации.
Расширение будет применяться при подписывании клиентских сертификатов, таких, которые используются для аутентификации удаленных пользователей.
Расширение будет применяться при подписывании серверных сертификатов, таких, которые используются для веб-серверов.
Расширение будет автоматически применяться при создании списков отзыва сертификатов (CRL — certificate revocation lists).
Расширение будет применяться при подписывании сертификата OCSP (Online Certificate Status Protocol, онлайн протокол статуса сертификатов).
Настройка SSL, TLS на WordPress
Для примера, возьмём сайт на WordPress и настроим на нём SSL/TLS, сделаем его доступным по HTTPS.
Нужно будет обязательно пройтись по списку и внести соответствующие изменения:
- Переписать в базе данных все ссылки, заменив на
Для этого, вы можете воспользоваться WP-Cli или специальной утилитой Seach Replace DB - Переписать в файлах темы все ссылки, заменив на или
- Отредактировать , а именно, перед добавить:
// example.com меняем на своё имя домена define('WP_HOME', 'https://example.com'); define('WP_SITEURL', 'https://example.com'); // Принудительная авторизация в админке по защищённому протоколу define('FORCE_SSL_ADMIN', true); // Чтобы предотвратить бесконечный редирект с http на https if (strpos($_SERVER, 'https') !== false) $_SERVER='on';
2 и 3 строки не обязательны, если выполнили первый пункт списка.
Про последнее можно добавить, что если WordPress находится за проксирующим сервером с SSL, но хостится на сервере без SSL (то есть, как в нашем случае, SSL на NGINX, Apache без), запросы к страницам сайта будут создавать бесконечный цикл. Чтобы его предотвратить, и используется определение в заголовках , наличие https в котором и будет говорить о том, что в заголовки надо будет записать метку о том, что HTTPS включен, и она будет сигнализировать Вордпрессу о том, что мы работаем на https.
Подробности можете посмотреть тут https://codex.wordpress.org/Administration_Over_SSL
Создание сертификата сервера
Далее предстоит создать сертификат сервера с помощью OpenSSL.
Создание запроса на подпись сертификата (CSR)
CSR — это открытый ключ, предоставляемый ЦС при запросе сертификата. ЦС выдает сертификат для этого конкретного запроса.
Примечание
Общее имя (CN) для сертификата сервера должно отличаться от имени домена издателя. Например, в данном случае общее имя издателя , а сертификата сервера — .
-
Используйте следующую команду, чтобы создать CSR:
-
При появлении запроса введите пароль для корневого ключа и сведения об организации для пользовательского ЦС: страна или регион, штат, организация, подразделение и полное доменное имя. Это домен веб-сайта — он должен отличаться от издателя.
Проверка созданного сертификата
-
Используйте следующую команду, чтобы напечатать выходные данные CRT-файла и проверить его содержимое:
-
Проверьте свой каталог и убедитесь, что в нем есть следующие файлы:
- contoso.crt;
- contoso.key;
- fabrikam.crt;
- fabrikam.key.
Compiling OpenSSL for Linux on Ubuntu 20.04
Start by making sure everything is up to date:
Now, let’s install some dependencies needed to build OpenSSL for Linux.
We need to install Git so that we can pull down the source for OpenSSL
I like to uninstall the system packaged version of OpenSSL on my build machine to avoid any confusion.
Next, let’s CD to our home directory.
In addition to the more advanced .configure script provided with the source, OpenSSL’s source directory includes a friendlier .config script with common defaults. Make this script executable and run it.
Now, we can issue make.
This will take several minutes to complete. Assuming it finishes successfully, issue make install
This will place a binary named openssl in /usr/local/bin/
Issue Ldconfig in order to rebuild the search path for libraries we’ve added to our installation
Now, let’s make sure OpenSSL works correctly:
Check openssl version:
Notice in the above that the “version” command against the binary functions, outputting the specific revision (j). This indicates that our build was successful.
Создать тестовый SSL сервер.
Команда OpenSSL s_server реализует общий SSL/TLS-сервер. Она должна использоваться только для целей тестирования. В приведенном ниже примере данный сервер прослушивает соединения на порту 8080 и возвращает отформатированную HTML страницу статуса, который включает много информации о ciphers:
$ openssl s_server -key key.pem -cert cert.pem -accept 8080 -www
Конвертирование сертификатов с DER в PEM формат.
# openssl x509 -inform der -in LN.der -out LN.pem
Как правило, при покупке SSL сертификатов, его отдают вам в формате .der и если вам нужно использовать его в веб-сервере или .pem формате, вы можете использовать команду выше, чтобы преобразовать такие сертификаты.
Конвертирование сертификатов с PEM в DER формат.
В случае, если вам необходимо изменить .pem формат в .der:
# openssl x509 -outform der -in linux-notes.pem -out linux-notes.der
Конвертирование сертификата и приватного ключа в PKCS#12 фотмат.
# openssl pkcs12 –export –out sslcert.pfx –inkey key.pem –in sslcert.pem
Если вам необходимо использовать сертификат с приложением Java или с любым другим, кто принимает формат PKCS# 12.
Совет: Вы можете включить «chain certificate» используя «-chain» опцию:
# openssl pkcs12 -export -out my_cert.pfx -inkey my_key.pem -in your_cert.pem -chain the_cert.pem
Создание CSR используя приватный ключ (private key).
# openssl req -out some_cert.csr -key exists.key -new
Если вы не хотите создать новый секретный ключ, а хотите используя вместо существующего, вы можете с предыдущей командой.
Проверьте содержимое сертификата в PKCS12 формате.
# openssl pkcs12 -info -nodes -in my_certificate.p12
PKCS12 — это двоичный формат, так что вы не сможете просматривать содержимое в блокноте или другом редакторе. Таким образом, вы должны использовать команду что выше, для просмотра содержимого файла формата PKCS12.
Получить SHA-1 отпечаток сертификата или CSR
Чтобы получить отпечаток SHA1 сертификата с использованием OpenSSL, используйте команду, приведенную ниже:
$ openssl dgst -sha1 my_cert.der
Чтобы получить SHA1 отпечаток пальца CSR с использованием OpenSSL, используйте команду, приведенную ниже:
$ openssl dgst -sha1 the_csr.der
Получить MD5 отпечаток сертификата или CSR
Чтобы получить отпечаток MD5 сертификата с использованием OpenSSL, используйте команду, приведенную ниже:
$ openssl dgst -md5 cert.der
Чтобы получить MD5 отпечаток пальца CSR с использованием OpenSSL, используйте команду, приведенную ниже:
$ openssl dgst -md5 my_csr.der
Тестирование SSL сертификата по URL.
# openssl s_client -connect linux-notes.org:443 -showcerts
Я использую это довольно часто для проверки SSL-сертификатов по URL с сервера. Это очень удобно для проверки некоторых деталей протокола, шифров и CERT.
Узнать версию OpenSSL
# openssl version
Поверка PEM сертификата на завершение (Expiration Date).
# openssl x509 -noout -in cert.pem -dates
Пример:
# openssl x509 -noout -in bestflare.pem -dates notBefore=Jul 4 14:02:45 2015 GMT notAfter=Aug 4 09:46:42 2015 GMT
Проверить поддержку SSL версии V2/V3 по URL.
Проверка SSL версии V2:
# openssl s_client -connect linux-notes.org:443 -ssl2
Проверка SSL версии V3:
# openssl s_client -connect linux-notes.org:443 -ssl3
Проверка TLS 1.0:
# openssl s_client -connect linux-notes.org:443 -tls1
Проверка TLS 1.1:
# openssl s_client -connect linux-notes.org:443 -tls1_1
Проверка TLS 1.2:
# openssl s_client -connect linux-notes.org:443 -tls1_2
Какой алгоритм используется в сертификате (проверка).
$ openssl req -noout -text -in mycert.csr | grep 'Signature Algorithm'
Или, используя URL:
openssl s_client -connect linux-notes.org:443 < /dev/null 2>/dev/null | openssl x509 -text -in /dev/stdin | grep "Signature Algorithm"
Получить сертификат по URL
Команда что ниже, сохранит сертификат в файл прямо по URL сайта:
$ echo -n | openssl s_client -connect linux-notes.org:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > pem.cert
Если веб-сервер имеет несколько сертификатов на один IP-адрес, то вам нужно будет сообщить OpenSSL, какой сертификат будет использоваться, пример ниже:
$ echo -n | openssl s_client -connect linux-notes.org:443 -servername linux-notes.org | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > pem.cert
Вот и все, много полезностей и все в одной статье «Примеры использования OpenSSL в Unix/Linux».
Генерирование запроса на подпись сертификата
Генерирование закрытого ключа и запроса
Этот метод позволяет вам подписать сертификат в ЦС и защитить веб-сервер Apache или Nginx с помощью HTTPS. Сгенерированный запрос на подпись можно отправить в ЦС, чтобы получить подписанный сертификат. Если ЦС поддерживает SHA-2, добавьте опцию -sha256.
Следующая команда создаст 2048-битный закрытый ключ (domain.key) и CSR (domain.csr):
Заполните поля в запросе на подпись.
Опция -newkey rsa:2048 создаст 2048-битный RSA-ключ. Опция –nodes отключает пароль для закрытого ключа.
Генерирование запроса для существующего закрытого ключа
Если у вас уже есть закрытый ключ, но нет сертификата, вы можете сгенерировать запрос для этого ключа.
Следующая команда создаст запрос сертификата (domain.csr) для существующего ключа (domain.key):
Ответьте на запросы программы, чтобы продолжить. Опция –new указывает, что запрос нужно сгенерировать.
Генерирование запроса для существующего сертификата и ключа
Этот метод позволяет обновить существующий сертификат, если оригинальный запрос на подпись сертификата был утерян.
Следующая команда создаст запрос (domain.csr) на основе существующего сертификата (domain.crt) и закрытого ключа (domain.key):
Опция -x509toreq создаст сертификат X509.
Из исходника
Устанавливаем пакеты, необходимые для сборки пакета:
yum install make gcc
* как видим, на момент написания обновления инструкции это была версия 1.1.1.
И копируем ссылку на ее скачивание:
На CentOS скачиваем исходник с использованием найденной ссылки:
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
И распаковываем его с последующим удалением:
tar -xvf openssl-*.tar.gz && \rm openssl-*.tar.gz
Переходим в папку с распакованным исходником:
cd openssl-*
Конфигурируем его:
./config —prefix=/usr/local —openssldir=/usr/local
Собираем:
make
И устанавливаем:
make install
Резервируем предыдущую версию openssl:
mv /usr/bin/openssl /root/openssl.back
И делаем ссылку на новую:
ln -s /usr/local/bin/openssl /usr/bin/openssl
Снова проверяем версию:
openssl version -a
Система вернет либо ошибку, например:
openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
… либо полные сведения об openssl, например:
OpenSSL 1.1.1g 21 Apr 2020 (Library: OpenSSL 1.0.2k-fips 26 Jan 2017)
built on: Sat May 11 01:54:53 2019 UTC
platform: linux-x86_64
options: bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,—noexecstack -Wall -O3 -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wa,—noexecstack -Wa,—generate-missing-build-notes=yes -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPADLOCK_ASM -DPOLY1305_ASM -DZLIB -DNDEBUG -DPURIFY -DDEVRANDOM=»\»/dev/urandom\»» -DSYSTEM_CIPHERS_FILE=»/etc/crypto-policies/back-ends/openssl.config»
OPENSSLDIR: «/etc/pki/tls»
ENGINESDIR: «/usr/lib64/engines-1.1»
Seeding source: os-specific
Обратите внимание, что у нас установлена новая версия OpenSSL, но по прежнему, используется старая библиотека — Library: OpenSSL 1.0.2k-fips 26 Jan 2017. Необходимо добавить в ldconfig новый путь
Для это создаем файл:
Необходимо добавить в ldconfig новый путь. Для это создаем файл:
vi /etc/ld.so.conf.d/openssl.conf
/usr/local/lib64
* если у нас используется система 32-бит, то путь будет /usr/local/lib.
Применяем настройки:
ldconfig -v
Снова проверяем:
openssl version
Мы должны увидеть:
OpenSSL 1.1.1g 21 Apr 2020
Обновление выполнено.
Принцип работы SSL и TLS
Принцип работы SSL и TLS, как я уже сказал, один и тот же. Поверх протокола TCP/IP устанавливается зашифрованный канал, внутри которого передаются данные по прикладному протоколу — HTTP, FTP, и так далее. Вот как это можно представить графически:
Прикладной протокол «заворачивается» в TLS/SSL, а тот в свою очередь в TCP/IP. По сути данные по прикладному протоколу передаются по TCP/IP, но они зашифрованы. И расшифровать передаваемые данные может только та машина, которая установила соединения. Для всех остальных, кто получит передаваемые пакеты, эта информация будет бессмысленной, если они не смогут ее расшифровать.
Установка соединения обеспечивается в несколько этапов:
1) Клиент устанавливает соединение с сервером и запрашивает защищенное подключение. Это может обеспечиваться либо установлением соединения на порт, который изначально предназначен для работы с SSL/TLS, например, 443, либо дополнительным запросом клиентом установки защищенного соединения после установки обычного.
2) При установке соединения клиент предоставляет список алгоритмов шифрования, которые он «знает». Сервер сверяет полученный список со списком алгоритмов, которые «знает» сам сервер, и выбирает наиболее надежный алгоритм, после чего сообщает клиенту, какой алгоритм использовать
3) Сервер отправляет клиенту свой цифровой сертификат, подписанный удостоверяющим центром, и открытый ключ сервера.
4) Клиент может связаться с сервером доверенного центра сертификации, который подписал сертификат сервера, и проверить, валиден ли сертификат сервера. Но может и не связываться. В операционной системе обычно уже установлены корневые сертификаты центров сертификации, с которыми сверяют подписи серверных сертификатов, например, браузеры.
5) Генерируется сеансовый ключ для защищенного соединения. Это делается следующим образом:
— Клиент генерирует случайную цифровую последовательность
— Клиент шифрует ее открытым ключом сервера и посылает результат на сервер
— Сервер расшифровывает полученную последовательность при помощи закрытого ключа
Учитывая, что алгоритм шифрования является асимметричным, расшифровать последовательность может только сервер. При использовании асимметричного шифрования используется два ключа — приватный и публичный. Публичным отправляемое сообщение шифруется, а приватным расшифровывается. Расшифровать сообщение, имея публичный, ключ нельзя.
6) Таким образом устанавливается зашифрованное соединение. Данные, передаваемые по нему, шифруются и расшифровываются до тех пор, пока соединение не будет разорвано.
Сертификат доменного имени
В большинстве случаев достаточно зарегистрировать в сертификате вашу рабочую станцию. Тем не менее, если вы предпочитаете собственные доменные имена для локальных приложений, в созданный сертификат можно добавить несколько альтернативных имен.
1. Создайте файл расширения x509 v3:
cat > v3.ext <<-EOFauthorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentsubjectAltName = @alt_names # Локальные хостингиDNS.1 = localhostDNS.2 = 127.0.0.1DNS.3 = ::1 # Перечислите доменные именаDNS.4 = local.devDNS.5 = my-app.devDNS.6 = local.some-app.devEOF
Следуя этому шаблону, можно добавить сколько угодно доменных имен.
Примечание: пожалуйста, обновите DNS.4, DNS.5 и DNS.6 или удалите их, если у вас не настроены никакие локальные доменные имена.
2. Создайте закрытый ключ и запрос на подпись сертификата:
openssl req -new -nodes -newkey rsa:4096 \ -keyout localhost.key -out localhost.csr \ -subj "/C=US/ST=State/L=City/O=Some-Organization-Name/CN=localhost"
Опционально: страну, штат, город и организацию можно изменять.
3. Создайте самоподписанный сертификат:
openssl x509 -req -sha512 -days 365 \-extfile v3.ext \-CA ca.crt -CAkey ca.key -CAcreateserial \-in localhost.csr \-out localhost.crt
Использование сертификата
Приложениям, обслуживающим ваш контент, понадобится доступ к файлам сертификата и закрытого ключа. Это может быть локальный веб-сервер (Apache или NGINX), локальный сервис или какой-то другой локальный инструмент, допустим, сборщик модулей DevServer.
Вот несколько примеров:
Создание самоподписанного корневого сертификата
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
Здесь мы использовали наш корневой ключ для создания корневого сертификата (файл rootCA.crt), который должен распространяться на всех компьютерах, которые нам доверяют. А приватный ключ (файл rootCA.key) должен быть секретным, поскольку он будет использоваться для подписи сертификатов серверов.
Создание сертификатов (делается для каждого домена) включает в себя несколько этапов. Эту процедуру необходимо выполнить для каждого домена/сервера, которым требуется доверенный сертификат от нашего ЦС.
Установка SSL/TLS-сертификата на сервер с nginx
Для установки SSL/TLS-сертификата на веб-сервер nginx надо выполнить несколько простых шагов:
1) Скопировать файлы .key и .pem на сервер. В различных операционных системах сертификаты и ключи могут храниться в разных директориях. В Debian’е, к примеру, это директория /etc/ssl/certs для сертификатов и /etc/ssl/private для ключей. В CentOS это /etc/pki/tls/certs и /etc/pki/tls/private
2) Прописать необходимые настройки в конфигурационный файл для хоста. Вот как это примерно должно выглядеть (это просто пример):
server { listen 443; server_name www.mycompany.com; root html; index index.html index.htm; ssl on; ssl_certificate server.pem; ssl_certificate_key server.key; ssl_session_timeout 5m; # Не рекомендуется использовать SSLv3 !!! # Он здесь только для примера ssl_protocols SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; ssl_prefer_server_ciphers on; location / { try_files $uri $uri/ =404; } }
3) Перезапустить nginx
4) Зайти браузером на 443 порт сервера — https://www.mycompany.com и проверить его работоспособность.
PEM
PEM (первоначально «Privacy Eулучшенный Mail ») — наиболее распространенный формат для X.509 сертификаты, CSRи криптографические ключи. Файл PEM представляет собой текстовый файл, содержащий один или несколько элементов в кодировке Base64 ASCII, каждый из которых содержит простые и нижние колонтитулы (например, и ). Один файл PEM может содержать сертификат конечного объекта, закрытый ключ или несколько сертификатов, образующих полную цепочку доверия. Большинство файлов сертификатов, загружаемых с SSL.com, будут в формате PEM.
Расширения имени файла PEM
PEM файлы обычно видны с расширениями , , и (для закрытых ключей), но вы также можете видеть их с разными расширениями. Например, файл пакета SSL.com CA, доступный в таблице загрузок в порядке сертификата, имеет расширение .
Общие преобразования PEM
В приведенных ниже командах OpenSSL замените имена файлов ВСЕМИ ЗАГЛАВНЫМИ буквами фактическими путями и именами файлов, с которыми вы работаете.
Преобразовать сертификат PEM с цепочкой доверия в PKCS # 7
PKCS # 7 (также известный как P7B) — это контейнерный формат для цифровых сертификатов, который чаще всего встречается в контексте серверов Windows и Java и обычно имеет расширение , Файлы PKCS # 7 не используются для хранения закрытых ключей. В приведенном ниже примере представляет файл со связанными промежуточными и корневыми сертификатами (такими как файл, скачанный с SSL.com).
openssl crl2pkcs7 -nocrl -certfile CERTIFICATE.pem -certfile MORE.pem -out CERTIFICATE.p7b
Преобразовать сертификат PEM с цепочкой доверия и секретным ключом в PKCS # 12
PKCS # 12 (также известный как PKCS12 или PFX) является распространенным двоичным форматом для хранения цепочки сертификатов и закрытого ключа в одном зашифрованном файле и обычно имеет расширения имени файла. or , В приведенном ниже примере добавляет файл со связанными промежуточными и корневыми сертификатами (такими как файл, загруженный с SSL.com), и добавляет закрытый ключ для (сертификат конечного объекта). Посмотри пожалуйста это как для более подробного объяснения показанной команды.
openssl pkcs12 -export -out CERTIFICATE.pfx -inkey PRIVATEKEY.key -in CERTIFICATE.crt -certfile MORE.crt
После выполнения указанной выше команды вам будет предложено создать пароль для защиты файла PKCS # 12. Запомните этот пароль. Он понадобится вам для доступа к любым сертификатам и ключам, хранящимся в файле.
Использование cfssl в Unix/Linux
Создаем папку:
$ mkdir tmp && cd $_
Создаем центр сертификации (certificate authority или CA):
$ cat > ca-config.json << EOF { "signing": { "default": { "expiry": "8760h" }, "profiles": { "kubernetes": { "usages": , "expiry": "8760h" } } } } EOF
Создаем CSR подпись:
$ cat > ca-csr.json << EOF { "CN": "Kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": } EOF
Можно добавить хост(ы), например:
{ "hosts": , "CN": "www.linux-notes.org", "key": { "algo": "rsa", "size": 2048 }, "names": }
Создаем сертификат:
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
Получаем примерный вывод:
2018/11/15 16:49:38 generating a new CA key and certificate from CSR 2018/11/15 16:49:38 generate received request 2018/11/15 16:49:38 received CSR 2018/11/15 16:49:38 generating key: rsa-2048 2018/11/15 16:49:38 encoded CSR 2018/11/15 16:49:38 signed certificate with serial number 352959392755430077750949756394023000115317850199
Другие вспомогательные команды
Создаем самоподписанный сертификат с использованием CSR:
$ cfssl selfsign www.linux-notes.net ca-csr.json | cfssljson -bare selfsigned
Генерируем self-signed root CA сертификат и приватный ключ:
$ cfssl genkey -initca csr.json | cfssljson -bare ca
Генерируем remote-issued сертификат и приватный ключ:
$ cfssl gencert -remote=remote_server csr.json
Генерируем local-issued сертификат и приватный ключ:
$ cfssl gencert -ca cert -ca-key key csr.json
Данная команда сгенерирует и выдаст сертификат и закрытый ключ из локального CA с помощью JSON. Вы можете использовать -hostname для переопределения SAN сертификатов.
Обновление OCSP файл ответов с новым сертификатом:
$ cfssl ocspsign -ca cert -responder key -responder-key key -cert cert \ | cfssljson -bare -stdout >> responses
Это вызовет ответ OCSP для сертификата и добавит его в файл ответов. Затем вы можете передать ответы на ocspserve для запуска OCSP-сервера.
Запускаем CFSSL API сервер. В CFSSL имеется поддержка HTTP-сервера с API; Все необходимые материалы можно найти в doc/api/intro.txt документе. Сервер запускается с помощью команды:
$ cfssl serve \ \ \
Пример:
$ cfssl serve -address=localhost -port=8888 -ca-key=ca-key.pem -ca=ca-cert.pem
Вывод логов можно контролировать с помощью «-loglevel» опции:
$ cfssl serve -loglevel 0
Где levels это:
- 0 — DEBUG
- 1 — INFO (По умолчанию)
- 2 — WARNING
- 3 — ERROR
- 4 — CRITICAL
Для помощи можно использовать:
$ cfssl -h Usage: Available commands: genkey gencrl ocspsign info certinfo sign version crl selfsign scan revoke serve gencert ocsprefresh ocspserve print-defaults bundle gencsr ocspdump Top-level flags: -allow_verification_with_non_compliant_keys Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.
Вот и все, статья «Установка cfssl в Unix/Linux» завершена.
Отзыв сертификата
Утилита OpenSSL ocsp может выступать в качестве ответчика OCSP, но она предназначена только для тестирования. Для производственной среды OCSP ответчики тоже существуют, но они выходят за рамки данной статьи.
Создадим серверный сертификат для тестирования.
Запустим ответчик OCSP на локальной машине. Вместо того, чтобы хранить статус отзыва в отдельном CRL файле ответчик OCSP напрямую читает файл index.txt. Ответ подписывается криптографической парой OCSP (используя опции –rkey и –rsigner).
В другом терминале пошлем запрос к OCSP ответчику. Опция указывает сертификат для запроса.
Начало вывода показывает следующее:
- был ли получен положительный ответ (OCSP Response Status)
- идентичность ответчика (Responder Id)
- статус отзыва сертификата (Cert Status)
Отзыв сертификата.
Как и раньше, запускаем ответчик OCSP в другом терминале и шлем запрос. В этот раз вывод показывает и .