使用SSL的Elastic Beanstalk上的Flask提供了403 Forbidden

时间:2014-08-23 08:29:52

标签: ssl amazon-web-services amazon-ec2 flask elastic-beanstalk

这是应用程序目录结构。

  • 应用程序/ __ init_.py
  • 应用程序/静态/
  • 应用程序/模型/
  • 应用程序/视图/
  • application.py
  • requirements.txt
  • .elasticbeanstalk /配置
  • .elasticbeanstalk / optionsettings.application_name
  • .ebextensions / python.config
  • .ebextensions / https.config

以下是.elasticbeanstalk

中文件的片段
#config
EnvironmentTier=WebServer::Standard::1.0
EnvironmentType=SingleInstance
Region=us-west-1
ServiceEndpoint=https://elasticbeanstalk.us-west-1.amazonaws.com
SolutionStack=64bit Amazon Linux 2014.03 v1.0.3 running Python

#optionsettings.application_name
[aws:elasticbeanstalk:container:python]
NumProcesses=1
NumThreads=15
StaticFiles=/static/=app/static/
WSGIPath=application.py

[aws:elasticbeanstalk:container:python:staticfiles]
/static/=app/static/

以下是我从CheapSSL

创建SSL证书的步骤
  • openssl genrsa 2048> privatekey.pem
  • openssl req -new -key privatekey.pem -out csr.pem
  • 向Comodo发出SSL证书请求并收到三个文件
    • 根CA证书 - AddTrustExternalCARoot.crt
    • 中级CA证书 - PositiveSSLCA2.crt
    • 您的PositiveSSL证书 - server.crt

注意:我将服务器指定为Apache / OpenSSL

最后,这里是.ebextensions

中文件的片段
#https.config
Resources:
  sslSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupName: {Ref : AWSEBSecurityGroup}
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

packages:
  yum:
    mod24_ssl : []

files:
  /etc/httpd/conf.d/ssl.conf:
    mode: 000777
    owner: ec2-user
    group: ec2-user
    content: |
      LoadModule ssl_module modules/mod_ssl.so
      Listen 443
      <VirtualHost *:443>
        <Proxy *>
          Order deny,allow
          Allow from all
        </Proxy>
        SSLEngine on
        SSLCertificateFile "/etc/pki/tls/certs/server.crt"
        SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"

        Alias /static /opt/python/current/app/
        <Directory /opt/python/current/app/>
        Order allow,deny
        Allow from all
        </Directory>

        WSGIScriptAlias / /opt/python/current/app/python/application.py

        <Directory /opt/python/current/app/>
        Order allow,deny
        Allow from all
        </Directory>

        WSGIDaemonProcess wsgi-ssl processes=1 threads=15 display-name=%{GROUP} \
          python-path=/opt/python/current/app:/opt/python/run/venv/lib/python2.6/site-packages user=wsgi group=wsgi \
          home=/opt/python/current/app
        WSGIProcessGroup wsgi
      </VirtualHost>

  /etc/pki/tls/certs/server.crt:
    mode: 000777
    owner: ec2-user
    group: ec2-user
    content: |
      -----BEGIN CERTIFICATE-----
      #contents from server.crt
      -----END CERTIFICATE-----


  /etc/pki/tls/certs/server.key:
    mode: 000777
    owner: ec2-user
    group: ec2-user
    content: |
      -----BEGIN RSA PRIVATE KEY-----
      #contents from privatekey.pem
      -----END RSA PRIVATE KEY-----

此配置是来自AWS Elastic Beanstalk文档的片段,只有很小的更改。 http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/SSLPython.SingleInstance.html

  • mod_ssl - &gt;由于yum安装错误导致mod24_ssl。我很幸运能从Github找到这个修复
  • 01killhttpd排除在外。在多次部署应用程序之后,杀死httpd会对应用程序造成永久性损坏。

症状如下。

  • 可以访问http:
  • 授予403 Forbidden您无权访问此服务器上的/。对于https:

如有必要,我会透露网站地址。

我已经采取了AWS文档中指定的每一步,但仍未能实现单一目标;用https挂钩我的网站。网上没有足够的帖子可以帮助我解决这个问题。我远离Load Balancer,因为我使用GoDaddy购买域名,而且为lb设置域名太复杂了(那是另一个故事)。

以下是Elastic Beanstalk Log快照的链接。

https://dl.dropboxusercontent.com/u/23288606/Log.txt

提前致谢。

更新

