[英]Websocket + SSL on AWS Application Load Balancer
我在ElastickBeanstalk上部署了一個Django應用程序。 我最近從Classic - > Application遷移了負載均衡器,以支持Websocket(由以下部分組成的層:Django-channels(〜= 1.1.8,channels-api == 0.4.0),Redis Elasticache AWS和Daphne(〜= 1.4))。 HTTP,HTTPS和Web Socket協議工作正常。
但我找不到通過安全SSL部署Websocket的方法。 它正在扼殺我,並且它正在阻止,因為來自瀏覽器的HTTPS連接將切斷非安全的ws://對等請求。
這是我的ALB配置有人作為解決方案嗎?
經過2天的調查,我終於破解了這個配置!
這是答案:
右邊和MINIMUM,aws - ALB配置: 的確,我們需要
轉發所有到Daphne的交通。 之所以我沒有在網絡中傳播:“/ ws / *”路由到Daphne,是因為它確實為我提供了HandShake OK,但之后,沒有什么,nada,websocket無法推回到訂戶。 我相信,原因是Daphne的推回不尊重您在conf中自定義的自定義基本跟蹤URL。 另外,我無法確定這種解釋。 但我確定的是,如果我不將所有流量轉發給達芙妮,那么握手后它就無法工作。
.ebextensions / 05_channels.config
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/start_supervisor.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
sudo virtualenv -p /usr/bin/python2.7 /tmp/senv
source /tmp/senv/bin/activate && source /opt/python/current/env
sudo python --version > /tmp/version_check.txt
sudo pip install supervisor
sudo /usr/local/bin/supervisord -c /opt/python/current/app/fxf/custom_eb_deployment/supervisord.conf
sudo /usr/local/bin/supervisorctl -c /opt/python/current/app/fxf/custom_eb_deployment/supervisord.conf reread
sudo /usr/local/bin/supervisorctl -c /opt/python/current/app/fxf/custom_eb_deployment/supervisord.conf update
sudo /usr/local/bin/supervisorctl -c /opt/python/current/app/fxf/custom_eb_deployment/supervisord.conf restart all
sudo /usr/local/bin/supervisorctl -c /opt/python/current/app/fxf/custom_eb_deployment/supervisord.conf status
start_daphne.sh(備注我根據我的ALB conf選擇8001端口)
#!/usr/bin/env bash source /opt/python/run/venv/bin/activate && source /opt/python/current/env /opt/python/run/venv/bin/daphne -b 0.0.0.0 -p 8001 fxf.asgi:channel_layer
start_worker.sh
#!/usr/bin/env bash source /opt/python/run/venv/bin/activate && source /opt/python/current/env python /opt/python/current/app/fxf/manage.py runworker
`
[unix_http_server]
file=/tmp/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/tmp/supervisord.log ; supervisord log file
loglevel=error ; info, debug, warn, trace
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:Daphne]
environment=PATH="/opt/python/run/venv/bin"
command=sh /opt/python/current/app/fxf/custom_eb_deployment/start_daphne.sh --log-file /tmp/start_daphne.log
directory=/opt/python/current/app
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/tmp/daphne.out.log
stderr_logfile=/tmp/daphne.err.log
[program:Worker]
environment=PATH="/opt/python/run/venv/bin"
command=sh /opt/python/current/app/fxf/custom_eb_deployment/start_worker.sh --log-file /tmp/start_worker.log
directory=/opt/python/current/app
process_name=%(program_name)s_%(process_num)02d
numprocs=2
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/tmp/workers.out.log
stderr_logfile=/tmp/workers.err.log
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
`
如果有些人仍在努力解決這個問題,我可能會在中等或某事上發布tuto。 不要猶豫,把它推給我答案;)
我也一直在使用SSL,EBS和Channels 1.x苦苦掙扎,與你描述的場景完全相同,但最后我可以部署我的應用程序。 SSL總是存在問題,因為Django在routing.py
文件中忽略了我在所有SSL請求中的routing.py
,並且在此之前一切正常。
我決定將所有websockets請求發送到服務器中的唯一根路徑,例如/ws/*
。 然后向負載均衡器添加一個特定規則,該負載均衡器通過端口443接收所有這些請求,並將它們重定向到端口5000(Daphne工作者正在偵聽)作為HTTP請求(而不是HTTPS!)。 在負載均衡器背后的假設下,VPC足夠安全。 請注意,此配置可能涉及其他項目的安全問題。
...因為來自瀏覽器的HTTPS連接將切斷非安全的ws://對等請求。
還有一件事。 您應該使用wss://
通過HTTPS啟動websocket連接。 你可以在你的.js
文件中寫這樣的東西。
var wsScheme = window.location.protocol.includes('https') ? 'wss' : 'ws';
var wsPath = wsScheme + '://' + window.location.host + '/your/ws/path';
var ws = new ReconnectingWebSocket(wsPath);
祝好運!
你應該使用wss://而不是ws://。 並更改有關代理的設置。 我剛剛添加了我的wsgi.conf。
<VirtualHost *:80>
WSGIPassAuthorization On
WSGIScriptAlias / /opt/python/current/app/config/wsgi.py
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
LoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so
ProxyPreserveHost On
ProxyRequests Off
ProxyPass "/ws/chat" "ws://**your site**/ws/chat" Keepalive=On
ProxyPassReverse "/ws/chat" "ws://**your site**/ws/chat" Keepalive=On
<Directory /opt/python/current/app/>
Require all granted
</Directory>
</VirtualHost>
然后它將給你200狀態連接。 “/ ws / chat /”應該用你的websocket網址替換。
在制作此文件之前,您應該檢查您的daphne服務器是否已打開。 問題我所經歷的是djangoenv和daemon.config的worker。
首先,djangoenv應該在一條線上。 這意味着沒有換行。 第二,如果你使用django channel v2,那么它不需要worker。 所以擦掉它。
這是我的daemon.config(我使用8001端口。):
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_daemon.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
# Get django environment variables
djangoenv=`cat /opt/python/current/env | tr '\n' ',' | sed 's/%/%%/g' | sed 's/export //g' | sed 's/$PATH/%(ENV_PATH)s/g' | sed 's/$PYTHONPATH//g' | sed 's/$LD_LIBRARY_PATH//g'`
djangoenv=${djangoenv%?}
# Create daemon configuraiton script
daemonconf="[program:daphne]
; Set full path to channels program if using virtualenv
command=/opt/python/run/venv/bin/daphne -b 0.0.0.0 -p 8001 config.asgi:application
directory=/opt/python/current/app
user=ec2-user
numprocs=1
stdout_logfile=/var/log/stdout_daphne.log
stderr_logfile=/var/log/stderr_daphne.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
; if rabbitmq is supervised, set its priority higher
; so it starts first
priority=998
environment=$djangoenv"
# Create the supervisord conf script
echo "$daemonconf" | sudo tee /opt/python/etc/daemon.conf
# Add configuration script to supervisord conf (if not there already)
if ! grep -Fxq "[include]" /opt/python/etc/supervisord.conf
then
echo "[include]" | sudo tee -a /opt/python/etc/supervisord.conf
echo "files: daemon.conf" | sudo tee -a /opt/python/etc/supervisord.conf
fi
# Reread the supervisord config
sudo /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf reread
# Update supervisord in cache without restarting all services
sudo /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf update
# Start/Restart processes through supervisord
sudo /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf restart daphne
並仔細檢查您的安全組alb到ec2。 祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.