您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?
Posted
技术标签:
【中文标题】您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?【英文标题】:can you add HTTPS functionality to a python flask web server? 【发布时间】:2015-06-10 02:23:23 【问题描述】:我正在尝试构建一个 Web 界面来在网络设备上模拟一个安静的界面,这个网络设备使用摘要式身份验证和 HTTPS。 我想出了如何将 Digest Authentication 集成到 Web 服务器中,但我似乎无法找到如何使用 FLASK 获取 https,如果你能告诉我如何请评论我需要用下面的代码做什么来实现它。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
return 'Flask is running!'
@app.route('/data')
def names():
data = "names": ["John", "Jacob", "Julie", "Jennifer"]
return jsonify(data)
if __name__ == '__main__':
app.run()
【问题讨论】:
【参考方案1】:在真正的 Web 服务器上部署 Flask,而不是使用内置(开发)服务器。
请参阅 Flask 文档的Deployment Options chapter。 nginx 和 Apache 等服务器都可以为您的站点设置 HTTPS 服务器而不是 HTTP 服务器。
列出的独立 WSGI 服务器通常部署在 Nginx 和 Apache 后面的代理转发配置中,前端服务器仍然为您处理 SSL 加密。
【讨论】:
如果您使用 mod_wsgi-express (pypi.python.org/pypi/mod_wsgi),它提供了一种使用 HTTPS 运行站点的简单方法,并且还具有在 Web 服务器级别处理 Digest 身份验证协议的内置功能。建议你在 mod_wsgi 邮件列表中询问它,因为 *** 不是一个讨论论坛,所以在这里不容易解释。 @Martijn Pieters,您能否解释一下为什么我们应该“在真正的 Web 服务器上部署 Flask,而不是使用内置(开发)服务器。”?谢谢 @Alexis.Rolland:内置服务器无法处理互联网的“真实世界”,它没有经过安全 POV 的强化,也没有针对性能进行调整。它的主要目的是在本地机器上引导开发,仅此而已。在生产环境中使用它需要您自担风险,在我看来这是一个相当大的风险。 使用真正的网络服务器并不总是一种选择,我只想用 Flask 和 https 提供一些文件 @mazs:那么您将承担安全风险。安装 gunicorn 并使用它来为您的 Flask 服务是微不足道的,至少该服务器更加坚固。【参考方案2】:这在紧要关头也有效
from flask import Flask, jsonify
from OpenSSL import SSL
context = SSL.Context(SSL.PROTOCOL_TLSv1_2)
context.use_privatekey_file('server.key')
context.use_certificate_file('server.crt')
app = Flask(__name__)
@app.route('/')
def index():
return 'Flask is running!'
@app.route('/data')
def names():
data = "names": ["John", "Jacob", "Julie", "Jennifer"]
return jsonify(data)
#if __name__ == '__main__':
# app.run()
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True, ssl_context=context)
【讨论】:
SSLv3 存在 POODLE 漏洞。将其更改为 TSL 点击此链接:flask.pocoo.org/snippets/111 在页面末尾的注释说明了如何更改为 TSL。 你的意思是 TLS 不是 TSL? 此用于创建context
的代码已被较新的 python 弃用。试试这个:import ssl context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain('certificate.crt', 'private.key')
我认为这里的 API 已经过时了。 My answer below 提供了一个适用于 Python 3.7.5 的版本。【参考方案3】:
不要使用 openssl 或 pyopenssl 它现在在 python 中已经过时了
参考下面的代码
from flask import Flask, jsonify
import os
ASSETS_DIR = os.path.dirname(os.path.abspath(__file__))
app = Flask(__name__)
@app.route('/')
def index():
return 'Flask is running!'
@app.route('/data')
def names():
data = "names": ["John", "Jacob", "Julie", "Jennifer"]
return jsonify(data)
if __name__ == '__main__':
context = ('local.crt', 'local.key')#certificate and key files
app.run(debug=True, ssl_context=context)
【讨论】:
生成local.crt
和local.key
见方法二:kracekumar.com/post/54437887454/ssl-for-flask-local-development
很奇怪,它运行在http://127.0.0.1:5000/
。这不应该在安全的http上运行吗?我仍然可以通过http://127.0.0.1:5000/
获取
我正在研究如何在 Dash 应用程序上实现 SSL,这个答案成功了,代码如下:context = ('local.crt','local.key') if __name__ == "__main__": app.run_server(host="192.168.200.100", port="8082", debug=True, ssl_context=context)
我正在使用谷歌云运行。在这种情况下,对于生产,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中?
这对我来说运行良好,但是当我使用 ssl_context=context 我的 index.html 不再加载链接的 .css 和 .js 本地文件。当我使用 ssl_context=None 运行应用程序时,html 会毫无问题地加载它们。这里有什么帮助吗?【参考方案4】:
如果此网络服务器仅用于测试和演示目的。您可以使用 ngrok,它也是一个开源的,可以为您的 http 流量提供隧道。
基本上,ngrok 创建一个公共 URL(http 和 https),然后将流量通过隧道传输到 Flask 进程正在运行的任何端口。
https://ngrok.com/product
设置只需几分钟。您首先必须下载该软件。然后运行命令 ./ngrok http [你的python进程运行的端口号]
然后它将在终端中打开一个窗口,为您提供 http 和 https 网址来访问您的网络应用程序。
【讨论】:
这真的很有效,没有太多安装/配置的麻烦。【参考方案5】: 要在您的烧瓶应用程序中运行 HTTPS 功能或 SSL 身份验证,首先安装“pyOpenSSL”python 包pip install pyopenssl
下一步是创建cert.pem
和key.pem
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
在您的烧瓶应用项目中复制生成的cert.pem
和key.pem
在app.run()
中添加ssl_context=('cert.pem', 'key.pem')
,如下例所示。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return "Flask is running!"
@app.route("/data")
def names():
data = "names": ["John", "Jacob", "Julie", "Jennifer"]
return jsonify(data)
if __name__ == "__main__":
app.run(ssl_context=("cert.pem", "key.pem"))
【讨论】:
我在第一步后遇到错误openssl' is not recognized as an internal or external command
你安装了pyopenssl吗?
是的,我已经安装了....稍后当我尝试第 2 步时 to create 'cert.pem' and 'key.pem'
它向我显示了错误
如果你在windows中,你必须将它添加到路径中。
您也必须下载它。来自网站,而不是来自 pip。【参考方案6】:
对于快速的 n' 脏自签名证书,您还可以使用 flask run --cert adhoc
或设置 FLASK_RUN_CERT
环境变量。
$ export FLASK_APP="app.py"
$ export FLASK_ENV=development
$ export FLASK_RUN_CERT=adhoc
$ flask run
* Serving Flask app "app.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 329-665-000
adhoc
选项没有很好的文档记录(有充分的理由,永远不要在生产中这样做),但在 cli.py source code 中提到了它。
Miguel GrinbergRunning Your Flask Application Over HTTPS 对此进行了详尽的解释。
【讨论】:
我正在使用谷歌云运行。在这种情况下,对于生产,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中?【参考方案7】:The top-scoring answer 的想法是正确的,但 API 似乎已经发展,以至于它不再像 2015 年首次编写时那样工作。
代替这个:
from OpenSSL import SSL
context = SSL.Context(SSL.PROTOCOL_TLSv1_2)
context.use_privatekey_file('server.key')
context.use_certificate_file('server.crt')
我在 Python 3.7.5 中使用过这个:
import ssl
context = ssl.SSLContext()
context.load_cert_chain('fullchain.pem', 'privkey.pem')
然后在 Flask.run
调用中提供 SSL 上下文,正如它所说:
app.run(…, ssl_context=context)
(我的server.crt
文件称为fullchain.pem
,我的server.key
称为privkey.pem
。这些文件是由我的 LetsEncrypt Certbot 提供给我的。)
【讨论】:
SSL POODLE 漏洞怎么样? 我正在使用谷歌云运行。在这种情况下,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中? 嘿,马克,您究竟是如何生成这些 crt pem 和密钥的? 呸忘了我看到了我们刚刚重命名的 server.crt 和密钥我在 wsl 上使用了 openssl 来生成它们【参考方案8】:超级简单:
app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
运行:
$ openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
$ flask run --cert=cert.pem --key=key.pem
【讨论】:
以上是关于您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?的主要内容,如果未能解决你的问题,请参考以下文章