使用OpenSSL自签证书在Flask中测试HTTPS失败问题排查
Flask测试环境HTTPS访问失败排查
问题回顾
你做了这些操作:
- 用命令生成自签名证书:
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 - 在Flask应用中配置
ssl_context,代码片段如下:from flask import Flask app = Flask(__name__) @app.route('/') def index(): """ Home page of the website """ return render_template('index.html') # ... 其他函数 ... if __name__ == "__main__": app.run(ssl_context=('cert.pem', 'key.pem')) - 启动后发现只有
http://0.0.0.0:5000能正常访问,尝试HTTPS时浏览器报SSL_ERROR_RX_RECORD_TOO_LONG,服务器日志显示Bad HTTP/0.9 request type。
问题原因及解决方法
嘿,这个错误组合我太熟悉了,本质就是服务器在处理HTTP请求,但你把HTTPS请求发到了同一个端口,反过来也会出类似问题。结合你的操作,大概率是下面两个原因之一:
1. 你用flask run启动应用,而非直接运行脚本
很多人容易踩这个坑:当你用flask run命令启动时,脚本里if __name__ == "__main__"代码块根本不会执行!也就是说你写的ssl_context配置完全没生效,服务器还是默认的HTTP模式。这时候你用https://0.0.0.0:5000访问,相当于把HTTPS握手请求塞给了HTTP服务器,它根本看不懂,就会抛出Bad HTTP/0.9 request type,浏览器则返回SSL相关错误。
解决办法:
- 直接运行你的脚本:比如执行
python app.py,确保app.run(ssl_context=...)被执行; - 如果习惯用
flask run,就加上SSL参数启动:flask run --ssl-cert=cert.pem --ssl-key=key.pem
2. 证书/密钥文件路径不对
如果你的cert.pem和key.pem不在脚本的当前工作目录下,Flask找不到它们时不会报错,而是默默回退到HTTP模式。这时候同样会出现上述错误。
解决办法:
- 把证书文件移到脚本的同一目录下;
- 或者在
ssl_context里使用绝对路径,比如:app.run(ssl_context=('/home/yourusername/certs/cert.pem', '/home/yourusername/certs/key.pem'))
验证正确配置的方法
当你正确启用HTTPS后:
- 访问
https://0.0.0.0:5000时,浏览器会提示“证书不安全”(自签名证书的正常现象),选择继续访问就能看到内容; - 此时再访问
http://0.0.0.0:5000会失败,因为服务器已经切换到HTTPS模式,不再处理HTTP请求。
内容的提问来源于stack exchange,提问作者peachykeen




