如何使用 SSL 将 AWS EC2 Flask 应用程序部署到 HTTPS 端口 443?

How do I deploy an AWS EC2 Flask application to HTTPS port 443 with SSL?

我无法在 https://my.domain/, although it does successfully deploy to the regular http://my.domain/

将我的 Flask 应用程序添加到 运行

我能够成功获取和测试 SSL 证书并验证它们在 https://my.domain:8888/

的 Jupyter Notebook 实例上工作

我能够修改 /etc/httpd/conf/httpd.conf 以访问我的根主目录 https://my.domain/ -> /home/username/code/

我也能够成功地将 http 请求重定向到 https,但登录页面只是一个 linux 浏览器,而不是我的 Flask 应用程序。

也就是说,即使对 httpd.conf、ssl.conf 和 wsgi.conf 进行了大量编辑以在端口 443 上启动 Flask 应用程序,它也不会这样做,而是保留在端口上80.

此外,我注意到每当我通过 AWS CodeStar 部署代码更改时,部署都会覆盖我的 EC2 实例 /etc/httpd/conf.d/wsgi.conf 文件。

Amazon 端是否有我必须配置的设置,以便我的应用程序部署到正确的端口?或者我是否需要在我的 EC2 实例服务器上编辑配置文件?还是有其他问题?

为了让 HTTPS/SSL 为 Flask 工作,以便 Flask 运行s 在 2 个端口上,您首先要遵循此处的提示:

但是,这只会将您的 Flask 代码设置为 运行 使用 SSL。它实际上不会在部署时启动 Flask 进程。为此,您需要编辑 /etc/httpd/conf.d/wsgi.conf 脚本以启动 wsgi 守护进程的第二个实例。

wsgi.conf 的默认脚本应包含端口 80 的部分。您要复制此部分,添加 SSL 参数,然后编辑 wsgi 命令以使用不同的变量名,否则 Apache 将启动时抱怨。我添加了以下内容:

  <VirtualHost *:443>
  ServerName <MY SERVER NAME>
  ServerAlias <MY SERVER NAME>
  SSLEngine on
  SSLCertificateFile    <Server PEM file>
  SSLCertificateKeyFile <Private Key PEM file>
  SSLProtocol all -SSLv2 -SSLv3
  SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
  SSLHonorCipherOrder on
  Alias /static/ /opt/python/current/app/static/
  <Directory /opt/python/current/app/static/>
  Order allow,deny
  Allow from all
  </Directory>
  WSGIScriptAlias / /opt/python/current/app/application.py
  <Directory /opt/python/current/app/>
    Require all granted
  </Directory>
  WSGIDaemonProcess wsgi2 processes=1 threads=15 display-name=%{GROUP} \
    python-path=/opt/python/current/app:/opt/python/run/venv/lib64/python3.4/site-packages:/opt/python/run/venv/lib/python3.4/site-packages user=wsgi group=wsgi \
    home=/opt/python/current/app
  WSGIProcessGroup wsgi2
  </VirtualHost>

请注意,此时您还可以编辑端口 80 部分以删除 wsgi,而是重定向到 443,如下所述: and

通过使用

重置 Apache 服务器来测试此配置
sudo service httpd restart

然后启动您的开发服务器

python application.py

sudo /home/ec2-user/anaconda3/bin/python application.py

然后您应该会在两个端口上看到 Flask 运行ning!

但是,请注意,如果您在 EC2 实例上 运行ning,您的代码可能已经部署并且 运行ning,因此您的端口可能正在使用中,您将看到"OSError: [Errno 98] Address already in use"

但是你还没有完成...哦不,还有一个问题...

我从 https://forums.aws.amazon.com/thread.jspa?threadID=163369 (see also the Whosebug questions what is difference between commands and container commands in elasticbean talk, Configure apache on elastic beanstalk, wsgi user permissions on elastic beanstalk) 中发现了这个事实...

显然,通过 CodeStar 和 Elastic Beanstalk 进行的 EC2 部署确实会覆盖您的 /etc/httpd/conf.d/wsgi.conf 文件。为了 prevent/correct 这个,你需要编辑你的 .ebextensions 配置脚本来使用你自己的 wsgi.conf 文件。请注意,这样做的缺点是无法跟踪亚马逊可能对其默认脚本所做的更新。

首先,我将要保留的 wsgi.conf 文件复制到 .ebextensions 目录。

接下来,我编辑了我的 .ebextensions/sshd.config 文件(该目录中唯一的文件)以添加以下内容:

files:
  "/etc/httpd/conf.d/wsgi.conf" :
    mode: "000777"
    owner: root
    group: root
    content: |
      <IfModule !wsgi_module>
      LoadModule wsgi_module modules/mod_wsgi.so
      </IfModule>
      . . .
      <VirtualHost *:443>
      . . .
      </VirtualHost>
      LogFormat "%h (%{X-Forwarded-For}i) %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

然后,在 "files:" 部分之后,我将以下内容添加到配置的末尾:

container_commands:
  02_update_wsgi:
    command: >
      cp .ebextensions/wsgi.conf ../wsgi.conf

注意上面使用的是CONTAINER_COMMANDS,不是COMMANDS。

这项技术的伟大之处在于 Elastic Beanstalk 会自动 运行s Apache 服务器重启命令,因此在部署后您不需要手动复制任何内容或重新运行 "sudo service httpd restart"

按照上述步骤将使您的 Flask 运行在 HTTPS 上使用 SSL 证书并正确部署。