Https для разработчиков | techrocks

Введение:

Потребовалось мне тут как-то написать небольшой API, в котором необходимо было помимо обычных запросов принимать запросы с «высокой степенью секретности».

Не я первый с этим столкнулся и мир давно уже использует для таких вещей

Поскольку на моём сервере используется nginx, то был установлен модуль SSLГугл не выдал ни одного работоспособного howto, но информация в сети есть по частям.

Итак, пошаговое руководство по настройке nginx на авторизацию клиентов через SSL-сертификаты.

Внимание! В статье для примера используются самоподписанные сертификаты!

Перед стартом создадим папку в конфиге nginx, где будут плоды наших трудов:

cd /path/to/nginx/config/
mkdir ssl && cd ssl

1 Подготовка CA

Создадим конфигnano ca.config

со следующим содержимым:

[ ca ]
default_ca = CA_CLIENT # При подписи сертификатов # использовать секцию CA_CLIENT

[ CA_CLIENT ]
dir = ./db # Каталог для служебных файлов
certs = $dir/certs # Каталог для сертификатов
new_certs_dir = $dir/newcerts # Каталог для новых сертификатов

database = $dir/index.txt # Файл с базой данных подписанных сертификатов
serial = $dir/serial # Файл содержащий серийный номер сертификата (в шестнадцатеричном формате)
certificate = ./ca.crt # Файл сертификата CA
private_key = ./ca.key # Файл закрытого ключа CA

default_days = 365 # Срок действия подписываемого сертификата
default_crl_days = 7 # Срок действия CRL
default_md = md5 # Алгоритм подписи

policy = policy_anything # Название секции с описанием политики в отношении данных сертификата

[ policy_anything ]
countryName = optional # Поля optional - не обязательны, supplied - обязательны
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional

Далее надо подготовить структуру каталогов и файлов, соответствующую описанной в конфигурационном файле

2. Создание клиентского закрытого ключа и запроса на сертификат (CSR)

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

3. Подпись запроса на сертификат (CSR) с помощью доверенного сертификата (CA).

При подписи запроса используются параметры заданные в файле ca.config

openssl ca -config ca.config -in client01.csr -out client01.crt -batch

В результате выполнения команды появится файл клиентского сертификата client01.crt.

Для создания следующих сертификатов нужно повторять эти два шага.

4. Создание сертификата в формате PKCS#12 для браузера клиента

Это на тот случай, если к вашему серверу подключаются не бездушные машины, как в моём случае, а живые люди через браузер.

Запароленный файл PKCS#12 надо скормить браузеру, чтобы он смог посещать ваш сайт.

openssl pkcs12 -export -in client01.crt -inkey client01.key -certfile ca.crt -out client01.p12 -passout pass:q1w2e3

Api key

API Key — это строка символов, которую передает клиент в запросах к серверу. Для успешной аутентификации строка должна совпадать у клиента и у сервера. Данная схема обеспечивает защиту от несанкционированного использования API и позволяет осуществлять, например, проверку лимитов использования API.

Api1:2022 broken object level authorization (недостатки контроля доступа к объектам)

Другое название этого риска: Insecure Direct Object References (Небезопасные прямые ссылки на объекты). Это самая распространенная проблема с API в настоящее время. Для иллюстрации приведу API, которое в дальнейшем использую еще для нескольких примеров уязвимостей.

Api10:2022 insufficient logging & monitoring (недостатки журналирования и мониторинга)

Чтобы выявить атаку или подозрительное поведение пользователей, систему надо мониторить, а события логировать с достаточным уровнем подробности:

Api3:2022 excessive data exposure (разглашение конфиденциальных данных)

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

Эти данные зачастую сериализируются в JSON без проверок и отправляется клиенту с предположением, что клиент сам отфильтрует нужные данные. Но проблема в том, что запрос может отправить не только клиент, а может сформировать злоумышленник напрямую к серверу и получить конфиденциальные данные. Например, безобидный запрос данных по пользователю с ID 1:

Api4:2022 lack of resources & rate limiting (отсутствие проверок и ограничений)

Необходимо защитить сервер от атак по подбору пароля (brute force attack). Для этого нужно реализовать следующие ограничения:

Для JS существуют средства, позволяющие делать такие проверки автоматически (например,

) и сразу посылать ответ «429 Too Many Requests», не нагружая сервер.

Необходимо защитить сервер и от отказа в обслуживании (DoS-атаки)

Например, сервер ожидает в параметре size число записей:

Api5:2022 broken function level authorization (недостатки контроля доступа на функциональном уровне)

Должна быть разработана четкая система разграничения доступа между ролями пользователей API. Например, есть роль: обычные пользователи и роль: администраторы. Команду по просмотру всех пользователей может вызвать только администратор:

