Задача: Разобрать как закрыть Webресурс сертификатом.

Т.е. если у пользователя в браузере прописан сертификат, то он увидит Web-ресурс если нет в доступе будет отказано. Это как мне кажется будет по лучше всякой связки Логин + Пароль или ее дополнение. Просто на основе этой задачи я реализовал доступ к своему OwnCloud 10 через client.p12 сертификату, а уже далее авторизация в аккаунте.

Шаг №1: Устанавливаю Webсервис в систему Ubuntu 18.04 Server:

ekzorchik@srv-bionic:~$ sudo tasksel install lamp-server

ekzorchik@srv-bionic:~$ echo "ServerName localhost" | sudo tee -a /etc/apache2/apache2.conf

Шаг №2: Отменяю явно работу Webсервиса на порт http (80/tcp):

ekzorchik@srv-bionic:~$ sudo nano /etc/apache2/ports.conf

#Listen 80

<IfModule ssl_module>

Listen 443

</IfModule>

<IfModule mod_gnutls.c>

Listen 443

</IfModule>

Шаг №3: Создаю копию openssl.cnf.original:

ekzorchik@srv-bionic:~$ sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.original

Шаг №4: Создаю свой пользовательский openssl.cnf на основе которого будут создаваться сертификаты сервера и клиентов:

ekzorchik@srv-bionic:~$ nano openssl.cnf

[ req ]

default_md = sha1

distinguished_name = req_distinguished_name

[ req_distinguished_name ]

countryName = Country

countryName_default = RU

countryName_min = 2

countryName_max = 2

localityName = Locality

localityName_default = RUSSIAN

organizationName = Organization

organizationName_default = ekzorchik

commonName = Common Name

commonName_max = 64

[ certauth ]

subjectKeyIdentifier = hash

authorityKeyIdentifier = keyid:always,issuer:always

basicConstraints = CA:true

crlDistributionPoints = @crl

[ server ]

basicConstraints = CA:FALSE

keyUsage = digitalSignature, keyEncipherment, dataEncipherment

extendedKeyUsage = serverAuth

nsCertType = server

crlDistributionPoints = @crl

[ client ]

basicConstraints = CA:FALSE

keyUsage = digitalSignature, keyEncipherment, dataEncipherment

extendedKeyUsage = clientAuth

nsCertType = client

crlDistributionPoints = @crl

[ crl ]

URI=http://172.33.33.22/ca.crl

Шаг №5: Создаю на основе собственного openssl.cnf Удостоверяющий центр (ключ) и пару сертификатов для нашего CA:

ekzorchik@srv-bionic:~$ openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer

Generating a RSA private key

......................................................................................................................+++++

......................+++++

writing new private key to 'ca.key'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country [RU]:

Locality [RUSSIAN]:

Organization [ekzorchik]:

Common Name []:172.33.33.22

ekzorchik@srv-bionic:~$

Шаг №6: Создаем новый приватный ключ SSL Key (т.к. нельзя использовать тот который делался для CA):

ekzorchik@srv-bionic:~$ openssl genrsa -out server.key 2048

Шаг №7:

ekzorchik@srv-bionic:~$ openssl req -config ./openssl.cnf -new -key server.key -out server.req

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country [RU]:

Locality [RUSSIAN]:

Organization [ekzorchik]:

Common Name []:172.33.33.22

Шаг №8: При наличии самозаверяющего центра сертификации выдается сертификат сервера с серийным номером 100:

ekzorchik@srv-bionic:~$ openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 3650 -outform PEM -out server.cer

Signature ok

subject=C = RU, L = RUSSIAN, O = ekzorchik, CN = 172.33.33.22

Getting CA Private Key

ekzorchik@srv-bionic:~$

ekzorchik@srv-bionic:~$ rm server.req

Шаг №9: Создаем закрытый ключ для клиента SSL:

ekzorchik@srv-bionic:~$ openssl genrsa -out client.key 2048

Шаг №10: Что касается сервера и для клиента, вам нужно сгенерировать запрос на подпись сертификата, и в качестве общего имени я использовал строку: "alektest":

ekzorchik@srv-bionic:~$ openssl req -config ./openssl.cnf -new -key client.key -out client.req

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country [RU]:

Locality [RUSSIAN]:

Organization [ekzorchik]:

Common Name []:alektest

Шаг №11: С вашим самозаверяющим центром сертификации выдайте сертификат клиента с серийным номером 101:

ekzorchik@srv-bionic:~$ openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 365 -outform PEM -out client.cer

Signature ok

subject=C = RU, L = RUSSIAN, O = ekzorchik, CN = alektest

Getting CA Private Key

ekzorchik@srv-bionic:~$

Шаг №12: Сохраните личный ключ и сертификат клиента в формате PKCS # 12. Этот сертификат будет защищен паролем, и этот пароль будет использоваться в следующих разделах для импорта сертификата в диспетчер сертификатов веб-браузера:

ekzorchik@srv-bionic:~$ openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12

Enter Export Password: указываю пароль на расшифровку, к примеру 712mbddr@

Verifying - Enter Export Password: 712mbddr@

ekzorchik@srv-bionic:~$

Шаг №13: Файл "client.p12» содержит закрытый ключ и сертификат клиента, поэтому файлы "client.key", "client.cer" и "client.req" больше не нужны, поэтому эти файлы можно удалить.

