Отказ от SSLv2 и SSLv3 с уведомлением пользователей: различия между версиями

Материал из Bas Wiki
Перейти к навигации Перейти к поиску
Строка 96: Строка 96:
}
}
</source>
</source>
Второй вариант конфига, который может пригодится, в случае отслеживания устаревших шифров. Здесь мы не используем location, а используем связку условного оператора if и переменной:
server {
listen 443 ssl;
server_name gwtools.ru;


ssl_certificate /etc/apache2/certs/public.crt;
ssl_certificate_key /etc/apache2/certs/private.key;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        root /usr/share/nginx/www;
        proxy_pass http://127.0.0.1:10080/;
proxy_redirect http://$host:10080/ /;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $flag "";
if ($uri !~ "sslv3.html") {
set $flag "${flag}1";
}
if ($ssl_protocol = "SSLv3") {
set $flag "${flag}2";
}
if ($flag = "12") {
return 302 https://$host/sslv3.html;
}
}
</source>
<br />
<br />



Версия от 14:46, 3 июля 2015

Вступление

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

Как бы быстро не двигался прогресс большое количество пользователей по всему миру используют устаревшее программное обеспечение. Windows XP и Internet Explorer'ы старых версий до сих пор используются в сети, которые не знают ничего о новых стандартах информационной безопасности. Тут и появляется одна большая проблема сложного выбора: не отворачиваться от старых во всех смыслах пользователей, но подвергать их опасности утечки данных или повысить минимальный порог безопасности, оставив за бортом ретроградов.

В моём случае такой вопрос не стоял, поэтому необходимо было готовится к переходу на современные протоколы и шифры максимально безболезненно для пользователей. За основу была взята статья Security/Server Side TLS в wiki Mozilla. Все настройки проводятся по конфигурации Intermediate. В данной статье я рассмотрю вариант, где мы будем работать только с протоколами. Это неплохой шаблон, который может пригодится в будущем для других интересных манипуляциях. Итак, приступим.


Анализ

Была определена дата, когда устаревшие протоколы будут отключены. Полетели e-mail рассылки и уведомления через систему сообщений о необходимости обновления ПО пользователям сервисов. Мы прекрасно понимали, что найдутся те, кто не увидят рассылок или попросту проигнорируют их. Для таких клиентов было решено поставить страницу-заглушку, которая бы содержала сообщение "что именно случилось", "что необходимо сделать" и "куда можно обратиться за подробностями". Данная страница будет включена при наступлении времени X. В течение 2 недель мы ловим нерасторопных пользователей и уже после этого окончательно выключаем устаревшие протоколы.

Перед тем как приступать к такого рода изменениям необходимо было оценить масштаб бедствия и подсчитать количество пользователей, использующих устаревшие браузеры. В этом отлично помогают сервисы Яндекс.Метрика и Google Analytics. Если же вы не использовали подобные инструменты, то на помощь придут анализаторы логов AWStats или Webalizer. В моём случае один сайт был с аналитикой, а другой был закрытый и там данные собирались с помощью AWStats.

В результате у нас было менее 3% пользователей, использовавших устаревшие браузеры и операционные системы. Конкретных цифр не будет :) Под эту категорию мы рассматривали пользователей с Internet Explorer 7.0 и ниже, а так же с Windows XP SP2 и ниже. Есть большое количество статей, в которых подробно описаны проблемы данных версий. Часть из них вы найдёте ниже. Основной посыл: старое ПО не поддерживает современные шифры и не имеет поддержку современных протоколов.

Технически это выглядит так:

  • Настраивается связка nginx (frontend) + Apache (backend), которая запускается в работу в обозначенную дату.
  • nginx использует те же устаревшие протоколы и шифры, что и текущий боевой Apache.
  • При подключении к сайту пользователь попадает на nginx, который примет любое подключение, даже со старыми протоколами и шифрами.
  • Если протокол шифрования нас устраивает, то пользователь работает как и обычно.
  • Если пользователь подключился по устаревшим протоколам, то его перекинет на специально подготовленную страницу.


Настройка Apache

В файле /etc/apache2/ports.conf мы комментируем использование портов 80 и 443 (8, 9, 17 и 21 строки). Обратите внимание, что я не добавляю слушающий порт в этом файле.

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default
# This is also true if you have upgraded from before 2.2.9-3 (i.e. from
# Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
# README.Debian.gz

#NameVirtualHost *:80
#Listen 80

<IfModule mod_ssl.c>
    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to <VirtualHost *:443>
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.
#    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
#    Listen 443
</IfModule>


В файле /etc/apache2/sites-available/gwtools.ru комментируем используемые виртуальные хосты для нашего сайта и делаем новый. Обратите внимание, что я открываю слушающий порт на локальном интерфейсе, т. к. я не хочу, чтобы Apache был доступен через снаружи. Так же мы используем обычный порт, а не SSL, т. к. нет смысла нагружать сервер шифрованием при локальной передаче через loopback-интерфейс.

Listen 127.0.0.1:10080
<VirtualHost 127.0.0.1:10080>
	DocumentRoot /var/www/gwtools.ru/
</VirtualHost>


Настройка nginx

Виртуальный хост для нашего сайта. Обратите внимание на то, что мы забираем на себя SSL-сертификаты Apache. Переменная $ssl_protocol возвращает протокол установленного SSL-соединения. Ещё нас может заинтересовать переменная $ssl_cipher, которая возвращает строку используемых шифров для установленного SSL-соединения, но в данной статье мы её не рассматриваем. Опция proxy_redirect (18 строка) необходима, т. к. в Apache для сайта используются редиректы с помощью mod_rewrite.

server {
	listen	80;
	return	301 https://$host$request_uri;
}

server {
	listen		443 ssl;
	server_name	gwtools.ru;

	ssl_certificate		/etc/apache2/certs/public.crt;
	ssl_certificate_key	/etc/apache2/certs/private.key;
	ssl_protocols		SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;

        root	/usr/share/nginx/www;

        location / {
		proxy_pass		http://127.0.0.1:10080/;
		proxy_redirect		http://$host:10080/ /;
		proxy_set_header	Host		$host;
		proxy_set_header	X-Real-IP	$remote_addr;
		proxy_set_header	X-Forwarded-For	$proxy_add_x_forwarded_for;

		if ($ssl_protocol = "SSLv3") {
			return 302 https://$host/sslv3.html;
		}
	}

	location = /sslv3.html {
	}

}

Второй вариант конфига, который может пригодится, в случае отслеживания устаревших шифров. Здесь мы не используем location, а используем связку условного оператора if и переменной: server { listen 443 ssl; server_name gwtools.ru;

ssl_certificate /etc/apache2/certs/public.crt; ssl_certificate_key /etc/apache2/certs/private.key; ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;

       root	/usr/share/nginx/www;
       proxy_pass		http://127.0.0.1:10080/;

proxy_redirect http://$host:10080/ /;

proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

set $flag "";

if ($uri !~ "sslv3.html") { set $flag "${flag}1"; }

if ($ssl_protocol = "SSLv3") { set $flag "${flag}2"; }

if ($flag = "12") { return 302 https://$host/sslv3.html; } } </source>

Заключение


Ссылки
  1. Security/Server Side TLS
  2. Как и зачем мы делаем TLS в Яндексе
  3. Выбор ciphersuites для TLS и уязвимость Logjam. Опыт Яндекса
  4. Модуль ngx_http_ssl_module - Встроенные переменные