Api6:2022 mass assignment (небезопасная десериализация)

В данном случае ситуация обратная предыдущему пункту Excessive Data Exposure — лишние данные передаются на сервер с целью несанкционированной замены значений. Как это понимать? Предположим у нас есть пользователь-хакер с ID 1 со следующими данными:

Api7:2022 security misconfiguration (некорректная настройка параметров безопасности)


Следующие действия могут привести к проблемам с безопасностью, соответственно, их надо избегать:

Api8:2022 injection (внедрение)

Внедрение — это выполнение программного кода, не предусмотренного системой. Разделяют внедрения:

Атака будет успешна, если сервер выполняет полученные команды без проверки. Чем-то напоминает «небезопасную десериализацию», только используются не дополнительные атрибуты, а SQL код или команды OS. В результате SQL инъекции можно получить несанкционированный доступ к данным.

GET /run

Api9:2022 improper assets management (недостатки управления api)

API может иметь несколько точек входа (endpoints) с разными версиями и функциональными назначениями. Например:

Cache-control


Cache-Control позволяет управлять кешом на стороне клиента, рекомендуется запретить кеширование, чтобы в кеше случайно не оставались приватные данные:

Cache-Control: no-store

Certsimple

CertSimple выдает только EV-сертификаты, и делает это похожим на Let’s Encrypt способом. И вот в чем его преимущества:

Простой процесс подачи заявкиНе нужно никакого дополнительного софта или вопросов в консоли.

Быстрое время проверкиОбычно проверка занимает около трех часов, в то время как в других CA это занимает 7-10 дней.

Бесплатное продление действия сертификатаВы можете с легкостью добавить новый домен или заменить потерянный частный ключ.

Подробнее написано здесь.

Content-security-policy

Позволяет защититься от атаки Cross-site scripting и других кросс-сайтовых инъекций, в том числе Clickjacking. Требует вдумчивого конфигурирования, т.к. параметров много. Но надо хотя бы поставить дефолтную политику, что предотвратит возможность атаки Cross-site Scripting:

Content-Security-Policy: default-src 'self'

Подробно значения заголовка Content-Security-Policy разбираются, например,

Cross-origin resource sharing (cors) (кросс-доменное использование ресурсов)

CORS — это механизм безопасности, который позволяет серверу задать правила доступа к его API. Например, если на сервере установить заголовок:

Access-Control-Allow-Origin: *

то это позволит использовать API без ограничения. Если это не публичное API, то для безопасности надо явно устанавливать Origin-ы, с которых разрешен доступ к API, например:

Insecure cookies and local storage (небезопасные cookies и данные в local storage)


Cookies должны использоваться безопасно:

Insecure passwords (небезопасные пароли)

С этой темой все просто:

Let’s encrypt

До появления Let’s Encrypt сертификаты продавались доверенными сторонними компаниями.

Процедура приобретения сертификата была обременительной. Она требовала работы с бумагами. Кроме того, сертификаты были довольно дороги.

Но затем появился Let’s Encrypt.

Linux, freebsd

Убедитесь, что OpenSSL установлен:

openssl version

Если OpenSSL отсутствует, то нужно его установить:

  • Debian, Ubuntu и подобные
sudo apt-get install openssl
  • Red Hat, CentOS и подобные
sudo yum install openssl
make -C /usr/ports/security/openssl install clean

Теперь сгенерировать ключ и CSR мы можем одной командой:

Nginx

Измените конфиг nginx:

Debian, Ubuntu, Red Hat, CentOS

/etc/nginx/nginx.conf

FreeBSD

/usr/local/etc/nginx/nginx.conf

Tls с расширением sni

На одном порту IP-адреса может прослушиваться только один процесс на сервере. Другие процессы могут прослушивать другие порты по тому же IP-адресу, но по каждой комбинации IP-адреса и порта прослушивается лишь один процесс.

Token-based authentication

Также называют Bearer Authentication.

Using components with known vulnerabilities (использование компонент с известными уязвимостями)

Компоненты, такие как библиотеки и framework-и выполняются с теми же привилегиями, что и приложение. Поэтому если среди используемых библиотек окажется небезопасный компонент, то это может привести к захвату или выводу из строя сервера. Для проверки безопасности компонент используются специальные приложения, например, для JavaScript можно использовать

X-content-type-options

Установка данного заголовка запрещает браузеру самому интерпретировать тип присланных файлов и принуждает использовать только тот, что был прислан в заголовке Content-Type. Без этого возможна ситуация, когда, например, посылается безобидный на вид txt файл, внутри которого вредоносный скрипт и браузер его выполняет как скрипт, а не как текстовой файл. Поэтому устанавливаем:

X-Content-Type-Options: nosniff