ekzorchik@srv-bionic:~$ rm client.key client.cer client.req

а можно и не удалять, а завести папку и для каждого клиента их хранить вдруг понадобятся.

ekzorchik@srv-bionic:~$ sudo mkdir -p /etc/apache2/ssl/client

ekzorchik@srv-bionic:~$ sudo mv client.key client.cer client.req /etc/apache2/ssl/client/

Шаг №14: Создаю каталог для сертификат у Webсервиса Apache2 в поддиректории:

ekzorchik@srv-bionic:~$ sudo mkdir /etc/apache2/ssl

ekzorchik@srv-bionic:~$ sudo cp server.cer server.key /etc/apache2/ssl/

ekzorchik@srv-bionic:~$ sudo cp ca.cer /etc/apache2/ssl/ca.cer

Шаг №15: Проверяю, подгружен ли модуль ssl если нет, то подгружаю.

ekzorchik@srv-bionic:~$ apachectl -M | grep ssl

ekzorchik@srv-bionic:~$

ekzorchik@srv-bionic:~$ sudo a2enmod ssl && sudo systemctl restart apache2

Шаг №16: Описываю поведение на доступ к сайту через сертификат:

ekzorchik@srv-bionic:~$ sudo unlink /etc/apache2/sites-available/000-default.conf
ekzorchik@srv-bionic:~$ sudo a2dissite 000-default.conf
ekzorchik@srv-bionic:~$ sudo nano /etc/apache2/sites-available/default-ssl.conf
<IfModule mod_ssl.c>
	<VirtualHost _default_:443>
		ServerAdmin webmaster@localhost
		DocumentRoot /var/www/html
		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined
		SSLEngine on
		SSLCertificateFile	/etc/apache2/ssl/server.cer
		SSLCertificateKeyFile   /etc/apache2/ssl/server.key
		SSLVerifyClient require
		SSLVerifyDepth  1
		SSLCACertificateFile /etc/apache2/ssl/ca.cer
		<FilesMatch "\.(cgi|shtml|phtml|php)$">
				SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
		</Directory>
	</VirtualHost>
</IfModule>
ekzorchik@srv-bionic:~$ sudo a2ensite default-ssl.conf

Шаг №17: Проверяю сделанные изменения на предмет ошибок, если ошибок нет, то перезапускаю Webсервис:

ekzorchik@srv-bionic:~$ sudo apache2ctl configtest && sudo systemctl restart apache2 && sudo systemctl status apache2 | head -n5

Syntax OK

● apache2.service - The Apache HTTP Server

Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)

Drop-In: /lib/systemd/system/apache2.service.d

└─apache2-systemd.conf

Active: active (running) since Fri 2020-05-22 22:39:51 MSK; 22ms ago

ekzorchik@srv-bionic:~$

Шаг №18: Копирую любым способом на ПК клиента сделанный под него сертификат client.p12

ekzorchik@srv-bionic:~$ scp client.p12 ekzorchik@172.33.33.16:/home/ekzorchik

Шаг №19: Т.к. система с IP-адресом 172.33.33.16 — это моя рабочая система Ubuntu 18.04 Desktop amd64 ноутбука Lenovo E555, а рабочий браузер Google Chrome, если обратиться по URLадресу https://172.33.33.22 я получаю:

"Этот сайт не может обеспечить безопасное соединение.

Ваш сертификат отклонен сайтом 127.33.33.22 или не был выдан.

Обратитесь за помощью к системному администратору.

ERR_BAD_SSL_CLIENT_AUTH_CERT"

Доступ к сайту закрыт, требуется установленный сертификат

Если установить сертификат client.p12 в браузер Google Chrome:

Настройка и управление Google Chrome - Настройки - Дополнительные - Настроить сертификаты - Ваши сертификаты - Импорт — нахожу скопированный сертификат client.p12, выделяю его и нажимаю "Открыть", затем указываю пароль на распаковку

  • Введите пароль сертификата
  • Пароль: ввожу 712mbddr@

и нажимаю OK.

Результат добавленного клиентского сертификата:

Импортирую сертификат client.p12 в браузер Google Chrome

Шаг №20: Теперь при обращении на URLадрес https://172.33.33.22 появляется окно выбора сертификата, выбираю и нажимаю OK

Сертификат установлен, браузер предлагает выбрать какой использовать для доступа на сайт

и результат доступ к сайту, открывает дефолтная страница Web-сервиса Apache2

Сертификат установлен, сайт открывается

Чтобы в строке адреса не значилось что "Не защищено", также можно импортировать ca.cer, то "Не защищено" смениться на доверенный:

ekzorchik@srv-bionic:~$ scp ca.cer ekzorchik@172.33.33.16:/home/ekzorchik

Чтобы сайт был доверенным импортируем ca.cer

Результат:

Теперь сайт открывается и браузер ему доверяет

Работает. Вообще мне важно из всего выше указанного — это чтобы доступ к странице был закрыт сертификатом. Уже на основе данной заметке и реализовал для себя, защиту на доступ к своему OwnCloud 10 on Ubuntu 18.04 Server. Если будут еще нюансы я дополню данную заметку или на ее основе сделаю еще одну дополняющую. С уважением, Олло Александр aka ekzorchik.