Làm cách nào để kiểm tra các kết nối https với Django dễ dàng như các kết nối không phải https sử dụng 'runningerver'?


109

Tôi có một ứng dụng sử dụng cookie "an toàn" và muốn kiểm tra chức năng của nó mà không cần thiết lập một máy chủ phát triển hỗ trợ SSL phức tạp. Có cách nào để thực hiện việc này đơn giản như tôi có thể kiểm tra các yêu cầu không được mã hóa bằng cách sử dụng ./manage.py runserverkhông?


Bạn không thể chỉ định runningerver 443 để làm cho máy chủ chạy trên cổng 443?
Furbeenator

@Furbeenator: Rất tiếc là không - điều này sẽ chỉ làm cho máy chủ HTTP trên 443, những gì tôi cần là một máy chủ SSL thực sự đang chạy.
Evan Grim

Câu trả lời:


109

Nó không phải đơn giản như việc xây dựng trong máy chủ phát triển, nhưng nó không phải là quá khó khăn để có được một cái gì đó gần bằng stunnel như một trung gian giữa SSLifying trình duyệt của bạn và máy chủ phát triển. Stunnel cho phép bạn thiết lập một máy chủ nhẹ trên máy của mình, chấp nhận các kết nối trên một cổng đã định cấu hình, bao bọc chúng bằng SSL và chuyển chúng đến một số máy chủ khác. Chúng tôi sẽ sử dụng điều này để mở một cổng đường hầm (8443) và chuyển bất kỳ lưu lượng nào mà nó nhận được đến một phiên bản máy chủ chạy Django.

Trước tiên, bạn sẽ cần đường hầm có thể được tải xuống tại đây hoặc có thể được cung cấp bởi hệ thống gói của nền tảng của bạn (ví dụ apt-get install stunnel:). Tôi sẽ sử dụng phiên bản 4 của stunnel (ví dụ: /usr/bin/stunnel4trên Ubuntu), phiên bản 3 cũng sẽ hoạt động, nhưng có các tùy chọn cấu hình khác nhau.

Trước tiên, hãy tạo một thư mục trong dự án Django của bạn để chứa các tệp cấu hình cần thiết và những thứ SSLish.

mkdir stunnel
cd stunnel

Tiếp theo, chúng ta sẽ cần tạo một chứng chỉ cục bộ và khóa để sử dụng cho giao tiếp SSL. Đối với điều này, chúng tôi chuyển sang openssl.

Tạo khóa:

openssl genrsa 1024 > stunnel.key

Tạo chứng chỉ sử dụng khóa này (điều này sẽ hỏi bạn một loạt thông tin sẽ được bao gồm trong chứng chỉ - chỉ cần trả lời với bất kỳ điều gì bạn cảm thấy tốt):

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

Bây giờ kết hợp chúng thành một tệp duy nhất mà stunnel sẽ sử dụng cho giao tiếp SSL của nó:

cat stunnel.key stunnel.cert > stunnel.pem

Tạo một tệp cấu hình cho stunnel có tên dev_https với các nội dung sau:

pid=

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

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

Tệp này cho stunnel biết những gì nó cần biết. Cụ thể, bạn đang yêu cầu nó không sử dụng tệp pid, tệp chứng chỉ ở đâu, sử dụng phiên bản SSL nào, nó sẽ chạy ở nền trước, nơi nó sẽ ghi đầu ra và chấp nhận kết nối trên cổng. 8443 và đưa chúng đến cổng 8001. Tham số cuối cùng (TIMEOUTclose) cho biết nó sẽ tự động đóng kết nối sau 1 giây trôi qua mà không có hoạt động nào.

Bây giờ, hãy bật lại vào thư mục dự án Django của bạn (thư mục có management.py trong đó):

cd ..

Ở đây chúng tôi sẽ tạo một tập lệnh có tên là runningerver sẽ chạy stunnel và hai máy chủ phát triển django (một cho các kết nối thông thường và một cho các kết nối SSL):

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

Hãy chia nhỏ điều này từng dòng một:

  • Dòng 1: Bắt đầu stunnel và trỏ nó đến tệp cấu hình mà chúng tôi vừa tạo. Điều này có chức năng lắng nghe đường hầm trên cổng 8443, quấn bất kỳ kết nối nào mà nó nhận được trong SSL và chuyển chúng đến cổng 8001
  • Dòng 2: Bắt đầu phiên bản máy chủ chạy Django bình thường (trên cổng 8000)
  • Dòng 3: Khởi động một phiên bản máy chủ chạy Django khác (trên cổng 8001) và định cấu hình nó để xử lý tất cả các kết nối đến như thể chúng đang được thực hiện bằng HTTPS.

Làm cho tệp runningcript chúng ta vừa tạo có thể thực thi được với:

chmod a+x runserver

