Защита сайта сертификатом p12

Задача: обеспечить вход на сайт только при наличии действующего сертификата формата p12.

Решение:

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

Сначала создадим корневой сертификат сервера и необходимые для дальнейшей работы файлы и папки. Для этого создадим в любой папке файл root_cer.sh с содержимым вида:

mkdir db                # БД сертификатов
mkdir certs             # ключ и сертификат сервера
mkdir db/certs          # пользовательские сертификаты
mkdir db/newcerts       # новые сертификаты
mkdir p12               # сертификаты для передачи клиентам (p12)
touch db/index.txt
echo "01" > db/serial
openssl req -new -newkey rsa:2048 -nodes -keyout certs/server.key -x509 -days 1024 \
          -subj /C=RU/ST=Vol/L=Vol/O=LTD\ ElkiPalki/OU=Sale/CN=zz/emailAddress=wefwerfwe@gmail.com \
          -out certs/server.crt

, где:

rsa:2048- длина ключа, -days — сколько дней действителен сертификат, -x509 — создаём самоподписаный сертификат, /C — страна, /ST — область, /L — город, /O — организация, /OU — отдел,

Результатом работы будут два файла в папке certs: servert.crt (сертификат) и serverk.key (закрытый ключ). Данные закрытого ключа можно посмотреть при помощи:

openssl rsa -noout -text -in server.key  
openssl x509 -noout -text -in server.crt           

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

В файл db/index.txt сохраняются данные о подписываемых сертификатах.

Далее необходимо создать файл с настройками для генерации пользовательских сертификатов 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            = ./certs/server.crt        # Файл сертификата CA
        private_key            = ./certs/server.key        # Файл закрытого ключа CA

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

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

        [ policy_anything ]
        countryName            = optional        # Код страны - не обязателен
        stateOrProvinceName    = optional        # ......
        localityName           = optional        # ......
        organizationName       = optional        # ......
        organizationalUnitName = optional        # ......
        commonName             = supplied        # ...... - обязателен
        emailAddress           = optional        # ......

Для автоматизации генерации клиентских сертификатов можно собрать небольшой bash скрипт:

#!/bin/bash
NO_ARGS=0
BASE_DIR=""
P12_DIR="$BASE_DIR/p12"
CA_CFG="$BASE_DIR/ca.config"            # Конфигурационный файл для подписи
CERTS="$BASE_DIR/db/certs"              # Каталог для хранения сертификатов
CA_FILE="$BASE_DIR/certs/server.crt"    # Доверенный сертификат (Им подписывам)

usage () {
  echo "Скрипт basename $0 предназначен для создания клиентских SSL сертификатов."
  echo ""
  echo "Использование: basename $0 email name password"
}

if [ $# -eq "$NO_ARGS" ]  # Сценарий вызван без аргументов?
then
  usage                   # Если запущен без "аргуменотов" - вывести справку
  exit $E_OPTERROR        # и выйти с кодом ошибки
fi

EMAIL=$1
echo "Email:$EMAIL"
NAME=$2
echo "Name:$NAME"
PASSWORD=$3
echo "Password:$PASSWORD"

# создаём запрос на клиентский сертификат
openssl req -new -newkey rsa:2048 -nodes -keyout "$CERTS/$NAME.key" \
        -subj /C=RU/CN=usr/emailAddress="$EMAIL" \
        -out "$CERT/$NAME.csr"

# подписываем запрос на сертификат при помощи доверенного сертификата
openssl ca -config "$CA_CFG" -in "$CERT/$NAME.csr" -out "$CERT/$NAME.crt" -batch

# создаём файл p12 для передачи клиенту
openssl pkcs12 -export -in "$CERT/$NAME.crt" -inkey "$CERTS/$NAME.key" \
        -certfile "$CA_FILE" -out "$P12_DIR/$NAME.p12" -passout pass:"$PASSWORD"

На входе скрипта необходимо задать email, имя пользователя без пробелов и пароль на установку сертификата. На выходе будет запись в БД сертификатов и непосредственно сам контейнер p12 в папке p12 для передачи клиенту.

И ещё один полезный скрипт, для автоматизации отзыва сертификатов revote.sh:

#!/bin/bash
NO_ARGS=0
BASE_DIR=""
CA_CFG="$BASE_DIR/ca.config"
CERTS="$BASE_DIR/db/newcerts"
usage () {
  echo "Скрипт basename $0 предназначен для отзыва клиентских SSL сертификатов."
  echo ""
  echo "Использование: basename $0 serial"
}
if [ $# -eq "$NO_ARGS" ]  # Сценарий вызван без аргументов?
then
  usage                   # Если запущен без "аргуменотов" - вывести справку
  exit $E_OPTERROR        # и выйти с кодом ошибки
fi

SERIAL=$1
echo "Отзываю сертификат: $CERTS/$SERIAL.pem"
openssl ca -config "$CA_CFG" -revoke "$CERTS/$SERIAL.pem"
# составим список отозваных в файл revoked.crl
openssl ca -gencrl -config "$CA_CFG" -out revoked.crl

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

openssl crl -in revoked.crl -text -noout

Осталось только настроить apache для того что бы он пускал на сайт, только при наличии сертификата, добавив:

SSLCACertificateFile /path/to/server.crt
SSLVerifyClient require

SSL сертификат Let’s Encrypt во FreeBSD 10.x + Apache24

1) Ставим официальный клиент из портов

2) Получаем SSL сертификат

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