X-frame-options (защита от clickjacking)

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

X-Frame-Options: deny

или разрешить использование только в нашем домене:

X-Frame-Options: sameorigin


А лучше для предотвращения атаки Clickjacking использовать более современный механизм и установить правильную политику безопасности

Content-Security-Policy

X-powered-by

Этот заголовок автоматически вставляется некоторыми серверами, что дает понять злоумышленнику, с каким сервером он имеет дело, например:

X-Powered-By: Express

Отсутствие этого заголовка, конечно, никого не остановит, но сразу давать такую подсказку не стоит. Поэтому передачу этого заголовка надо запретить.

Авторизация с помощью клиентских ssl сертификатов. – itc-life

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

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

Наиболее наглядным примером использования авторизации посредством
клиентских сертификатов является система платежей WebMoney Transfer, а
точнее реализация WM Keeper Light. Данная схема авторизации признана
наиболее надежной и, в том или ином виде, широко используется в сфере
предоставления банковских услуг.

Практическая реализация рассматривается на основе популярной связки
веб-сервера Apache (https://httpd.apache.org/) и модуля mod_ssl (https://www.modssl.org/),
основанного на использовании библиотеки openssl (https://www.openssl.org/).
Предполагается, что соответствующее программное обеспечение у вас уже
установлено.

Для реализации процесса авторизации по клиентским сертификатам
требуется:

1. Создать собственный доверенный сертификат (Certificate Authority),
для того чтобы с помощью него подписывать и проверять клиентские
сертификаты.
2. Создать клиентские сертификаты, подписанные доверенным
сертификатом, для последующей передачи их клиентам.
3. Сконфигурировать веб-сервер для запроса и проверки клиентских
сертификатов.

Примечание: Для работы с ключами используется программа openssl,
входящая в пакет библиотеки openssl. Все приведенные в статье
примеры максимально адаптированы для их выполнения из серверных
скриптов при автоматизации процесса выдачи клиентских сертификатов,
в частности нигде не используется интерактивный режим. При создании
закрытых ключей не используется шифрование ключа, поэтому
рекомендуется максимально использовать систему ограничения прав
доступа операционной системы на файлы ключей.

Создание собственного самоподписанного доверенного сертификата.

Собственный доверенный сертификат (Certificate Authority – далее CA)
необходим для подписи клиентских сертификатов и для их проверки при
авторизации клиента веб-сервером. С помощью приведенной ниже команды
создается закрытый ключ и самоподписанный сертификат.

# openssl req -new -newkey rsa:1024 -nodes -keyout ca.key -x509 -days 500 
-subj /C=RU/ST=Msk/L=Msk/O=My Inc/OU=Sale/CN=bla/[email protected] 
-out ca.crt

Описание аргументов:

req

Запрос на создание нового сертификата.

-new

Создание запроса на сертификат (Certificate Signing Request –
далее CSR).

-newkey rsa:1023

Автоматически будет создан новый закрытый RSA ключ длиной 1024
бита. Длину ключа можете настроить по своему усмотрению.

-nodes
Не шифровать закрытый ключ (См. примечание выше).
-keyout ca.key
Закрытый ключ сохранить в файл ca.key.
-x509
Вместо создания CSR (см. опцию -new) создать самоподписанный
сертификат.
-days 500

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

-subj /C=RU/ST=Msk/L=Msk/O=My
Inc/OU=Sale/CN=bla/[email protected]

Данные сертификата, пары параметр=значение, перечисляются через
‘/’. Символы в значении параметра могут быть “подсечены” с
помощью обратного слэша “”, например “O=My Inc”. Также можно
взять значение аргумента в кавычки, например, -subj
“/xx/xx/xx”.
Описание параметров:
С – Двухсимвольный код страны (Country). Необязательный
параметр.
ST – Название региона/области/края/республики/… (State
Name). Необязательный параметр.
L – Название города/поселка/… (Locality Name).
Необязательный параметр.
O – Название организации (Organization Name).
Необязательный параметр.
OU – Название отдела (Organization Unit). Необязательный
параметр.
CN – Имя сертификата, при создании серверных сертификатов
используется доменное имя сайта, для клиентских
сертификатов может быть использовано что угодно (Common
Name). Обязательный параметр. Максимальная длина 64
символа.
emailAddress – почтовый адрес (E-mail address).
Необязательный параметр. Максимальная длина 40 символов.

Необязательные параметры могут быть пропущены, например,
/C=RU/CN=blabla/[email protected].

-out ca.crt
Сертификат сохранить в файл ca.crt.

В результате выполнения команды появятся два файла ca.key и ca.crt.

Просмотреть данные закрытого ключа и сертификата вы можете с помощью
команд:

# openssl rsa -noout -text -in ca.key (для ключа)
# openssl x509 -noout -text -in ca.crt (для сертификата)

Создание клиентских сертификатов

Подготовка конфигурации и файлов для подписи сертификатов.

Создайте конфигурационный файл с именем ca.config следующего
содержания.

[ ca ]
default_ca = CA_CLIENT # При подписи сертификатов
# использовать секцию CA_CLIENT
[ CA_CLIENT ]
dir = ./db # Каталог для служебных файлов
certs = $dir/certs # Каталог для сертификатов
new_certs_dir = $dir/newcerts # Каталог для новых сертификатов
database = $dir/index.txt # Файл с базой данных
# подписанных сертификатов
serial = $dir/serial # Файл содержащий серийный номер
# сертификата
# (в шестнадцатиричном формате)
certificate = ./ca.crt # Файл сертификата CA
private_key = ./ca.key # Файл закрытого ключа CA
default_days = 365 # Срок действия подписываемого
# сертификата
default_crl_days = 7 # Срок действия CRL (см. $4)
default_md = md5 # Алгоритм подписи
policy = policy_anything # Название секции с описанием
# политики в отношении данных
# сертификата
[ policy_anything ]
countryName = optional # Код страны - не обязателен
stateOrProvinceName = optional # ......
localityName = optional # ......
organizationName = optional # ......
organizationalUnitName = optional # ......
commonName = supplied # ...... - обязателен
emailAddress = optional # ......

Создайте структуру каталогов и файлов, соответсвующую описанной в
конфигурационном файле

# mkdir db
# mkdir db/certs
# mkdir db/newcerts
# touch db/index.txt
# echo "01" > db/serial

Примечание: В файле db/serial записывается текущий серийный номер
подписываемого сертификата в шестнадцатиричном формате. В файл
db/index.txt сохраняются данные о подписываемых сертификатах.

Создание клиентского закрытого ключа и запроса на сертификат (CSR).

Для создания подписанного клиентского сертификата предварительно
необходимо создать запрос на сертификат, для его последующей подписи.
Аргументы команды полностью аналогичны аргументам использовавшимся при
создании самоподписанного доверенного сертификата (см. $1), но
отсутсвует параметр -x509.

# openssl req -new -newkey rsa:1024 -nodes -keyout client01.key 
-subj /C=RU/ST=Msk/L=Msk/O=Inc/OU=Web/CN=usr/[email protected] 
-out client01.csr

В результате выполнения команды появятся два файла client01.key и
client01.csr. Просмотреть данные закрытого ключа и запроса на
сертификат (CSR) вы можете с помощью команд:

# openssl rsa -noout -text -in client01.key (для ключа)
# openssl req -noout -text -in client01.csr (для запроса)

Подпись запроса на сертификат (CSR) с помощью доверенного сертификата (CA).

При подписи запроса используются параметры заданные в файле ca.config

# openssl ca -config ca.config -in client01.csr -out client01.crt -batch

Описание аргументов:

ca

Подпись запроса с помощью CA.

-config ca.config

Использовать конфигурационный файл ca.config.

-in client01.csr

CSR находится в файле client01.csr

-out client01.crt

Сохранить сертификат в файл client01.crt

-batch

Не спрашивать подтверждения подписи.

В результате выполнения команды появится файл клиентского сертификата
client01.crt. Просмотреть данные сертификата вы можете с помощью
команды:

# openssl x509 -noout -text -in client01.crt

Подготовка данных для передачи клиенту.

Для передачи полученных в результате предыдущих операций файлов
клиенту, обычно используется файл в формате PKCS#12. В этот файл
упаковывается и защищается паролем вся информация необходимая клиенту
для инсталяции сертификата в броузер.

# openssl pkcs12 -export -in client01.crt -inkey client01.key 
-certfile ca.crt -out client01.p12 -passout pass:q1w2e3

Описание аргументов:

pkcs12

Работа с файлами формата PKCS#12.

-export

Экспортирование данных в файл.

-in client01.crt

Файл клиентского сертификата.

-inkey client01.key

Файл закрытого ключа.

-certfile ca.crt

Файл доверенного сертификата.

-out client01.p12

Сохранить данные в файл client01.p12.

-passout pass:q1w2e3

Установить пароль q1w2e3 на файл (пароль может быть любым, в
том числе и пустым)

На этом процесс создания клиентского сертификата завершен. Теперь вам
необходимо передать клиенту файл client01.p12 и пароль к нему любым
удобным безопасным способом, а также проинструктировать его о
процедуре инсталяции сертификата в броузер.

Для создания новых клиентских сертификатов повторите операции с $2.2.
по $2.4.

Настройка веб-сервера.

Для реализации процесса авторизации по клиентским сертификатам
необходимо сконфигурировать веб-сервер для решения следующих задач:
1. Запрет доступа к защищаемой области по протоколу HTTP.
2. Запрос и проверка клиентских сертификатов.

Запрет доступа к защищаемой области по протоколу HTTP.

Найдите в конфигурационном файле веб-сервера httpd.conf секцию
, соответсвующую вашему сайту и добавьте в неё
следующие директивы

SSLRequire

Описание директив:

/path/to/secure/area/

Абсолютный путь до директории защищаемой области.

SSLRequire

Запрещает доступ клиенту, если при соединении не используется
протокол HTTPS (HTTP через SSL).

Запрос и проверка клиентских сертификатов.

Найдите в конфигурационном файле веб-сервера httpd.conf секцию ,
соответсвующую вашему сайту и добавьте в неё следующие директивы:

SSLCACertificateFile /path/to/ca.crt
SSLVerifyClient require

Описание директив:

SSLCACertificateFile /path/to/ca.crt

Абсолютный путь до доверенного сертификата (см. $1.). Также в
качестве значения директивы SSLCACertificateFile может быть
указан файл, содержащий несколько доверенных сертификатов
(формируется путем обычной конкатенации файлов сертификатов),
тогда все они будут считаться доверенными сертификатами.

SSLVerifyClient require

При наличии этой директивы веб-сервер будет запрашивать
сертификат у клиента в обязательном порядке. Если клиент не
предоставляет сертификат, тогда сервер отклоняет запрос. Если
клиент предоставляет сертификат, то веб-сервер проверяет его
срок действия и поставщика сертификата (сертификат которым он
подписан), если сертификат поставщика присутсвует в файле
SSLCACertificateFile, то проверка считается успешной и клиенту
предоставляется доступ до защищенной области.

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

# apachectl restart

Альтернативные способы настройки веб-сервера.

В этом разделе будут рассмотрены альтернативные пути настройки
веб-сервера для авторизации по клиентским сертификатам. Вариантов
настройки и их комбинаций может быть много, нижеприведенные примеры
проиллюстрируют некоторые из них и помогут при разработке собственных
конфигураций.

Пример 1.

Допустим файл указанный в директиве SSLCACertificateFile содержит
несколько доверенных сертификатов (см. описание директивы
SSLCACertificateFile). Требуется разрешить доступ до защищенной
области только владельцам сертификатов, подписанных только одним из
поставщиков.

SSLVerifyClient require
SSLRequire %{SSL_CLIENT_I_DN_O} eq "First CA Inc."

Описание директив:

SSLRequire %{SSL_CLIENT_I_DN_O} eq "First CA Inc."

Требует чтобы организацией поставщика клиентского сертификата
являлась “First CA Inc.”. Аналогичным способом можно проверять
любые другие параметры клиентского сертификата или его
поставщика. Более подробную информацию о директиве SSLRequire и
именах переменных смотрите в документации по mod_ssl.

Пример 2.

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

SSLVerifyClient require
SSLOptions  FakeBasicAuth
AuthName "My secure area"
AuthType Basic
AuthUserFile /path/to/passwd/file
require valid-user

Содержимое файла /path/to/passwd/file

/C=RU/L=Msk/O=My Inc./CN=user/[email protected]:xxj31ZMTZzkVA
/C=RU/L=Sam/O=My LTD./CN=vas/[email protected]:xxj31ZMTZzkVA
/C=RU/L=Zel/O=My LLC./CN=prs/[email protected]:xxj31ZMTZzkVA
........

Описание директив:

SSLOptions  FakeBasicAuth

Имитирует простую авторизацию веб-сервером. Имя пользователя и
пароль не запрашиваются, но сверяются данные клиентского
сертификата с данными в файле /path/to/passwd/file. Строка
идентифицирующая клиента может быть получена из клиентского
сертификата с помощью команды:

# openssl x509 -noout -subject -in client.crt

Или взята из базы данных db/index.txt, формируемой при подписи
CSR (см. $2.). В качестве пароля всегда используется строка
“xxj31ZMTZzkVA”, являющаяся результатом шифрования строки
“password” с помощью алгоритма DES.

Отзыв сертификатов.

Результат проверки веб-сервером клиентского сертификата будет успешным
на весь срок действия сертификата. Возникает вопрос, что делать в
случае если вы хотите отказать какому-либо клиенту в доступе по его
клиентскому сертификату. Для решения этой проблемы создается список
отзыва сертификатов (Certificate Revocation List – CRL). В списке
отзыва перечисляются отозванные вами клиентские сертификаты. В
соответсвии с этим списком веб-сервер будет отклонять запросы если
сертифкат клиента отозван.

Создание списка отзыва (CRL).

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

# openssl ca -gencrl -config ca.config -out ca.crl

Описание аргументов:

ca

При создании CRL также используется этот аргумент.

-gencrl

Создание списка отзыва сертификатов.

-config ca.config

Использовать конфигурационный файл ca.config.

-out ca.crl

Сохранить созданный список отзыва в файл ca.crl

В результате будет создан список отзыва, основанный на базе данных
подписанных сертификатах db/index.txt. Так как на данный момент ни
один из сертификатов в базе данных не помечен как отозванный, то
созданный список будет пустым. Просмотреть данные списка отзыва вы
можете с помощью следующей команды.

# openssl crl -in ca.crl -text -noout

Одной из важных черт списка отзыва является его срок действия,
указываемый в конфигурационном файле ca.config с помощью директивы
default_crl_days. Также альтернативно может быть использована
директива default_crl_hours, если вы планируете часто обновлять ваш
CRL. Список отзыва должен обновляться не позже истечения срока
действия. Для переодического вызова приведенной выше команды можно
использовать cron.

Отзыв сертификата.

Для того чтобы отозвать клиентский сертификат необходимо пометить его
в базе данных сертификатов db/index.txt как отозванный, тогда при
следующем обновлении списка отзыва, этот сертификат будет в него
включен. Для пометки сертификата как отозванного используйте
приведенную ниже команду.

# openssl ca -config ca.config -revoke client01.crt

Описание аргументов:

-revoke client01.crt
Отозвать сертификат находящийся в файле client01.crt

Настройка веб-сервера

После создания списка отзыва сертификатов необходимо дать возможность
веб-серверу использовать его. Для этого добавьте приведенную ниже
директиву в конфигурационный файл веб-сервера.

SSLCARevocationFile /path/to/ca.crl

Описание директив:

SSLCARevocationFile /path/to/ca.crl
Абсолютный путь до файла со списком отзыва сертификатов (см.
$4.1.)

Не забывайте перезапускать веб-сервер после каждого изменения его
конфигурации.

# apachectl restart

Заключение.

Вышеизложенный материал можно дополнять и углублять, цель статьи –
минимальное руководство по реализации авторизации по клиентским
сертификатам на практике. Любой читатель, имеющий доступ к
использовавшемуся программному обеспечению, с помощью этой статьи
может за короткое время настроить свой веб-сервер для решения этой
задачи. Каждый из изложенных пунктов можно расширить и написать по
нему отдельную статью, заинтересовавшиеся читатели могут получить
дополнительные сведения в документации по Apache, mod_ssl и openssl. В
заключение хочется дать несколько советов по программной реализации
вышеописанных процессов.

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

open ( LOCK, ">/tmp/cert-sign.lck" ) or error_handling();
flock ( LOCK, 2 ) or error_handling();

# … код, реализующий подпись сертификата …

close( LOCK );

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

Второй совет связан с извлечением и обработкой данных клиентских
сертификатов в CGI-скриптах. При простой авторизации клиента по имени
и паролю веб-сервер помещает имя пользователя в переменную окружения
REMOTE_USER. Аналогичным образом из переменных окружения можно извлечь
данные клиентского сертификата при авторизации по сертификату. Для
того чтобы веб-сервер устанавливал значения переменных окружения,
относящихся к клиентскому сертификату необходимо добавить в
конфигурацию веб-сервера следующую директиву:

SSLOptions  StdEnvVars  ExportCertData

Описание директив:

 StdEnvVars
Включает установку в переменные окружения данных, относящихся к
SSL.
 ExportCertData

Включает установку в переменные окружения текста сертификатов
использовавшихся при передаче данных.

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

Альтернативой переменной REMOTE_USER могут служить следующие
переменные: SSL_CLIENT_M_SERIAL - серийный номер клиентского
сертификата, SSL_CLIENT_S_DN_CN - имя сертификата (Common Name) или
SSL_CLIENT_S_DN - данные сертификата (Subject Name, см. описание
аргумента -subj в $1). Если вы хотите использовать переменную
SSL_CLIENT_S_DN_CN для идентификации пользователя, то вы должны
обеспечить уникальность Common Name для разных сертификатов при
создании запросов на клиентский сертификат (см. $2.2.). Уникальность
SSL_CLIENT_M_SERIAL и SSL_CLIENT_S_DN гарантируется автоматически при
подписи сертификатов.

Несколько мелких замечаний от Александр Елисеенко:

1) ключ -sabj при генерации сертификатов явно лишний, все именные
данные и так будут запрошены (в интерактиве). Для упрощения жизни
можно отредактировать файл openssl.cnf, секция [
req_distinguished_name ]. Тогда останется только жать ENTER.

2) специально создавать файл ca.config нет смысла, дешевле
воспользоваться готовым openssl.cnf

