底部的更新,我解決了它,但不確定解決方案是否正確。
我在 CentOS 上運行了 Apache,并在其中使用 Gunicorn 運行 Flask 應用程式的本地主機埠 8080 的代理。此設定適用于 Apache 埠 80 (HTTP),我可以使用我的域http://example.com和瀏覽器連接到它,但現在我嘗試設定 SSL/HTTPS,但它不起作用。
導航到https://example.com嘗試加載頁面一段時間(如 30ish 秒),然后顯示 502 錯誤頁面:
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /.
Reason: Error reading from remote server
阿帕奇錯誤日志:
[proxy_http:error] [pid 30209] (103)Software caused connection abort: [client xx.xxx.xxx.xxx:60556] AH01102: error reading status line from remote server localhost:8080
[proxy:error] [pid 30209] [client xx.xxx.xxx.xxx:60556] AH00898: Error reading from remote server returned by /
Gunicorn 錯誤日志(前 7 行來自 Gunicorn 啟動,不知道為什么這個資訊在錯誤日志中,最后 3 行是 HTTPS 請求回傳 502 錯誤時):
[29478] [INFO] Listening at: http://127.0.0.1:8080 (29478)
[29478] [INFO] Using worker: sync
[29480] [INFO] Booting worker with pid: 29480
[29481] [INFO] Booting worker with pid: 29481
[29482] [INFO] Booting worker with pid: 29482
[29483] [INFO] Booting worker with pid: 29483
[29484] [INFO] Booting worker with pid: 29484
[29478] [CRITICAL] WORKER TIMEOUT (pid:29480)
[29480] [INFO] Worker exiting (pid: 29480)
[29554] [INFO] Booting worker with pid: 29554
適用于 HTTP ( /etc/httpd/conf/httpd.conf) 的Apache 配置:
Listen 80
#other default config values here
<VirtualHost *:80>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
IncludeOptional conf.d/*.conf
Apache config which is not working for HTTPS (/etc/httpd/conf.d/ssl.conf):
Listen 443 https
#other default config values here
<VirtualHost *:443>
#other default config values here too
SSLCertificateFile /etc/pki/tls/certs/cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/cert.key
SSLProxyEngine on
ProxyPass / https://localhost:8080/
ProxyPassReverse / https://localhost:8080/
</VirtualHost>
If I remove/comment the SSLProxyEngine, ProxyPass amd ProxyPassReverse lines and restart Apache I get the default Apache welcome page and HTTPS works just fine so clearly the problem is in the Proxy somehow?
The flask app is started with Gunicorn by:
gunicorn --config gunicorn_config.py app:app
gunicorn_config.py:
workers = 5
bind = '127.0.0.1:8080'
umask = 0o007
reload = True
accesslog = 'log_gunicorn_access.txt'
errorlog = 'log_gunicorn_error.txt'
app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080)
And once again, this works when navigating to my domain using HTTP but doesn't work when using HTTPS.
Any help?
UPDATE:
I managed to get another error. Now navigating to https://example.com loads instantly and shows 500 error page:
Proxy Error
The proxy server could not handle the request GET /.
Reason: Error during SSL Handshake with remote server
Apache error log:
[proxy:error] [pid 32385] (502)Unknown error 502: [client xx.xxx.xxx.xxx:50932] AH01084: pass request body failed to [::1]:8080 (localhost)
[proxy:error] [pid 32385] [client xx.xxx.xxx.xxx:50932] AH00898: Error during SSL Handshake with remote server returned by /
[proxy_http:error] [pid 32385] [client xx.xxx.xxx.xxx:50932] AH01097: pass request body failed to [::1]:8080 (localhost) from xx.xxx.xxx.xxx ()
No more any errors in Gunicorn error log.
I added these two lines to gunicorn_config.py:
keyfile = '/etc/pki/tls/private/cert.key'
certfile = '/etc/pki/tls/certs/cert.pem'
and made sure both files are accessible by the user running Gunicorn (chmod o r cert.key/pem).
No idea if I was supposed to change it like this as I thought the traffic should go like: client --https--> Apache and then Apache --http--> Gunicorn.
Also HTTP (http://example.com) no longer works and gives the previous 502 error page but I guess running Gunicorn with the cert configs doesn't allow HTTP anymore and would need to run the app twice with different configs).
UPDATE 2:
I added more Apache logging by adding this line to /etc/httpd/conf.d/ssl.conf inside virtual host:
LogLevel info
And now I got additional info in Apache error log:
[ssl:info] [pid 3808] [remote 127.0.0.1:8080] AH02411: SSL Proxy: Peer certificate does not match for hostname localhost
Then I added new line to /etc/httpd/conf.d/ssl.conf inside virtual host:
SSLProxyCheckPeerName off
And now I got another Apache error:
[ssl:info] [pid 3999] [remote 127.0.0.1:8080] AH02005: SSL Proxy: Peer certificate CN mismatch: Certificate CN: example.com Requested hostname: localhost
Added new line to /etc/httpd/conf.d/ssl.conf inside virtual host:
SSLProxyCheckPeerCN off
Aaaand 現在導航到https://example.com正常作業,我從應用程式回傳“Hello world”!
現在,我想我的問題,需要更新,以及:它是不好的做法,錯誤的或不安全的在使用SSLProxyCheckPeerName off,并SSLProxyCheckPeerCN off在這方面?或者有沒有更好的方法,因為我認為沒有辦法在本地主機上訂購官方 SSL 證書?
uj5u.com熱心網友回復:
你正在使用
ProxyPass / http://localhost:8080/
和
ProxyPass / https://localhost:8080/
(注意 1 個字母的差異)。
你localhost:8080將成為無論是HTTP或HTTPS。根據您的描述(和普遍期望),它正在為 http 提供服務。如果您甚至將您的 :443 虛擬主機代理到 http,它會作業得更好。
您可能會遇到更多問題,因為代理應用程式并不真正知道它實際上是通過 https 提供的,但這與這個問題不同。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/357883.html
