Як я можу перевірити https-з'єднання з Django так просто, як я можу не-https-з'єднання за допомогою 'runserver'?


109

У мене є програма, яка використовує "захищені" файли cookie і хочу перевірити її функціональність, не потребуючи налаштування складного сервера розробки з підтримкою SSL. Чи є спосіб зробити це так просто, як я можу перевірити незашифровані запити за допомогою ./manage.py runserver?


Ви не можете просто вказати runserver 443, щоб змусити сервер працювати на порт 443?
Furbeenator

@Furbeenator: На жаль, це не так - це просто зробить сервер HTTP на 443, що мені потрібно - це власне SSL-сервер.
Еван Грим

Відповіді:


109

Це не так просто, як вбудований сервер розробки, але не дуже важко отримати щось близько, використовуючи stunnel як посередник SSLifying між вашим браузером та сервером розробки. Stunnel дозволяє налаштувати на вашій машині легкий сервер, який приймає з'єднання на налаштованому порту, обертає їх SSL та передає їх до іншого сервера. Ми будемо використовувати це для відкриття порту оглушення (8443) і для передачі трафіку, який він отримує, до екземпляра запуску Django.

Спочатку вам знадобиться оглушення, яке можна завантажити тут, або може надати пакетна система вашої платформи (наприклад:) apt-get install stunnel. Я буду використовувати версію 4 оглушення (наприклад: /usr/bin/stunnel4на Ubuntu), версія 3 також буде працювати, але має різні параметри конфігурації.

Спочатку створіть каталог у своєму проекті Django, щоб вмістити необхідні файли конфігурації та SSLish.

mkdir stunnel
cd stunnel

Далі нам потрібно створити локальний сертифікат і ключ, який буде використовуватися для зв'язку SSL. Для цього ми звернемося до openssl.

Створіть ключ:

openssl genrsa 1024 > stunnel.key

Створіть сертифікат, який використовує цей ключ (це попросить вас купу інформації, яка буде включена у сертифікат - просто дайте відповідь, що вам здається добре):

openssl req -new -x509 -nodes -sha1 -days 365 -key stunnel.key > stunnel.cert

Тепер об'єднайте їх в один файл, який stunnel використовуватиме для свого SSL-зв’язку:

cat stunnel.key stunnel.cert > stunnel.pem

Створіть конфігураційний файл для оглушення під назвою 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 (той, який у ньому розміщено manag.py):

cd ..

Тут ми створимо скрипт з ім'ям runserver, який запустить оглушення та два сервери розвитку django (один для звичайних з'єднань і один для з'єднань SSL):

stunnel4 stunnel/dev_https &
python manage.py runserver&
HTTPS=1 python manage.py runserver 8001

Давайте розбимо це по черзі:

  • Рядок 1: Починає оглушення і вказує на файл, який ми тільки що створили. Це оглушення прослуховує порт 8443, загортає будь-які з'єднання, які він отримує в SSL, і передає їх порту 8001
  • Рядок 2: запускає звичайний екземпляр запуску Django (на порту 8000)
  • Рядок 3: запускає інший екземпляр запуску Django (на порту 8001) і налаштовує його на обробку всіх вхідних з'єднань так, ніби вони виконувалися за допомогою HTTPS.

Зробіть файл, який ми тільки що створили, виконуваним:

chmod a+x runserver

Тепер, коли ви хочете запустити свій сервер розробки, просто виконайте його ./runserverз каталогу проектів. Щоб спробувати це, просто наведіть браузер на http: // localhost: 8000 для нормального трафіку HTTP та https: // localhost: 8443 для HTTPS-трафіку. Зауважте, що ваш веб-переглядач майже напевно скаржиться на використаний сертифікат і вимагатиме від вас додати виняток або іншим чином явно доручити браузеру продовжувати перегляд. Це тому, що ви створили власний сертифікат, і браузер не довіряє йому правду про те, хто це. Це добре для розвитку, але очевидно, це не скоротить його для виробництва.

На жаль, на моїй машині цей сценарій runserver не виходить гарним чином, коли я натиснув Ctrl-C. Мені вручну вбивати процеси - хтось має пропозицію виправити це?

Завдяки Майклу Gilė по пошті і Джанго переплетення в запис вікі для довідкового матеріалу.


3
Я просто натрапив на цю відповідь. Деякі зауваження: вам не обов’язково потрібно запускати окремий екземпляр розробки на 8001, ви також можете дозволити йому підключитися до порту 8000. Якщо ви хочете, щоб оглушення вбивалося автоматично, додайте функцію та вихідну пастку: kill_stunnel () { kill $ stunnel_pid} trap kill_stunnel вихід stunnel4 stunnel / dev https & stunnel_pid = $ 1
Friek

2
Другий екземпляр викликається HTTPS = 1, що означає, що request.is_secure()буде звітувати True. Якщо вам це не потрібно, ви маєте рацію - ви можете просто вказати оглушення на один екземпляр.
Еван Грім

Якщо ви працюєте в режимі фіксації оглушення, не підтримується .... додайте файли fips = ні до файлу dev_https, щоб вимкнути його
yeahdixon

2
Я просто спробував це, коли намагаюся створити копію розробки роботи на сайті над проектом, розробленим кимось іншим, але я отримую "sslVersion = SSLv3": SSLv3 not supported.
ГенріМ

@Friek stunnel_pid=$1не працював для мене, але stunnel_pid=$!робив. Як stunnel_pid=$1ви працювали?
Утку

86

Я рекомендую використовувати пакет django-sslserver .

Поточний пакет на PyPI підтримує лише версію Django 1.5.5, але патч був здійснений через 5d4664c . За допомогою цього виправлення система працює добре і є досить простим і зрозумілим рішенням для тестування https-з'єднань.

