/ Blog Meta

Now Supporting HTTPS and IPv6

A small change for others, but a decent-sized change on my end, this blog now supports HTTPS. I'll work out enforcing HTTPS for all connections, but for the time being the blog can be served with or without SSL encryption. In addition, the blog now supports end-to-end IPv6 connectivity. Many thanks to AWS ACM, ALB and Route53 services for making both those changes possible.

Next up may be CloudFront integration, but I think cost-saving is more important than being globally performant at this point.

EDIT: My mistake - I had set up IPv6 support but hadn't configured the AAAA DNS records in Route53. That has now been remedied.


EDIT2: And now HTTPS is enforced across the entire site! This was an interesting problem given that this is typically done via a URL rewrite (or HTTP 301 response being sent back) from the nginx backend server. However, this blog is behind an AWS ALB, so that means that unless I put the same SSL cert on the backend as is in use on the ALB, I the backend server is to expect all requests to come in on port 80. So how to get around this?

Set up an additional server port on the backend specifically for returning a 301:

server {
  listen 80;
  server_name jgreenemi.com;

  location / {
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;

# Set up redirection rules to ensure HTTPS is always used.
server {
  listen 81;
  server_name jgreenemi.com;
  return 301 https://$server_name$request_uri;

Note that by returning a 301 to the ALB (and subsequently getting a 301 back to the viewer's browser), this triggers the same request to be made to the path that was requested, just with the HTTPS protocol specified. Also note that I didn't use the oft-used URL rewrite method because this is less clean and less scalable:

rewrite ^/(.*)$ https://jgreenemi.com permanent;

Although this would set up a permanent redirect, it means that if you went to a sub-page of the site while on HTTP, you would get dropped back to the main page on HTTPS, rather than being sent to that same page over HTTPS.

Now, I mentioned earlier that this being behind an ALB introduces some complexity. That's because you can't, at present, redirect a client request based on the protocol used - you can route it to a different Target Group of EC2 instances based on what TCP port and path it came in on though. In my case, this works out well because I set up two Target Groups, both expecting requests on port 80, and registered my web server instance behind each of them. However, on one group I registered the instance for port 80, and the other for port 81. Following this I set the ALB paths for sending client requests from the ALB's port 80 to the Target Group for using the backend's port 81, which will always invoke the HTTP 301 response. For requests coming in on the ALB's port 443, those requests simply go to the Target Group configured for the backend instance's port 80, servicing requests normally.


EDIT3: I've also introduced syntax highlighting via Prism like so!

    <!-- An HTML example. -->
    <link rel="stylesheet" type="text/css" href="/assets/css/prism-okaidia.css" />
    <script src="/assets/js/prism.js?v=358420d181"></script>
  * A Scala example.
object {
  def main(args: Array[String]): Unit = {

Although the tutorials all indicated that each block needed to be prefixed with language-html or language-scala, recent updates now only require the language name to be supplied, like html or scala.

It's the little things that make a difference.