Содержание
Выбрав фреймворк Django для разработки корпоративного сайта, я столкнулся с проблемой тестирования его работы по протоколу HTTPS при использовании встроенного веб-сервера. Несмотря на поддержку работы с безопасными соединениями в Django, поставляемый в комплекте веб-сервер не обслуживает запросы по HTTPS.
Первое, что пришло в голову, поднять полноценный веб-сервер (например, Apache) для разработки и тестирования, но что если не хочется отказываться от удобств и простоты использования встроенного веб-сервера Django?
Поиск в Интернете по запросу «django + https» выдал несколько статей датированных 2009 и 2012 годами, в которых для тестирования HTTPS предлагается использовать stunnel.
Данная статья является инструкцией полученной в результате настройки stunnel
под среду разработки Django на Ubuntu 12.04.1 LTS x64.
Программная среда
- Ubuntu 12.04.1 LTS (x64)
- OpenSSL 1.0.1 14 Mar 2012
- Python 2.7.3
- virtualenv 1.8.4
- Django 1.5.1
Установка и настройка stunnel
Для начала необходимо установить stunnel
(версии 4.х, ветка 3.х более не поддерживается):
$ sudo apt-get install stunnel4
Базовые настройки stunnel
находятся в файле /etc/default/stunnel4
:
# /etc/default/stunnel # Julien LEMOINE <[email protected]> # September 2003 # Change to one to enable stunnel automatic startup ENABLED=0 # Configuration file loacation mask FILES="/etc/stunnel/*.conf" OPTIONS="" # Change to one to enable ppp restart scripts PPP_RESTART=0
В нашем случая изменения вносить не нужно, так как stunnel
будет использоваться лишь в связке с веб-сервером Django на время разработки и тестирования.
А вот то, что понадобится обязательно — сертификат X.509.
Генерация сертификата
В руководстве stunnel указаны следующие требования к сертификату:
…. Each SSL enabled daemon needs to present a valid X.509 certificate to the peer. It also needs a private key to decrypt the incoming data. The easiest way to obtain a certificate and a key is to generate them with the free OpenSSL package …
… The order of contents of the .pem file is important. It should contain the unencrypted private key first, then a signed certificate (not certificate request). There should be also empty lines after certificate and private key. Plaintext certificate information appended on the top of generated certificate should be discarded. So the file should look like this:
——BEGIN RSA PRIVATE KEY——
[encoded key]
——END RSA PRIVATE KEY——
[empty line]
——BEGIN CERTIFICATE——
[encoded certificate]
——END CERTIFICATE——
[empty line]
Для генерации приватного ключа и сертификата воспользуемся OpenSSL (должен присутствовать в Ubuntu 12.04.1):
$ cd ~ $ openssl genrsa -out private.key $ openssl req -new -x509 -key private.key -out stunnel.cert -days 365
Во время генерации необходимо ввести данные о владельце (коды стран для удобства).
На выходе получаем два файла private.key
и stunnel.cert
, которые необходимо объединить и добавить пустые строки согласно шаблона:
$ (cat private.key ; echo ; cat stunnel.cert ; echo) > stunnel.pem
Теперь создадим файл конфигурации для туннеля.
Файл конфигурации
Пример файла конфигурации stunnel.conf-sample
находится в /usr/share/doc/stunnel4/examples/
, а описание параметров можно посмотреть в man stunel4
или в документации. Плюс ко всему, раздел FAQ на сайте программы содержит некоторые полезные советы.
Создадим файл конфигурации в домашнем каталоге:
$ cd ~ $ vim stunnel.conf
В нашем случая он имеет следующее содержимое:
; Certificate & Key cert = ./stunnel.pem ; Use SSL version 3, which is more secure sslVersion = SSLv3 ; If next argument is empty, then no pid file will be created pid = ; if 'yes' stay in foreground (don't fork) and log to stderr instead of via syslog foreground = no ; Performance tweak from FAQ (https://www.stunnel.org/faq.html) socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 ; Enable compression compression = zlib ; Debugging - emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6), or debug (7) debug = 7 output = /var/log/stunnel4/stunnel.log ; HTTPS service section [https] ; Port to listen incoming client connections accept = 8443 ; Port which Django development server listens to connect = 8000 ; Tweak for MSIE (see FAQ or manual) TIMEOUTclose = 0
Давайте проверим, что получилось?
Создание туннеля и запуск веб-сервера
Запустим stunnel
и встроенный веб-сервер Django для тестового проекта (пустой проект, сразу после django-admin.py startproject
):
$ cd ~ $ stunnel4 stunnel.conf $ source django/bin/activate (django)$ cd django/projects (django)$ django-admin.py startproject testone (django)$ cd testone/ (djanho)$ HTTPS=on python manage.py runserver
Переменная окружения HTTPS=on необходима для корректной симуляции HTTPS в Django, без нее метод request.is_secure() будет возвращать False.
Проверим «прослушиваемые» порты:
$ netstat –an
Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State ... tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN ...
Туннель успешно создан — stunnel
слушает на всех внешних интерфейсах порт 8443, а веб-сервер локальные соединения на порту 8000.
Для «уничтожения» туннеля подойдет команда killall
:
$ ps -e | grep stunnel4
12530 pts/1 00:00:00 stunnel4 12531 pts/1 00:00:00 stunnel4 12532 pts/1 00:00:00 stunnel4 12533 pts/1 00:00:00 stunnel4 12534 pts/1 00:00:00 stunnel4 12535 ? 00:00:00 stunnel4
$ killall stunnel4
Проверка работы
Откроем в браузере любой существующий на сервере URL, используя https://
вместо http://
. При первом запросе мы должны увидеть предупреждения о ненадежном сертификате, т.к. подписан он был нами лично, а не аккредитованным центром (Certificate Authority). После подтверждения исключения безопасности, перед нами появится запрошенная страница, полученная по протоколу HTTPS.
Было
Стало
Заключение
В результате мы получаем возможность отладки работы проекта Django с использованием HTTPS без необходимости держать полноценный веб-сервер.
Хочу отметить, что на сайте stunnel
присутствует версия для Windows и Android, так что попытаться собрать подобную схему можно и на этих операционных системах.
Всем большое спасибо за внимание и надеюсь, что данная информация будет кому-то полезной.
Под конец перечислю те преимущества и недостатки, которые отметил для себя, а также приведу список ссылок.
Преимущества
+ не требуется установка полноценного веб-сервера;
+ возможность построения туннелей для нескольких Django веб-серверов;
+ использование преймуществ встроенного веб-сервера.
Недостатки
— это не полноценный веб-сервер с поддержкой HTTPS;
— необходимость в установке и настройки дополнительного ПО;
— фактически веб-сервер Django обрабатывает HTTP запросы (см. логи ниже).
Логи веб-сервера
Validating models…
0 errors found
July 26, 2013 — 10:06:33
Django version 1.5.1, using settings ‘testone.settings’
Development server is running at 127.0.0.1:8000/
Quit the server with CONTROL-C.
…
[26/Jul/2013 10:07:25] «GET / HTTP/1.1» 200 1955
[26/Jul/2013 10:07:30] «GET / HTTP/1.1» 200 1955
…
Материалы