Django ile https bağlantılarını 'runserver' kullanarak https olmayan bağlantıları olabildiğince kolay nasıl test edebilirim?


109

"Güvenli" tanımlama bilgileri kullanan bir uygulamam var ve karmaşık bir SSL etkin geliştirme sunucusu kurmaya gerek kalmadan işlevselliğini test etmek istiyorum. Bunu şifrelenmemiş istekleri kullanarak test edebildiğim kadar basit bir şekilde yapmanın bir yolu var mı ./manage.py runserver?


Sunucuyu 443 numaralı bağlantı noktasında çalıştırmak için çalıştırma sunucusu 443'ü belirtemez misiniz?
Furbeenator

@Furbeenator: Maalesef hayır - bu sadece sunucuyu 443'te HTTP yapacak, ihtiyacım olan gerçek bir SSL sunucusu çalışıyor.
Evan Grim

Yanıtlar:


110

O değil olarakYerleşik geliştirme sunucusu basit , ancak tarayıcınız ile geliştirme sunucusu arasında bir SSLleştirici aracı olarak stunnel kullanarak bir şeyi yakınlaştırmak çok da zor değil. Stunnel, makinenizde yapılandırılmış bir bağlantı noktasındaki bağlantıları kabul eden, bunları SSL ile saran ve başka bir sunucuya ileten hafif bir sunucu kurmanıza olanak tanır. Bunu bir stunnel bağlantı noktasını (8443) açmak ve aldığı trafiği bir Django çalıştırma sunucusu örneğine geçirmek için kullanacağız.

