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

Posted

技术标签:

【中文标题】如何使用 SSL 将 AWS EC2 Flask 应用程序部署到 HTTPS 端口 443?【英文标题】:How do I deploy an AWS EC2 Flask application to HTTPS port 443 with SSL? 【发布时间】:2018-01-02 10:32:06 【问题描述】:

我无法让我的 Flask 应用程序在 https://my.domain/ 上运行,尽管它确实成功部署到常规 http://my.domain/

我能够成功获取和测试 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 实例服务器上编辑配置文件?还是有其他问题?

【问题讨论】:

【参考方案1】:

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

但是,这只会将您的 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,如下所述: Redirect to Https using Elastic Beanstalk ELB 和 Redirect HTTP to HTTPS Apache2

通过使用重置 Apache 服务器来测试此配置

sudo service httpd restart

然后启动你的开发服务器

python application.py

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

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

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

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

我从https://forums.aws.amazon.com/thread.jspa?threadID=163369 发现了以下事实(另请参阅 *** 问题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 文件。为了防止/纠正这种情况,您需要编辑 .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-Fori) %l %u %t \"%r\" %>s %b \"%Refereri\" \"%User-Agenti\"" combined

然后,在“文件:”部分之后,我将以下内容添加到配置的末尾:

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

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

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

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

【讨论】:

以上是关于如何使用 SSL 将 AWS EC2 Flask 应用程序部署到 HTTPS 端口 443?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 godaddy ssl 证书添加到托管在 aws ec2 上的站点

amazonaws ec2怎么配置ssl

将使用 Celery 和 Redis 的 Flask 应用程序部署到 AWS:直接使用 Elastic Beanstalk 还是 EC2?

如何在 AWS EC2 和 ELB 上使用 Godaddy 注册的域实现 SSL 证书

如何启用 (https) SSL 证书 AWS EC2 托管站点

AWS EC2应用程序负载均衡器+双向SSL?