У меня есть приложение, которое использует "безопасные" куки и хочет протестировать его функциональность без необходимости создания сложного сервера разработки с поддержкой SSL. Есть ли способ сделать это так же просто, как я могу протестировать незашифрованные запросы, используя ./manage.py runserver
?
Как я могу проверить соединения https с Django так же легко, как я могу, не используя https-соединения, используя "сервер-сервер"?
Ответ 1
Это не как просто, как встроенный сервер разработки, но не слишком сложно что-то закрыть, используя stunnel в качестве посредника SSLification между вашим браузером и сервером разработки. Stunnel позволяет вам настроить легкий сервер на вашем компьютере, который принимает соединения на настроенном порту, обертывает их SSL и передает их на другой сервер. Мы будем использовать это, чтобы открыть порт stunnel (8443) и передать любой трафик, который он получает, на экземпляр сервера Django.
Сначала вам понадобится stunnel, который может быть загружен здесь или может быть предоставлен вашей платформенной системой пакетов (например: apt-get install stunnel
). Я буду использовать версию 4 stunnel (например, /usr/bin/stunnel4
на Ubuntu), версия 3 также будет работать, но имеет разные параметры конфигурации.
Сначала создайте каталог в проекте Django, чтобы сохранить необходимые файлы конфигурации и файлы SSLish.
mkdir stunnel
cd stunnel
Далее нам нужно создать локальный сертификат и ключ, который будет использоваться для связи SSL. Для этого перейдем к openssl.
Создайте ключ:
openssl genrsa 1024 > stunnel.key
Создайте сертификат, который использует этот ключ (это спросит вас кучу информации, которая будет включена в certficate - просто ответьте тем, что вам нравится):
openssl req -new -x509 -nodes -sha1 -days 365 -key stunnel.key > stunnel.cert
Теперь объедините их в один файл, который stunnel будет использовать для связи с SSL:
cat stunnel.key stunnel.cert > stunnel.pem
Создайте файл конфигурации для stunnel с именем dev_https со следующим содержимым:
pid=
cert = stunnel/stunnel.pem
sslVersion = SSLv3
foreground = yes
output = stunnel.log
[https]
accept=8443
connect=8001
TIMEOUTclose=1
Этот файл сообщает stunnel, что ему нужно знать. В частности, вы говорите ему не использовать файл pid, где находится файл сертификата, какую версию SSL использовать, чтобы он работал на переднем плане, где он должен регистрировать свой вывод и что он должен принимать соединение на порту 8443 и перенести их на порт 8001. Последний параметр (TIMEOUTclose) сообщает ему, что он автоматически закрывает соединение через 1 секунду без активности.
Теперь вернитесь в каталог проекта Django (тот, у которого есть manage.py):
cd ..
Здесь мы создадим script namedervererver, который будет запускать stunnel и два сервера разработки django (один для обычных соединений и один для SSL-соединений):
stunnel4 stunnel/dev_https &
python manage.py runserver&
HTTPS=1 python manage.py runserver 8001
Позвольте сломать это, строка за строкой:
- Строка 1: запускает stunnel и указывает на файл конфигурации, который мы только что создали. Это прослушивает прослушивание на порту 8443, завершает любые подключения, которые он получает в SSL, и передает их по порту 8001
- Строка 2: запускает обычный экземпляр запуска Django (на порту 8000)
- Строка 3: запускает другой экземпляр сервера Django (на порт 8001) и настраивает его для обработки всех входящих подключений, как если бы они выполнялись с использованием HTTPS.
Создайте исполняемый файл, который мы только что создали, с помощью:
chmod a+x runserver
Теперь, когда вы хотите запустить сервер разработки, просто запустите ./runserver
из своего каталога проектов. Чтобы попробовать, просто укажите свой браузер на http://localhost:8000 для обычного HTTP-трафика, а https://localhost:8443 для трафика HTTPS. Обратите внимание, что вы в браузере почти наверняка жалуетесь на используемый сертификат и требуют, чтобы вы добавили исключение или иным образом явно указали браузер продолжить просмотр. Это связано с тем, что вы создали свой собственный сертификат, и браузеру не доверяет, чтобы он рассказывал правду о том, кто он. Это хорошо для развития, но, очевидно, не сократит его для производства.
К сожалению, на моей машине этот runerver script не удаляется красиво, когда я нажимаю Ctrl-C. Я должен вручную убить процессы - у кого есть предложение исправить это?
Спасибо Майкл Гил post и django-weave запись в вики для справочного материала.
Ответ 2
Я бы рекомендовал использовать django-sslserver пакет.
В текущем пакете PyPI поддерживается только до версии 1.5.5 Django, но патч был зафиксирован с помощью 5d4664c. С этим исправлением система работает хорошо и представляет собой довольно простое и простое решение для тестирования соединений https.
UPDATE: Поскольку я отправил свой ответ, фиксация выше была объединена в мастер-ветку, а новая версия была нажата к PyPI. Поэтому не нужно указывать фиксацию 5d4664c для этого конкретного исправления.
Ответ 3
Как и django-sslserver, вы можете использовать RunServerPlus из django-extensions
Он имеет зависимости от Werkzeug (поэтому вы получаете доступ к отличному отладчику Werkzeug) и pyOpenSSL (требуется только для режима ssl), поэтому для установки run:
pip install django-extensions Werkzeug pyOpenSSL
Добавьте его в INSTALLED_APPS в файле settings.py проекта.
INSTALLED_APPS = (
...
'django_extensions',
...
)
Затем вы можете запустить сервер в режиме ssl с помощью:
./manage.py runserver_plus --cert /tmp/cert
Это создаст файл сертификата в /tmp/cert.crt
и файл ключа в /tmp/cert.key
, который затем может быть повторно использован для будущих сеансов.
В django-расширениях есть множество дополнительных материалов, которые вы можете использовать, поэтому стоит быстро просмотреть документы.
Ответ 4
Зарегистрируйтесь на https://ngrok.com/. Вы можете использовать https для тестирования. Это может помочь людям, которые просто хотят быстро протестировать https.
Ответ 5
Для тех, кто ищет опцию stunnel для переднего плана для целей отладки:
stunnel.pem - это сертификат, сгенерированный, как в ответе на голосование Эвана Гримма.
Прослушивание всех локальных интерфейсов на порту 443 и пересылка на порт 80 на localhost
sudo stunnel -f -p stunnel.pem -P ~/stunnel.pid -r localhost:80 -d 443
sudo требуется только для входящих портов (-d [host:] port) под 1024
Ответ 6
Это можно сделать в одной строке с помощью socat:
socat openssl-listen:8443,fork,reuseaddr,cert=server.pem,verify=0 tcp:localhost:8000
где 8443 - это порт для прослушивания входящих HTTPS-соединений, server.pem является самоподписанным сертификатом сервера и localhost: 8000 - это отладочный HTTP-сервер, запущенный как обычно.
Подробнее: http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html