3) подробное освещение вопроса генерации сертификатов - дело нужное,
но не лишним было бы отметить, что в составе дистрибутива openssl есть
готовый скрипт CA (CA.sh или GA.pl), с помощью которого ключи
генерятся без всяких проблем

(https://www.opennet.ru/tips/info/681.shtml)

Ну и по вопросу организации проверки клиентских сертификатов на
сервере - не все так просто,как написано в статье.

Корневой (или доверенный) сертификат может быть не один. Каталог, где
они размещены, указывается директивой SSLCACertificatePath. Для
каждого доверенного сертификата должен быть указан md5 hash. Все
доверенные сертификаты могут быть сгруппированы в один файл (вместе с
md5 хэшем, а не путем обычной конкатенации файлов сертификатов), путь
к нему в этом случае указывается директивой SSLCACertificateFile. Если
используются довереннные сертификаты, подписанные другими CA, то
директивой SSLVerifyDepth устанавливается глубина проверки цепочки
сертификатов.

Алгоритм token-based authentication

Разберем подробнее последнюю из описанных схем. На схеме представлен упрощенный алгоритм Token-Based Authentication на примере реализации возможности «Зайти с помощью Google аккаунта»

Доменное имя

Пожалуй, все начинается с покупки доменного имени. Затем вы настраиваете его в DNS-сервере (в роли DNS-сервера может выступать ваш облачный провайдер).

Вероятно, вы приобретете облачный сервер (виртуальную машину) или что-то типа того, и там будет постоянный публичный IP-адрес.

Чтобы ваш домен указывал на IP-адрес вашего сервера, вы настраиваете A record («А»-запись) на DNS-сервере.

Скорее всего вам придется проделать все это лишь однажды, при первоначальной настройке.

Использованное по


Ubuntu Server 10.10 (Linux 2.6.35-22-server #35-Ubuntu SMP x86_64 GNU/Linux)

nginx 0.9.3

OpenSSL 0.9.8o 01 Jun 2022

Как это работает let’s encrypt

Есть три существенных различия между Let’s Encrypt и другими CA.

Конфиг nginx

listen *:443;
ssl on;
ssl_certificate /path/to/nginx/ssl/server.crt;
ssl_certificate_key /path/to/nginx/ssl/server.nopass.key;
ssl_client_certificate /path/to/nginx/ssl/ca.crt;
ssl_verify_client on;

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;

Настройка сервера для использования let’s encrypt

cPanel

Войдите в вашу cPanel.Проскрольте в секцию «Security» и кликните по «Let’s Encrypt for cPanel».

Несколько приложений на одном сервере

На одном сервере (или серверах) может быть много приложений. Например, другие API-программы или базы данных.

На одном порту по одному адресу обслуживается лишь один процесс (в нашем примере — TLS Termination Proxy). Но на сервере (или серверах) могут быть запущены и другие приложения/процессы, если только они не используют ту же комбинацию публичного IP и порта.

Обновление сертификата

Рано или поздно у каждого сертификата истекает срок годности (например, через три месяца после приобретения).

После этого специальная программа (иногда — тот же TLS Termination Proxy) обращается к Let’s Encrypt и возобновляет сертификат(ы).

TLS-сертификаты привязаны к доменному имени, не к IP-адресу.

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

Это можно сделать разными способами. Например:

  • Модифицировать какие-нибудь DNS-записи.
    • Для этого программа должна поддерживать API DNS-провайдера. Поэтому то, доступен ли для вас такой вариант, зависит от вашего провайдера.
  • Запуститься как сервер на публичном IP-адресе, связанном с доменом (по крайней мере на время процедуры получения сертификата).
    • Как уже говорилось, на одном адресе и одном порту может прослушиваться только один процесс.
    • Это одна из причин, почему полезно «поручать» обновление сертификатов тому же TLS Termination Proxy.
    • Если обновлением занимается другая программа, вам нужно будет остановить TLS Termination Proxy, запустить другую программу для получения сертификатов, затем настроить их в TLS Termination Proxy и перезапустить его. Это не идеальный выход, потому что во время этой процедуры ваше приложение будет недоступно.

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

Надеюсь, был кому-то полезен.

P.S. Этот пост был моей первой публикацией 16 января 2022 года, старая копия удалена (по желанию администрации сайта и потому, что она не была привязана к моему аккаунту).

Продление срока действия сертификата

Ваш сертификат действует не вечно, а только определенный период. Обычно, это год. Не ждите последнего момента чтобы продолжить сертификат, ваш регистратор посылать вам напоминание как только приблизится дата конца его действия. Я рекомендую оформить новый сертификат при первом таком напоминанию.

Эта процедура мало отличается от получения нового сертификата: создание CSR, получение сертификата и его установки. К тому же, сертификат будет валидным сразу после подписания, и до даты прекращения действия прошлого сертификата один год. То есть, будет время, когда оба сертификата будут работать, а в вас будет время, чтобы проверить работу нового сертификата без заминок в работе вашего сайта.

Аннулирование

Ссылки на использованные списки:

Желаю всем легкодоступных, но безопасных API! )

It’s only the beginning!

Стандарты безопасности

Начнем со стандартов. Существует несколько стандартов, которые помогут нам сформулировать список требований к безопасности API:

OWASP (Open Web Application Security Project) известна своими списками рисков в разных программных технологиях. Нам интересен список «10 наиболее опасных уязвимостей при разработке API»:

Добавлю пункты, которые

, но относятся к нашей теме:


А также уязвимости из списка другой организации Common Weakness Enumeration (CWE):

И несколько пунктов из других найденных списков:

В результате получился список, который, на мой взгляд, достаточно полно отражает современные проблемы безопасности API. Для проверки того, что список получился общим и применимым для всех технологий я использовал рекомендации по безопасности API, найденные на просторах Интернета (ссылки приведены в конце статьи). Далее рассмотрим все перечисленные пункты.

Шаг 1. создание собственного самоподписанного доверенного сертификата.

Собственный доверенный сертификат (Certificate Authority или CA) необходим для подписи клиентских сертификатов и для их проверки при авторизации клиента веб-сервером.С помощью приведенной ниже команды создается закрытый ключ и самоподписанный сертификат.

Шаг 2. сертификат сервера

Создадим сертификат для nginx и запрос для него

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr

Подпишем сертификат нашей же собственной подписью

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

Чтобы nginx при перезагрузке не спрашивал пароль, сделаем для него беспарольную копию сертификата

openssl rsa -in server.key -out server.nopass.key

Шаг первый: создание частного ключа и запроса на подписание сертификата (csr)

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

cPanel

  • Войдите в вашу cPanel
  • Проскрольте в секцию «Security» и кликните на «SSL / TLS».
cPanel
cPanel
  1. Кликните по «Private Keys (KEY)», чтобы создать новый частный ключ.
  • Выставьте параметр «Key Size» в «2048-bit» и нажмите «Generate»
Выставьте параметр «Key Size» в «2048-bit» и нажмите «Generate»
Выставьте параметр «Key Size» в «2048-bit» и нажмите «Generate»
  • Будет сгенерирован новый частный ключ и вы увидите подтверждение.
Будет сгенерирован новый частный ключ и вы увидите подтверждение.
Будет сгенерирован новый частный ключ и вы увидите подтверждение.

Если вы вернетесь на страницу «Private Keys», то увидите этот ключ в списке.

Если вы вернетесь на страницу «Private Keys», то увидите этот ключ в списке.
Если вы вернетесь на страницу «Private Keys», то увидите этот ключ в списке.
  • Вернитесь к странице «SSL / TLS Manager» и кликните по «Certificate Signing Requests (CSR)», чтобы создать CSR.
Вернитесь к странице «SSL / TLS Manager» и кликните по «Certificate Signing Requests (CSR)», чтобы создать CSR.
Вернитесь к странице «SSL / TLS Manager» и кликните по «Certificate Signing Requests (CSR)», чтобы создать CSR.

Теперь выберите ключ, мы только что сгенерировали в соответствующем поле. Заполняйте все поля правильно, ведь эта информация будет видно публично в вашем сертификате. Обратите особое внимание на секцию «Domains», имя домена должно точно совпадать. Когда закончите, нажмите кнопку «Generate».

  • Новый CSR будет создан, вы увидите подтверждение.

Если вы вернетесь на страницу «Certificate Signing Request», то увидите созданный CSR:

Если вы вернетесь на страницу «Certificate Signing Request», то увидите созданный CSR:
Если вы вернетесь на страницу «Certificate Signing Request», то увидите созданный CSR:

Шаг третий: установка сертификата

cPanel

Вернитесь на страницу «SSL / TLS Manager». Кликните по «Certificates (CRT)», чтобы импортировать новый сертификат.

Вы будете перемещены на страницу «Paste, Upload or Generate». Загрузите или скопируйте контент файла полученный на прошлом шаге.

Когда вы загрузите сертификат, его содержание будет распознано и данные появятся в соответствующих полях. Нажмите кнопку «Save Certificate».

Сертификат будет сохранен, а вы получите сообщение с подтверждением.

Если вы вернетесь на страницу «Certificates (CRT)», то увидите наш сертификат.

Заключение


В статье мы рассмотрели угрозы, которые подстерегают API при его эксплуатации и способы борьбы с ними. В заключении приведу несколько общих выводов:

Похожее:  Территориальные управления ЕИРЦ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *