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?