3
votes

I have a Windows/.NET elastic beanstalk instance with an SSL cert setup on the load balancer. By default this creates a port forwarding from https/443 to http/80. I would like to have 443/https on the load balancer forward to 443 https on the beanstalk instance.

I was trying to do what is documented here:

I reconfigured the corresponding EC2 instance EC2-->Load Balancers-->Listeners so that HTTPS forward to HTTPS configured with my SSL cert, the problem is when I try and make an HTTPS request after that it just times out. It seems like the ElasticBeanstalk instance doesn't like me modifying the EC2 Listeners.

Any ideas?

3

3 Answers

2
votes

To get SSL to work in between the LoadBalancer and the Elastic beanstalk I need several things:

  1. Configure the EC2 LoadBalancer to forward port 443 to port 443 (on SSL). I already had this part in the question above.

  2. Configure the IIS on the EC2 instance like any other site with SSL: a). Install SSL Cert on EC2 instance in IIS. b). Add https/443 binding with the SSL cert.

The problem was I was expecting #2 for free. On Windows Azure this is pretty much free when you configure certificates on your instance, but as of now this is not the case on AMZN ElasticBeanstalk for windows.

I also would expect #2 to be scriptable so I could scale up or down instances without have to manually do #2. I was looking for some easy way to tie in power-shell scripts on my EB instances but they apparently don't have this feature either.

My final solution was to create a custom vm images (AMI) with the SSL cert installed an the https binding already added. If I do this I can deploy the ElasticBeanstalk image with my SSL stuff already setup. Doing this then allows me to scale up or down without any configuration.

1
votes

This was a particular problem for me with my ASP.NET MVC project with various OAuth providers. Basically anything that should use https was broken under Elastic Beanstalk. I tried coding around it by looking for the X-Forwarded-Proto HTTP header, but it was pretty nasty. So I really wanted SSL straight through to my EC2 instances.

It probably took me 3h to figure out how to do this without using an AMI, so hopefully this helps someone.

I've previously tried the custom AMI approach and, though it works, it presents two problems:

  1. I have to patch and maintain my own AMI which is time consuming. If I use a standard image, I can just rebuild the environment when a newer image is available.
  2. I can't source-control my configuration settings - they are just embedded in an opaque AMI somewhere in the cloud.

I adapted this from this post.

First of all, you need to add a directory to the root of your visual studio web project called: .ebextensions.

Inside it, create a text file called environment.config - we're going to use YAML here, so don't edit it in Visual Studio in case it thinks it's an Application Config file and adds tabs - YAML is whitespace sensitive. The syntax for the file is documented on Amazon.

My file has a bunch of other settings for tuning IIS, but the relevant bit looks like this:

container_commands:
  site_add_ssl_binding:
    command: PowerShell -ExecutionPolicy Bypass -File "C:\\inetpub\\wwwroot\\.ebextensions\\ssl.ps1"

This will execute a custom PowerShell script called ssl.ps1. So let's create that inside the .ebextensions directory:

# If there is no existing SSL binding
if ( -not(Get-WebBinding "Default Web Site" -Port 443) ) {

    # Import the .pfx file into the certificate store
    $securepwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWORD_HERE" -Force -AsPlainText
    $cert = Import-PfxCertificate -FilePath C:\inetpub\wwwroot\.ebextensions\my-certificate.pfx cert:\localMachine\my -Password $securepwd

    # Create site binding in IIS
    New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https
    New-Item IIS:SslBindings\0.0.0.0!443 -value $cert
}

When executed, this command will import a .pfx file into the certificate store, and then create the SSL binding on port 443 of your website.

With the original code that I referenced, I had all kinds of issues with dodgy character encodings. So if you copy/paste this sample and it doesn't work, you can test it by remoting into your EC2 instance, opening a command prompt and executing the command directly: PowerShell -ExecutionPolicy Bypass -File "C:\inetpub\wwwroot\.ebextensions\ssl.ps1"

You'll need to add your .pfx file to the .ebextensions directory too. In Visual Studio, make sure that all of the files are included in the project, and have a Build Action of Content (tip select the file in the Solution Explorer and press F4). The solution explorer should look like:

  • web-project.csproj
    • .ebextensions
      • environment.config
      • my-certificate.pfx
      • ssl.ps1
  • ...

Then using the AWS Toolkit for Visual Studio, right-click on your project and select Publish to AWS and follow the prompts. This will upload your deployment package to your Elastic Beanstalk environment, and install it. Your customisations will be executed during a deployment, or whenever a new EC2 instance is provisioned.

Following a successful execution, the .ebextensions directory gets deleted.

If you don't want to include the .pfx file inside your Visual Studio project, the original example uses PowerShell to download the .pfx file from an S3 instance. You can also avoid embedding the password in the .ps1 by referencing an Elastic Beanstalk environment variable.

To get this working end-to-end you'll also need to:

  1. Configure your load-balancer to forward 443 traffic to port 443 on your EC2 instances - the default switches to port 80.
  2. Configure the security group out of the load-balancer to allow 443 traffic.
  3. Configure the security group into the EC2 instances to allow 443 traffic.
0
votes

With some instance types, you can configure Elastic Beanstalk app servers via configuration files. You can use this technique to enable SSL.

See Serve HTTPS From Elastic Beanstalk Application Instances for example configuration.