3) Настраиваем Apache

Настройка сводится к изменению строчек в httpd-ssl.conf . Предполагается, что самоподписанный сертификат корневой, у вас уже установлен и сгенерирован.

 

4) В крон помещаем строчку на выполнение раз в месяц:




Автоматическое создание поддомена в apache

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

Решение: настроим apache так, чтобы он автоматически подхватывал доменное имя, и отдавал страницу из соотвествующей доменному имени папки:

1. Вкючаем модуль vhost_alias

2. Настраиваем основной кинфиг apache подобным образом образом:

 

3. Одно НО! Настроенный таким образом апач будет искать www.zxc.ru и zxc.ru в разных папках. Для устранения: в папке www.zxc.ru создадим .htaccess, который будет переадресовывать на zxc.ru:




Редирект по условию..

Задача: любой пользователь попадающий на сайт и у которого в адресной строке присутствует слово iptv должен  перенаправляется на один сайт, а все остальные — на другой.

Решение: правим .htaccess

Подробнее о регулярных выражениях:
В регулярном выражении можно использовать любые печатные символы и пробел, но часть символов имеет особое значение:

Круглые скобки () используются для выделения групп символов.

Символ ^ обозначает начало строки.

Символ $ обозначает конец строки.

Символ . обозначает любой символ.

Символ | обозначает альтернативу. Например, выражения «A|B» и «(ABC|DEF)» означают «A или B» и «ABC или DEF» соответственно.

Символ ? ставится после символа (или группы символов), который может как присутствовать, так и отсутствовать. Например, выражению «jpe?g» подойдет и строка «jpg», и строка «jpeg». Пример выражения с группой символов: «super-(puper-)?site».

Символ * ставится после символа (или группы символов), который может отсутствовать или присутствовать неограниченное число раз подряд. Например, выражению «jpe*g» подойдут строки «jpg», «jpeg» и «jpeeeeeeg».

Символ + действует аналогично символу * с той лишь разницей, что предшествующий ему символ обязательно должен присутствовать хотя бы один раз. Например, выражению «jpe+g» подойдут строки «jpeg» и «jpeeeeg», но не «jpg».

Квадратные скобки [] используются для перечисления допустимых символов. Например, выражение «[abc]» равносильно выражению «a|b|c», но вариант с квадратными скобками обычно является более оптимальным по быстродействию. Внутри скобок можно использовать диапазоны: например, выражение «[0-9]» равносильно выражению «[0123456789]». Если символы внутри квадратных скобок начинаются с символа ^, это означает любой символ, кроме перечисленных в скобках. Например, выражение «[^0-9]+» означает строку из любых символов, кроме цифр.

Символ \ ставится перед спецсимволами, если они нужны в своем первозданном виде. Например, выражению «jpe\+g» соответствует только одна строка «jpe+g».

{3,9} — фигурные скобки означают диапозон количества символов, в данном случае допускается от 3 до 9 символов, длина строки из символов должна быть равна или более 3 равна или менее 9 символов. Применяется в основном в модуле преобразований — синтаксис регулярных выражений преобразований, значение флагов. Пример, проверяем строку HTTP запроса отправленную браузером серверу на предмет совпадения ее содержания определенному шаблону:
♳ RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
♴ предположим что мы запросили индексную сраницу на сервере %{THE_REQUEST} = «GET /index.html HTTP/1.1»
♵ в таком случае мы читаем исходную строку содержащую фигурные скобки так «начало_полученных_данныхGETпробел/index.phpпробелHTTP/»
♶ т.е. может быть «GET», а может быть «POST» могут быть и другие значения… просто символы, в зависимости от того чем и как мы запросим файл index.php на сервере.

Все, что расположено после символа ‘#’, считается комментарием.