Overcomming the virtual hosts/HTTPs conflict on Amazon AWS


Previously I've described the conflict between virtual hosts and HTTPs. For those that use Amazon's EC2 cloud, the below describes an elegant remedy for that conflict .

Assumed Basic Setup


For the purposes of this example, I'll assume you have an EC2 instance of Ubuntu Lucid with an apache server serving two websites: example.com and eazybusiness.com. Both have their own virtual host definitions, each containing it's corresponding site's specific configuration. If you need more information on how to configure your virtual hosts I direct you to apache's comprehensive documentation on the subject.

The virtual host definitions would look something like:

<VirtualHost *:80>
ServerName www.eazybusiness.com

ServerAdmin admin@eazybusiness.com
DocumentRoot /var/sites/eazybusiness.com/
</VirtualHost>
<VirtualHost *:80>
ServerName www.example.com

ServerAdmin admin@example.com
DocumentRoot /var/sites/example.com/
</VirtualHost>


The above definitions allow insequre, plain HTTP connections to both sites. The hostname provided by the browser client is matched against the servername's in the virtual hosts and the correct configuration is used accordingly.

Configure Amazon's Elastic Load Balancer


In order to secure our two websites, we'll first create the necessary proxy via Amazon's load balancer facility.

  • First configure your ec2 image to use the Amazon command line tools. Ubuntu this images make this easier thanks to the power of apt-get.


  • Seperate command line tools are required for ELB. Download the tools from Amazon, and unzip to somewhere on your image.

  • Set an environment variable AWS_ELB_HOME to point to where you unzipped the tools.



Now, let's create our first loadbalancer:

Here we configured loadbalacer to listen on port 443 and port 80. All requests to port 80, are to be forwarded to port 80, and requests to 443 are to be forwarded to 8445
Note: amazon's api tools default to the region us-east-1. If you wish to use any other region, you must provide the --region parameter

Create a second loadbalancer for example.com:

Note: the example.com loadbalancer will forward requests to port 443 to a different port than the eazybusiness.com loadbalancer

Next, register our instance with both load balancers:

elb-register-instances-with-lb eazybusiness --region us-west-1 --instances $instanceId
elb-register-instances-with-lb example --region us-west-1 --instances $instanceId


Configure Apache


Apache must start to list on the ports that the load balancers will forward to. To this, edit /etc/apache2/ports.conf and add the lines:

Listen 8443 https
Listen 8445 https

To confirm the ports are being listened on try the following commands:

netstat -na | more
nmap -sT -O localhost


Ensure mod_headers is enabled
sudo a2enmod headers


Configure Virtual Hosts


The virtual hosts need to be configured for SSL, and reflect the ports defined for the loadbalancers. In our example, the virtual hosts become:

<VirtualHost *:80>
ServerName www.eazybusiness.com

ServerAdmin admin@eazybusiness.com
DocumentRoot /var/sites/eazybusiness.com/
SSLEngine On
SSLCertificateFile /etc/ssl/eazybusiness.com.crt
SSLCertificateKeyFile /etc/ssl/eazybusiness.com.key
RequestHeader set X_FORWARDED_PROTO 'https'
</VirtualHost>
<VirtualHost *:80>
ServerName www.example.com

ServerAdmin admin@example.com
DocumentRoot /var/sites/example.com/
SSLEngine On
SSLCertificateFile /etc/ssl/example.com.crt
SSLCertificateKeyFile /etc/ssl/example.com.key
RequestHeader set X_FORWARDED_PROTO 'https'
</VirtualHost>

Note: the RequestHeader directive requires that you enable mod_headers for Apache.
sudo a2enmod headers


Configure DNS


The AWS console displays a list of load balancers. From this list, glean the relevant DNS names, and make the relevant alterations to the dns server like this:

eazybusiness.com. IN CNAME eazybusiness-2028819496.us-west-1.elb.amazonaws.com.
example.com. IN CNAME example-2028229496.us-west-1.elb.amazonaws.com.

Note: don't forget the proceeding dot when using full domains.

Configure Amazon Firewall


Ensure the specified ports open, which in our example are 8445 and 8443.

To confirm the port is open with Telnet try:

telnet $public_dns_of_image 8445



After completing all of the steps above you should now be able to support multiple secure websites sharing the same webserver.

References


Major credit goes to this post

Comments

  1. Thanks for providing this informative information you may also refer.
    http://www.s4techno.com/blog/2015/12/21/protect-instances-from-termination-by-auto-scaling/

    ReplyDelete
  2. I admire the valuable information you offer in your articles. I will bookmark your blog and have my friends check up here often. I am quite sure they will learn lots of new stuff here than anybody else! Regards aws openings in hyderabad.

    ReplyDelete
  3. Hello Admin,
    I really enjoyed while reading your article, the information you have mentioned in this post was damn good. Keep sharing your blog with updated and useful information.
    Regards,
    Amazon Web Services Training in Chennai

    ReplyDelete

Post a Comment

Popular posts from this blog

AngularJs: User friendly date display with AngularJs and MomentJs

Nerd Tree: A File Explorer with Mac Vim

Getting started with Grails functional tests using Geb + Spock