How do I add HSTS headers to my nginx / react app on app engine flex?

Viewed 3154

I've got a react app running via nginx on app engine flexible environment, using a custom domain and SSL, and I'd like to add HSTS headers.

I know from what resources i could find that my application code itself needs to serve the headers, rather than putting them directly in any app.yaml file,

so i figured i could do it through my nginx.conf as described in https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

However, my nginx block is specific for responding to app engine requests, so it's really only listening on :8080 -

I was under the impression that all requests come through from app engine to :8080 so I wouldn't imagine adding another server block to listen on 443 would do anything?

maybe i'm better off having the react app somehow serve the header?

worker_processes 1;

events {
  worker_connections 1024;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  # Logs will appear on the Google Developer's Console when logged to 
this
  # directory.
  access_log /var/log/app_engine/app.log;
  error_log /var/log/app_engine/app.log;

  gzip on;
  gzip_disable "msie6";

  server {
    listen 8080;

    server_name localhost;
    root /src/build;

    if ( $http_x_forwarded_proto = 'http' ) {
      return 301 https://$host$request_uri;
    }

    location /nginx_status {
      stub_status on;
      access_log off;
    }

    location / {
      try_files $uri $uri/ /index.html;
    }
  }
}
1 Answers

Well, now i feel foolish.

All I had to do was add the following line in the right place:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

I was initially trying to add it just above the if ( $http_x_forwarded... part and I was also trying it with the always keyword at the end as well and my deploy kept failing with this line in it.

Anyway, it works!

the full resulting nginx.conf is as follows:

worker_processes 1;

events {
  worker_connections 1024;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  # Logs will appear on the Google Developer's Console 
  # when logged to this directory.
  access_log /var/log/app_engine/app.log;
  error_log /var/log/app_engine/app.log;

  gzip on;
  gzip_disable "msie6";

  server {
    listen 8080;

    server_name localhost;
    root /src/build;

    if ( $http_x_forwarded_proto = 'http' ) {
      return 301 https://$host$request_uri;
    }

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";        

    location /nginx_status {
      stub_status on;
      access_log off;
    }

    location / {
      try_files $uri $uri/ /index.html;
    }
  }
}
Related