有人阅读了日志并指出了一条错误消息,说明了这一点。

[ssl:warn] [pid 1989] AH01909: [ec2-address].compute.amazonaws.com:443:0 server certificate does NOT include an ID which matches the server name

所以是的,SSL证书是指我的自定义域名,而服务器仍然认为它是ec2的默认公共DNS(我认为)。

仅供参考,自定义域名是从Godaddy购买的。我这样做是为了让A Record指向我的ec2 ip地址。

简而言之,我如何做到这一点,以便当我的ec2服务器设置ssl时,它知道它的fqdn是我的自定义域,而不是ec2提供的域?

2 个答案:

答案 0 :(得分:2)

警告:我是开发人员,而不是系统管理员,我不知道我在做什么

本周我遇到了同样的问题。包括域名之一。这是一个适合我的配置。欢迎提供反馈,因为我刚刚攻击了这一点。

Resources:
  sslSecurityGroupIngress: 
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupName: {Ref : AWSEBSecurityGroup}
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

packages:
  yum:
    mod24_ssl : []

files:
  /etc/httpd/conf.d/ssl.conf:
    mode: "000755"
    owner: root
    group: root
    content: |
      LoadModule ssl_module modules/mod_ssl.so
      Listen 443
      <VirtualHost *:443>
        <Proxy *>
        Require all granted
        </Proxy>
        SSLEngine on
        SSLCertificateFile "/etc/pki/tls/certs/server.crt"
        SSLCertificateChainFile "/etc/pki/tls/certs/inter.crt"
        SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"

        Alias /static /opt/python/current/app/printwithme/static
        <Directory /opt/python/current/app/>
        Order allow,deny
        Allow from all
        </Directory>

        WSGIScriptAlias / /opt/python/current/app/application.py

        <Directory /opt/python/current/app/>
        Require all granted
        </Directory>

        WSGIDaemonProcess wsgi-ssl processes=1 threads=15 display-name=%{GROUP} \
          python-path=/opt/python/current/app:/opt/python/run/venv/lib/python2.6/site-packages user=wsgi group=wsgi \
          home=/opt/python/current/app
        WSGIProcessGroup wsgi-ssl
      </VirtualHost>

  /etc/pki/tls/certs/server.crt:
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----

      -----END CERTIFICATE-----

  /etc/pki/tls/certs/server.key:
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN RSA PRIVATE KEY-----

      -----END RSA PRIVATE KEY-----

  /etc/pki/tls/certs/inter.crt:
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----

      -----END CERTIFICATE-----

container_commands:
  01killhttpd:
    command: "killall httpd"
  02waitforhttpddeath:
    command: "sleep 3"

首先添加我认为禁止的问题与文件权限有关。我认为OP的权限设置为777。就我而言,它与Apache版本有关。亚马逊在他们的例子中使用Apache 2.2,但服务器中有2.4。通过运行httpd -v确认。如果是这样,请参阅this link。这给了我<Proxy *><Directory /opt/python/current/app/>的更改。我不知道Order deny,allowOrder allow,deny之间的区别,我现在知道它们被称为访问控制。如果我改错了,请告诉我。然后我收到了404个错误。

改变之后我不得不改变:

WSGIScriptAlias / /opt/python/current/app/python/application.py

WSGIScriptAlias / /opt/python/current/app/application.py

这应该指向您创建应用程序对象的文件。你可能会有所不同。

然后不得不改变:

Alias /static /opt/python/current/app/

Alias /static /opt/python/current/app/my-app-name/static

因为在我的应用程序中,静态文件位于嵌套文件夹中。这应该指向你的目录。注意my-app-name是您需要更改的变量。

最后,我添加了一个chain文件。这是由SSL人员凭我的证书给我的。您可能还需要添加它。根据我的理解,它可能是可选的,但不是真的。

很抱歉,如果我错过了什么。

更新

我遇到了文件模式的问题。我不得不引用它们:     模式:&#34; 000755&#34;     模式:&#34; 000400&#34;

我将更新配置以反映这些更改。

答案 1 :(得分:0)

这些不匹配:

    WSGIDaemonProcess wsgi-ssl processes=1 threads=15 display-name=%{GROUP} \
      python-path=/opt/python/current/app:/opt/python/run/venv/lib/python2.6/site-packages user=wsgi group=wsgi \
      home=/opt/python/current/app
    WSGIProcessGroup wsgi

你可能应该:

    WSGIProcessGroup wsgi-ssl

用于该指令。