ОНОВЛЕННЯ: Оскільки я опублікував свою відповідь, комісія вище була об'єднана в головну гілку, і новий випуск був перенесений на PyPI. Таким чином, не повинно бути ніякої необхідності вказувати 5d4664c комісію для цього конкретного виправлення.


5
Це виглядає перспективно - мені, можливо, доведеться оновити прийняту відповідь на цю. Хтось ще хоче зважити?
Еван Грім

3
це повинно стати прийнятою відповіддю, яка використовується на деякий час у досить складному проекті, який просто не може працювати без запуску на https і ніколи не мав проблем.
simone cittadini

2
Добре працює ... Дякую! :)
nidHi

5
Працює з Python 3.6.2 та Django 1.11.3.
фенікс

2
Працює з Python 3.5 та Django 1,11
Hansel

64

Подібно до django-sslserver, ви можете використовувати RunServerPlus з django-extensions

Він має залежність від Werkzeug (тому ви отримуєте доступ до відмінного налагоджувача Werkzeug) та pyOpenSSL (необхідний лише для режиму ssl), щоб встановити запуск:

pip install django-extensions Werkzeug pyOpenSSL

Додайте його до INSTALLED_APPS у вашому файлі settings.py проекту:

INSTALLED_APPS = (
    ...
    'django_extensions',
    ...
)

Тоді ви можете запустити сервер у режимі ssl за допомогою:

./manage.py runserver_plus --cert /tmp/cert

Це створить файл cert у /tmp/cert.crtта ключ-файл, за допомогою /tmp/cert.keyякого потім можна буде повторно використовувати для майбутніх сеансів.

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


2
Насправді найкраща відповідь для Django 1.6+, оскільки django-sslserver не підтримує автоматичне перезавантаження нової версії
Zat42

Найкраща відповідь для налагодження + активація SSL.
Юда Правіра

Цікаво, чому це не працює в контейнерному додатку докер
Roel

@Roel швидко спробував, і, здається, працює для світового додатка привіт. може бути, що базове зображення не вимагає залежностей (наприклад, якщо ви використовуєте -alpine) або вам може знадобитися відкрити свій діапазон IP, наприклад./manage.py runserver_plus --cert /tmp/cert 0.0.0.0:8000
djsutho

FileNotFoundError: [Errno 2] Немає такого файлу чи каталогу: '/tmp\\cert.crt'
Марк Ентоні Лібрес

38

просто встановіть

sudo pip install django-sslserver

включити sslserver до встановлених aps

INSTALLED_APPS = (...
"sslserver",
...
)

тепер ти можеш бігати

 python manage.py runsslserver 0.0.0.0:8888

2
Найчистіше рішення!
SexyBeast

дійсно чисте рішення, але чомусь це дуже повільно
Bhanu Tez

Хм, Chrome попереджає, що сертифікат недійсний.
нульовий знак

@zerohedge це просто для розвитку, тому це не має значення.
Sharpless512

це дуже елегантно - але чи є якесь рішення використовувати його для перевірки безпечних з'єднань? наприклад, якщо ви хочете протестувати проти API Graph Graph? developers.facebook.com/docs/graph-api/webhooks#setup
frednikgohar

14

Зареєструйтесь на https://ngrok.com/ . Ви можете використовувати https для тестування. Це може допомогти людям, які просто хочуть швидко протестувати https.


6
Для швидкого тестування це чудове рішення. І мені нічого не потрібно було підписувати, просто завантажуйте та запускайте.
GavKilbride

4

Для тих, хто шукає передплановану версію параметра оглушення для налагодження:

stunnel.pem - це сертифікат, сформований як у голосовій відповіді Евана Грімма.

Слухайте всі локальні інтерфейси на порту 443 і пересилайте до порту 80 на localhost

sudo stunnel -f -p stunnel.pem -P ~/stunnel.pid -r localhost:80 -d 443

sudo необхідний лише для вхідних портів (порт -d [host:]) під номером 1024


4
  1. Встановити ngrok. посилання для завантаження: https://ngrok.com/download
  2. Випуск наступної команди на терміналі

    ngrok http 8000

Він розпочне сесію ngrok. У ньому буде вказано два URL-адреси. Один зіставлений на http: // localhost: 8000 . Друге відображено на https: // localhost: 8000 . Перевірте знімок екрана нижче. Використовуйте або URL-адресу. Він відобразить ваш локальний сервер.

зразок скріншоту сесії ngrok


Найпростіший спосіб зробити це, але не забудьте поставити новий https URL наallowed_host
Roel

2

Це можна зробити в один рядок з 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


0

Обробіть SSL / TLS за допомогою проксі-сервера, такого як Nginx, а не Django. Nginx може бути налаштований на прослуховування на порт 443, а потім переадресацію запитів на ваш сервер розробки Django (як правило http://127.0.0.1:8000). Конфігурація Nginx для цього може виглядати наступним чином:

server {
    listen 443 ssl;
    server_name django-dev.localhost;

    ssl_certificate /etc/ssl/certs/nginx_chain.pem;
    ssl_certificate_key /etc/ssl/private/nginx.pem;    

    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
    }
}

Вам також необхідно зіставити django-dev.localhostз 127.0.0.1і додати django-dev.localhostдо ALLOWED_HOSTSв settings.py. У Linux вам потрібно буде додати наступний рядок до /etc/hosts:

127.0.0.1   django-dev.localhost

Тоді ви зможете зайти на https://django-dev.localhostсвій веб- сайт розробника, перейшовши у свій браузер (вам потрібно буде обійти попередження щодо безпеки вашого браузера).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.