Here is the application directory structure.
- app/__init_.py
- app/static/
- app/models/
- app/views/
- application.py
- requirements.txt
- .elasticbeanstalk/config
- .elasticbeanstalk/optionsettings.application_name
- .ebextensions/python.config
- .ebextensions/https.config
Here are the snippets of files inside .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/
Here is the steps I took to create SSL certificate from CheapSSL
- openssl genrsa 2048 > privatekey.pem
- openssl req -new -key privatekey.pem -out csr.pem
- Made SSL certificate request to Comodo and received three files
- Root CA Certificate - AddTrustExternalCARoot.crt
- Intermediate CA Certificate - PositiveSSLCA2.crt
- Your PositiveSSL Certificate - server.crt
Note: I specified the server to be Apache/OpenSSL
Lastly, here are the snippets of files inside .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-----
This config is a snippet from AWS Elastic Beanstalk documentation with small changes. http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/SSLPython.SingleInstance.html
- mod_ssl -> mod24_ssl due to yum install error. I was lucky to find this fix from Github
- 01killhttpd excluded. After going through deploying application multiple times, killing httpd left permanent damage to the application.
The symptom is the following.
- Can access to http:
- Gives 403 Forbidden You don't have permission to access / on this server. for https:
I will disclose the site address if necessary.
I have taken every step specified in AWS Documentation but still failed to achieve a single goal; hooking my site with https. There aren't enough posts available online to help me figure this out. I stayed away from Load Balancer because I purchased domain using GoDaddy and it's too complicated to set up domain for lb (That's another story).
Here is the link to the snapshot of Elastic Beanstalk Log.
https://dl.dropboxusercontent.com/u/23288606/Log.txt
Thanks in advance.
Update:
Someone read the logs and pointed out an error message stating this.
[ssl:warn] [pid 1989] AH01909: [ec2-address].compute.amazonaws.com:443:0 server certificate does NOT include an ID which matches the server name
So yeah, SSL certificate refers to my custom domain while the server still thinks of it as ec2's default Public DNS (I think).
FYI, the custom domain is purchased from Godaddy. I made it so that A Record points to my ec2 ip address.
In short, how do I make it so that when my ec2 server sets up ssl, it knows its fqdn is my custom domain, not the one provided by ec2?
WARNING: I'm a developer, not a sys admin and I have no idea what I am doing.
This week I had the exact same problems. Including the domain one. Here is a configuration that worked for me. Feedback is welcomed since I just hacked this togheter.
Add first I thought the forbidden problems had to do with file permissions. Which I think is why OP has his permissions set to
777
. In my case it had to do with Apache versions. Amazon uses Apache 2.2 in their example but have 2.4 in the servers. Confirm that by runninghttpd -v
. If this is true then see this link. Which gave me my changes in<Proxy *>
and<Directory /opt/python/current/app/>
. I don't know the difference betweenOrder deny,allow
andOrder allow,deny
, which I now know are called access controls. If I changed them wrong please let me know. Then I received404
errors.After changing that I had to change:
to
This should point to the file where you create your application object. Your's might be different.
Then had to change:
to
because in my app the static files are in nested folder. This should point to the directory with your. Notice
my-app-name
is a variable to be changed by you if needed.Lastly I added a
chain
file. This was given to me by the SSL people with my certificate. You might need to add it too. In my understanding it might be optional but not really.Sorry if I missed anything.
Update
I had issues with the file modes. I had to quote them: mode: "000755" mode: "000400"
I will update the configuration to reflect these changes.
These don't match:
You possibly should have:
for that directive.