Öncelikle buradan indirilebilecek veya platformunuzun paket sistemi tarafından sağlanabilecek (örneğin :) stunnel'e ihtiyacınız olacak apt-get install stunnel. Stunnel'ın 4. sürümünü kullanacağım (örneğin: /usr/bin/stunnel4Ubuntu'da), sürüm 3 de çalışacak, ancak farklı yapılandırma seçeneklerine sahip.

Öncelikle Django projenizde gerekli yapılandırma dosyalarını ve SSLish öğelerini tutmak için bir dizin oluşturun.

mkdir stunnel
cd stunnel

Daha sonra, SSL iletişimi için kullanılacak yerel bir sertifika ve anahtar oluşturmamız gerekecek. Bunun için openssl'ye dönüyoruz.

Anahtarı oluşturun:

openssl genrsa 1024 > stunnel.key

Bu anahtarı kullanan sertifikayı oluşturun (bu size sertifikaya dahil edilecek bir dizi bilgi soracaktır - sadece size iyi gelen her şeyi yanıtlayın):

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

Şimdi bunları, stunnel'ın SSL iletişimi için kullanacağı tek bir dosyada birleştirin:

cat stunnel.key stunnel.cert > stunnel.pem

Aşağıdaki içeriğe sahip dev_https adlı stunnel için bir yapılandırma dosyası oluşturun:

pid=

cert = stunnel/stunnel.pem
sslVersion = SSLv3
foreground = yes
output = stunnel.log

[https]
accept=8443
connect=8001
TIMEOUTclose=1

Bu dosya stunnel'a bilmesi gerekenleri söyler. Spesifik olarak, bir pid dosyası kullanmamasını, sertifika dosyasının nerede olduğunu, hangi SSL sürümünü kullanacağını, ön planda çalışması gerektiğini, çıktısını nereye kaydetmesi gerektiğini ve bağlantı noktasında bağlantıyı kabul etmesi gerektiğini söylüyorsunuz. 8443 ve bunları 8001 numaralı bağlantı noktasına götürün. Son parametre (TIMEOUTclose), herhangi bir etkinlik olmadan 1 saniye geçtikten sonra bağlantıyı otomatik olarak kapatmasını söyler.

Şimdi Django proje dizininize geri dönün (içinde manage.py bulunan):

cd ..

Burada, stunnel ve iki django geliştirme sunucusunu çalıştıracak runserver adında bir betik oluşturacağız (biri normal bağlantılar için, diğeri SSL bağlantıları için):

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

Bunu satır satır parçalayalım:

  • Satır 1: Stunnel'ı başlatır ve onu az önce oluşturduğumuz yapılandırma dosyasına yönlendirir. Bu, 8443 numaralı bağlantı noktasında stunnel dinlemeye sahiptir, aldığı tüm bağlantıları SSL olarak sarar ve 8001 numaralı bağlantı noktasına iletir.
  • Satır 2: Normal bir Django çalıştırma sunucusu örneği başlatır (8000 numaralı bağlantı noktasında)
  • Satır 3: Başka bir Django çalıştırma sunucusu örneğini (bağlantı noktası 8001'de) başlatır ve onu gelen tüm bağlantıları HTTPS kullanılarak gerçekleştiriliyormuş gibi ele alacak şekilde yapılandırır.

Yeni oluşturduğumuz runscript dosyasını şununla çalıştırılabilir yapın:

chmod a+x runserver

Şimdi, geliştirme sunucunuzu çalıştırmak istediğinizde, sadece ./runserverproje dizininizden çalıştırın . Denemek için, tarayıcınızı normal HTTP trafiği için http: // localhost: 8000'e ve HTTPS trafiği için https: // localhost: 8443'e yönlendirmeniz yeterlidir . Tarayıcınızın kullanılan sertifika hakkında neredeyse kesinlikle şikayet edeceğini ve bir istisna eklemenizi veya tarayıcıya göz atmaya devam etmesi için açıkça talimat vermenizi gerektireceğini unutmayın. Bunun nedeni, kendi sertifikanızı oluşturmuş olmanız ve tarayıcının sertifikanın kim olduğu hakkında gerçeği söylediğine güvenilmemesidir. Bu geliştirme için iyidir, ancak belli ki üretim için kesmeyecektir.

Ne yazık ki, makinemde Ctrl-C'ye bastığımda bu çalıştırma sunucusu betiği güzelce çıkmıyor. İşlemleri manuel olarak sonlandırmam gerekiyor - bunu düzeltmek için bir önerisi olan var mı?

Michael Gile'nin gönderisi ve django-weave'in referans materyal için wiki girişi sayesinde.


4
Ben sadece bu cevaba rastladım. Bazı açıklamalar: 8001'de ayrı bir geliştirme örneği çalıştırmanız gerekmez, bunun 8000 numaralı bağlantı noktasına bağlanmasına da izin verebilirsiniz. Stunnel'ın otomatik olarak öldürülmesini istiyorsanız, bir işlev ve bir çıkış tuzağı ekleyin: kill_stunnel () { $ stunnel_pid} tuzak kill_stunnel çıkışına stunnel4 stunnel / dev https & stunnel_pid = $ 1 öldürmek
Friek

2
İkinci örnek HTTPS = 1 ile çağrılır, bu request.is_secure()da raporlayacağı anlamına gelir True. Buna ihtiyacınız yoksa, o zaman haklısınız - sadece stunnel'ı tek bir örneğe yönlendirebilirsiniz.
Evan Grim

Stunnel fips moduna geçerseniz desteklenmiyor .... kapatmak için dev_https dosyasına fips = no ekleyin
yeahdixon

2
Başka biri tarafından geliştirilen bir projede bir site çalışmasının geliştirme kopyasını oluşturmaya çalışırken bunu denedim ama alıyorum "sslVersion = SSLv3": SSLv3 not supported.
HenryM

@Friek stunnel_pid=$1benim için çalışmadı ama stunnel_pid=$!yaptı. stunnel_pid=$1Senin için nasıl çalıştı ?
Utku

86

Django-sslserver paketini kullanmanızı tavsiye ederim .

PyPI'daki mevcut paket yalnızca Django 1.5.5 sürümüne kadar destekler ancak 5d4664c aracılığıyla bir yama gerçekleştirilmiştir . Bu düzeltme ile sistem iyi çalışır ve https bağlantılarını test etmek için oldukça basit ve anlaşılır bir çözümdür.

GÜNCELLEME: Cevabımı yayınladığımdan beri, yukarıdaki taahhüt ana dalda birleştirildi ve yeni bir sürüm PyPI'ye aktarıldı. Bu nedenle, söz konusu düzeltme için 5d4664c kaydının belirtilmesine gerek yoktur.


5
Bu umut verici görünüyor - bununla ilgili kabul edilen yanıtı güncellemem gerekebilir. Tartışmak isteyen başka biri var mı?
Evan Grim

3
Bu, bir süre için oldukça karmaşık bir projede kullanılan, https üzerinde çalışmadan çalışamayan ve hiçbir zaman problem yaşamayan kabul edilen cevap haline gelmelidir.
simone cittadini

2
İyi çalışıyor ... Teşekkürler! :)
nidHi

5
Python 3.6.2 ve Django 1.11.3'ten itibaren çalışır.
phoenix

2
Python 3.5 ve Django 1.11'den itibaren çalışır
Hansel

64

Django-sslserver'a benzer şekilde , django-uzantılarından RunServerPlus'ı kullanabilirsiniz.

Werkzeug'a (böylece mükemmel Werkzeug hata ayıklayıcısına erişebilirsiniz) ve pyOpenSSL'ye (yalnızca ssl modu için gereklidir) bağımlılıkları vardır, bu nedenle çalıştırmayı kurmak için:

pip install django-extensions Werkzeug pyOpenSSL

Bunu projelerinizin ayarlar.py dosyasında INSTALLED_APPS'ye ekleyin:

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

Ardından sunucuyu ssl modunda şu şekilde çalıştırabilirsiniz:

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

Bu, adresinde bir sertifika dosyası /tmp/cert.crtve /tmp/cert.keydaha sonra gelecekteki oturumlar için yeniden kullanılabilecek bir anahtar dosyası oluşturacaktır.

Django uzantılarında yararlı bulabileceğiniz bir sürü ekstra şey vardır, bu nedenle dokümanlar arasında hızlı bir şekilde gezinmeye değer.


2
Aslında django-sslserver yeni sürüm için otomatik yeniden yüklemeyi desteklemediğinden, Django 1.6+ için en iyi cevap
Zat42

Hata ayıklama için en iyi cevap + SSL'yi etkinleştirin.
Yuda Prawira

Docker containerized uygulamasında neden çalışmadığını merak ediyorum
Roel

@Roel hızlı bir şekilde denedi ve bir merhaba dünya uygulaması için işe yarıyor gibi görünüyor. temel görüntünüzün gerekli bağımlılıkları olmayabilir (örneğin, -alpin kullanıyorsanız) veya IP aralığınızı açmanız gerekebilir örn../manage.py runserver_plus --cert /tmp/cert 0.0.0.0:8000
djsutho

FileNotFoundError: [Errno 2] Böyle bir dosya veya dizin yok: '/tmp\\cert.crt'
Mark Anthony Libres

38

sadece kur

sudo pip install django-sslserver

kurulu aps'ye sslserver'ı dahil et

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

şimdi koşabilirsin

 python manage.py runsslserver 0.0.0.0:8888

2
En temiz çözüm!
SexyBeast

gerçekten temiz bir çözüm, ancak nedense çok yavaş
Bhanu Tez

Hmm, Chrome, sertifikanın geçersiz olduğuna dair bir uyarı veriyor.
zerohedge

@zerohedge sadece geliştirme içindir, bu yüzden önemli değil.
Sharpless512

bu çok zarif - ancak güvenli bağlantıları test etmek için bunu kullanmanın herhangi bir çözümü var mı? Örneğin, Facebook Graph API'ye karşı test etmek istiyorsanız? developer.facebook.com/docs/graph-api/webhooks#setup
frednikgohar

14

Https://ngrok.com/ için kaydolun . Test etmek için https kullanabilirsiniz. Bu, https'yi hızlı bir şekilde test etmek isteyen kişilere yardımcı olabilir.


6
Hızlı bir test için bu harika bir çözüm. Ve hiçbir şey için kaydolmam gerekmedi, sadece indirip çalıştırın ./ngrok http 8000, 8000 benim localhost portum.
GavKilbride

4

Hata ayıklama amacıyla stunnel seçeneğinin önceden planlanmış bir sürümünü arayanlar için:

stunnel.pem, Evan Grimm'in en çok oylanan cevabında olduğu gibi oluşturulmuş bir sertifikadır.

443 numaralı bağlantı noktasındaki tüm yerel arabirimleri dinleyin ve localhost üzerindeki 80 numaralı bağlantı noktasına iletin

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

sudo yalnızca 1024'ün altındaki gelen bağlantı noktaları (-d [host:] bağlantı noktası) için gereklidir


4
  1. Ngrok'u kurun. indirme bağlantısı: https://ngrok.com/download
  2. Terminalde komut takibi sorunu

    ngrok http 8000

Ngrok oturumunu başlatacak. İki url listeleyecektir. Biri http: // localhost: 8000 ile eşleştirilmiştir . İkincisi, https: // localhost: 8000 ile eşleştirilir . Lütfen aşağıdaki ekran görüntüsünü kontrol edin. Her iki url'yi kullanın. Yerel sunucunuzla eşleşecektir.

örnek ngrok oturumu ekran görüntüsü


Bunu yapmanın en kolay yolu ancak yeni https url'siniallowed_host
Roel

2

Socat ile tek satırda yapılabilir:

socat openssl-listen:8443,fork,reuseaddr,cert=server.pem,verify=0 tcp:localhost:8000

, burada 8443 gelen HTTPS bağlantılarını dinlemek için bir bağlantı noktasıdır, server.pem kendinden imzalı bir sunucu sertifikasıdır ve localhost: 8000 her zamanki gibi başlatılan bir hata ayıklama HTTP sunucusudur.

Daha fazla ayrıntı: http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html


0

SSL / TLS'yi Django yerine Nginx gibi bir proxy ile işleyin. Nginx, 443 numaralı bağlantı noktasını dinleyecek ve ardından istekleri Django dev sunucunuza (tipik olarak http://127.0.0.1:8000) iletecek şekilde ayarlanabilir . Bunun için bir Nginx yapılandırması aşağıdaki gibi görünebilir:

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;
    }
}

Ayrıca harita gerekir django-dev.localhostetmek 127.0.0.1ve eklemek django-dev.localhostiçin ALLOWED_HOSTSde settings.py. Linux'ta, aşağıdaki satırı şuna eklemeniz gerekir /etc/hosts:

127.0.0.1   django-dev.localhost

Daha sonra https://django-dev.localhost, tarayıcınıza giderek geliştirici sitenize erişebileceksiniz (tarayıcınızın güvenlik uyarısını atlamanız gerekecek).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.