Bây giờ khi bạn muốn chạy máy chủ phát triển của mình, chỉ cần thực thi ./runservertừ thư mục dự án của bạn. Để dùng thử, chỉ cần trỏ trình duyệt của bạn đến http: // localhost: 8000 cho lưu lượng HTTP thông thường và https: // localhost: 8443 cho lưu lượng HTTPS. Lưu ý rằng trình duyệt của bạn gần như chắc chắn sẽ phàn nàn về chứng chỉ được sử dụng và yêu cầu bạn thêm một ngoại lệ hoặc hướng dẫn rõ ràng để trình duyệt tiếp tục duyệt. Điều này là do bạn đã tạo chứng chỉ của riêng mình và nó không được trình duyệt tin cậy để nói sự thật về chứng chỉ đó là ai. Điều này là tốt cho sự phát triển, nhưng rõ ràng sẽ không cắt giảm nó để sản xuất.

Thật không may, trên máy của tôi, tập lệnh trình chạy này không thoát ra một cách dễ dàng khi tôi nhấn Ctrl-C. Tôi phải giết các quy trình theo cách thủ công - bất cứ ai có đề xuất để khắc phục điều đó?

Cảm ơn bài đăng của Michael Gile và mục nhập wiki của django-wear để làm tư liệu tham khảo.


3
Tôi vừa vấp phải câu trả lời này. Một số lưu ý: bạn không nhất thiết phải chạy một phiên bản phát triển riêng biệt trên 8001, bạn cũng có thể để nó kết nối với cổng 8000. Nếu bạn muốn stunnel tự động bị hủy, hãy thêm một hàm và một exit trap: kill_stunnel () { kill $ stunnel_pid} bẫy kill_stunnel thoát stunnel4 stunnel / dev https & stunnel_pid = $ 1
Friek

2
Phiên bản thứ hai được gọi với HTTPS = 1 có nghĩa là request.is_secure()sẽ báo cáo True. Nếu bạn không cần điều đó thì bạn đã đúng - bạn có thể chỉ đường hầm vào một trường hợp duy nhất.
Evan Grim

Nếu bạn chạy vào stunnel Chế Độ FIPS không được hỗ trợ .... thêm FIPS = không đến tập tin dev_https để tắt nó đi
yeahdixon

2
Tôi vừa thử điều này khi tôi đang cố gắng thiết lập một bản sao phát triển của công việc trang web trên một dự án do người khác phát triển nhưng tôi nhận được "sslVersion = SSLv3": SSLv3 not supported.
HenryM

@Friek stunnel_pid=$1không làm việc cho tôi nhưng stunnel_pid=$!đã làm. Làm thế nào đã stunnel_pid=$1làm việc cho bạn?
Utku

86

Tôi khuyên bạn nên sử dụng gói django-sslserver .

Gói hiện tại trên PyPI chỉ hỗ trợ tối đa Django phiên bản 1.5.5 nhưng một bản vá đã được cam kết thông qua 5d4664c . Với bản sửa lỗi này, hệ thống chạy tốt và là một giải pháp khá đơn giản và dễ hiểu để kiểm tra các kết nối https.

CẬP NHẬT: Kể từ khi tôi đăng câu trả lời của mình, cam kết ở trên đã được hợp nhất vào nhánh chính và một bản phát hành mới đã được đẩy lên PyPI. Vì vậy, không cần phải chỉ định cam kết 5d4664c cho bản sửa lỗi cụ thể đó.


5
Điều này có vẻ đầy hứa hẹn - tôi có thể phải cập nhật câu trả lời được chấp nhận trên câu trả lời này. Còn ai muốn cân không?
Evan Grim

3
điều này sẽ trở thành câu trả lời được chấp nhận, được sử dụng một thời gian trong một dự án khá phức tạp mà chỉ đơn giản là không thể hoạt động nếu không chạy trên https và không bao giờ gặp sự cố.
simone cittadini

2
Hoạt động tốt ... Cảm ơn! :)
nidHi 12/12/16

5
Hoạt động như Python 3.6.2 và Django 1.11.3.
Phoenix

2
Hoạt động như Python 3.5 và Django 1.11
Hansel

64

Tương tự như django-sslserver, bạn có thể sử dụng RunServerPlus từ django-extensions

Nó có các phụ thuộc vào Werkzeug (vì vậy bạn có quyền truy cập vào trình gỡ lỗi Werkzeug tuyệt vời) và pyOpenSSL (chỉ cần thiết cho chế độ ssl), do đó, để cài đặt, hãy chạy:

pip install django-extensions Werkzeug pyOpenSSL

Thêm nó vào INSTALLED_APPS trong tệp settings.py dự án của bạn:

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

Sau đó, bạn có thể chạy máy chủ ở chế độ ssl với:

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

Thao tác này sẽ tạo tệp chứng chỉ tại /tmp/cert.crtvà tệp khóa tại /tmp/cert.keyđó có thể được sử dụng lại cho các phiên trong tương lai.

Có rất nhiều thứ bổ sung được bao gồm trong các phần mở rộng django mà bạn có thể thấy sử dụng, vì vậy bạn nên lướt nhanh qua các tài liệu.


2
Thực ra câu trả lời tốt nhất cho Django 1.6 + kể từ django-sslserver không hỗ trợ tính năng tự động tải lại cho phiên bản mới
Zat42

Câu trả lời tốt nhất cho việc gỡ lỗi + kích hoạt SSL.
Yuda Prawira

Tôi tự hỏi tại sao nó không hoạt động trong ứng dụng chứa docker
Roel

@Roel đã dùng thử nhanh và có vẻ như nó hoạt động cho một ứng dụng hello world. có thể là hình ảnh cơ sở của bạn không có các phụ thuộc bắt buộc (ví dụ: nếu bạn sử dụng -alpine) hoặc bạn có thể cần mở phạm vi IP của mình, ví dụ./manage.py runserver_plus --cert /tmp/cert 0.0.0.0:8000
djsutho

FileNotFoundError: [Errno 2] Không có tệp hoặc thư mục nào như vậy: '/tmp\\cert.crt'
Mark Anthony Libres

38

chỉ cần cài đặt

sudo pip install django-sslserver

bao gồm sslserver trong aps đã cài đặt

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

bây giờ bạn có thể chạy

 python manage.py runsslserver 0.0.0.0:8888

2
Giải pháp sạch nhất!
SexyBeast

thực sự là một giải pháp làm sạch, nhưng đối với một số lý do, nó là rất chậm
Bhanu Tez

Rất tiếc, Chrome đang đưa ra cảnh báo rằng chứng chỉ không hợp lệ.
zerohedge

@zerohedge của nó chỉ để phát triển, vì vậy nó không quan trọng.
Sharpless512

điều này rất thanh lịch - nhưng có giải pháp nào để sử dụng điều này để kiểm tra các kết nối an toàn không? ví dụ, nếu bạn muốn kiểm tra dựa trên API Đồ thị của Facebook? developers.facebook.com/docs/graph-api/webhooks#setup
frednikgohar

14

Đăng ký https://ngrok.com/ . Bạn có thể sử dụng https để kiểm tra. Điều này có thể giúp những người chỉ muốn kiểm tra nhanh https.


6
Để kiểm tra nhanh, đây là một giải pháp tuyệt vời. Và tôi không phải đăng ký bất cứ thứ gì, chỉ cần tải xuống và chạy ./ngrok http 8000, 8000 là cổng localhost của tôi.
GavKilbride

4

Đối với những người đang tìm kiếm phiên bản nền trước của tùy chọn stunnel cho mục đích gỡ lỗi:

stunnel.pem là một chứng chỉ được tạo như trong câu trả lời được bình chọn nhiều nhất của Evan Grimm.

Nghe trên tất cả các giao diện cục bộ trên cổng 443 và chuyển tiếp đến cổng 80 trên máy chủ cục bộ

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

sudo chỉ cần thiết cho các cổng đến (-d [host:] port) dưới 1024


4
  1. Cài đặt ngrok. liên kết tải xuống: https://ngrok.com/download
  2. Phát hành lệnh sau trên thiết bị đầu cuối

    ngrok http 8000

Nó sẽ bắt đầu phiên ngrok. Nó sẽ liệt kê hai url. Một được ánh xạ tới http: // localhost: 8000 . Thứ hai được ánh xạ tới https: // localhost: 8000 . Vui lòng kiểm tra ảnh chụp màn hình bên dưới. Sử dụng một trong hai url. Nó sẽ ánh xạ đến máy chủ cục bộ của bạn.

ảnh chụp màn hình phiên ngrok mẫu


Cách dễ nhất để làm điều đó nhưng hãy nhớ đặt url https mới choallowed_host
Roel,

2

Nó có thể được thực hiện trong một dòng với socat:

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

, trong đó 8443 là một cổng để lắng nghe các kết nối HTTPS đến, server.pem là chứng chỉ máy chủ tự ký và localhost: 8000 là một máy chủ HTTP gỡ lỗi được khởi chạy như thường lệ.

Thêm chi tiết: http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html


0

Xử lý SSL / TLS bằng proxy như Nginx thay vì Django. Nginx có thể được thiết lập để lắng nghe trên cổng 443 và sau đó chuyển tiếp các yêu cầu đến máy chủ nhà phát triển Django của bạn (thường là http://127.0.0.1:8000). Cấu hình Nginx cho điều này có thể giống như sau:

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

Bạn cũng sẽ cần để ánh xạ django-dev.localhosttới 127.0.0.1và thêm django-dev.localhostvào ALLOWED_HOSTStrong settings.py. Trên Linux, bạn sẽ cần thêm dòng sau vào /etc/hosts:

127.0.0.1   django-dev.localhost

Sau đó, bạn sẽ có thể truy cập trang web nhà phát triển của mình bằng cách truy cập https://django-dev.localhosttrong trình duyệt của bạn (bạn sẽ cần phải bỏ qua cảnh báo bảo mật của trình duyệt).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.