Ghost CLI optional force https

At the moment the CLI will setup a blog on the host you specify, if that is (for example) https://www.elliotblackburn.com and will only create nginx configurations for that host. If someone tries to navigate to the http version (http://www.elliotblackburn.com) they’ll be met with a standard “welcome to nginx” page.

It’s very straight forward to dive into the nginx config and setup a redirect, but I feel like this should be an option offered by the CLI to handle rather than editing the nginx file specifically. This introduces probably a few design questions.

  1. Should it default to redirecting http -> https if SSL is turned on?
  2. Should it serve http and https requests, though this might require changes in the main ghost project as well as the CLI.

I feel like if I turned on SSL, it should offer to redirect http traffic for me as an option, or do it automatically since most browsers are moving towards global SSL these days, but that’s probably up for debate.

Hm, this definitely sounds like something we should be taking care of - @acburdine / @Aileen ?

1 Like

I remember being able to do something like this when setting up let’s encrypt certificates for nginx with the certbot CLI. It was just an option to choose.

It should be a very simple server block added to the nginx file if done via SSL redirect, so assuming there is some sort of nginx template in the cli project it should be a fairly straightforward PR to add an additional redirecting server block to it. (I say with almost never having looked at the ghost-cli code).

Probably they could be several redirects at the same time, if we follow Google’s classical advice on either all www or all non-www (SEO advice: url canonicalization - Matt Cutts).

For example, if we want Nginx redirects for http → https and www → non-www:

server {
	listen 93.184.216.34:80;
	server_name example.com www.example.com;
	return 301 https://example.com$request_uri;
}

server {
	listen 93.184.216.34:443 ssl http2;
	server_name www.example.com;
	ssl_certificate /etc/letsencrypt/(...).cer;
	ssl_certificate_key /etc/letsencrypt/(...).key;
	return 301 https://example.com$request_uri;
}

server {
	listen 93.184.216.34:443 default_server ssl http2;
	server_name example.com;
	ssl_certificate /etc/letsencrypt/(...).cer;
	ssl_certificate_key /etc/letsencrypt/(...).key;
	(...)
}

(93.184.216.34 is example.com’s IP)


Update: Although this simple configuration works, see another example below on this thread, more compatible with Ghost CLI’s files, Let’s Encrypt renewals, etc.

1 Like

So we actually used to do this in early (pre-1.0) versions of the CLI - I built it in there initially because I thought “if someone enables https, they want to redirect http”. However, in later versions it was removed - can’t remember the exact reasons why. I don’t really want to make the “redirect” behavior the default, however I would definitely accept a PR for (and would be willing to work on) a flag for the CLI nginx stuff that will do that redirect on setup.

@acburdine why would we not want to make this a default for the SSL provisioning step? What’s the use-case for needing both http and https, when we know https is available?

I can’t remember exactly what the use-case was off the top of my head, but iirc @Hannah was the one who suggested not adding the redirect in automatically, so she might remember the reason.

Not guilty! As far as I understand it from digging back through slack logs, there was some concern that Ghost CLI was getting in the way, doing HTTP -> HTTPS redirects in advance and not letting Ghost do it’s redirect to the admin URL.

However, this doesn’t really make any sense to me. The admin URL, if it is set should 100% always be served over HTTPS.

If a user configures HTTPS, I definitely don’t expect that the HTTP version would show an nginx page.

Going forward, we are moving towards only supporting HTTPS - that’s where the web as a whole is going.

IMO, if HTTPS is configured, there should be nginx config in place to serve the ~/.well-known path for HTTP just in case that’s needed again to reissue the cert, and otherwise should redirect to HTTPS.

This is a sensible default, anyone who doesn’t want it to redirect can change it to a custom error page or whatever.

1 Like

About the redirections I’ve mentioned before, I’m thinking it’s better to follow more closely Ghost CLI’s way to do it, with four files (usually in /var/www/ghost/system/files/) instead of one file per domain, including redirections and Let’s Encrypt configuration:

For http://example.comhttps://example.com (file example.com.conf):

server {
	listen 93.184.216.34:80;
	server_name example.com;
	location ~ /.well-known {
		allow all;
	}
	location / {
		return 301 https://example.com$request_uri;
	}
}

For http://www.example.comhttps://example.com (file www.example.com.conf):

server {
	listen 93.184.216.34:80;
	server_name www.example.com;
	location ~ /.well-known {
		allow all;
	}
	location / {
		return 301 https://example.com$request_uri;
	}
}

For https://www.example.comhttps://example.com (file www.example.com-ssl.conf):

server {
	listen 93.184.216.34:443 ssl http2;
	server_name www.example.com;
	ssl_certificate /etc/letsencrypt/www.example.com/fullchain.cer;
	ssl_certificate_key /etc/letsencrypt/www.example.com/www.example.com.key;
	include /etc/nginx/snippets/ssl-params.conf;
	location ~ /.well-known {
		allow all;
	}
	location / {
		return 301 https://example.com$request_uri;
	}
}

For https://example.com (file example.com-ssl.conf):

server {
	listen 93.184.216.34:443 default_server ssl http2;
	server_name example.com;
	ssl_certificate /etc/letsencrypt/example.com/fullchain.cer;
	ssl_certificate_key /etc/letsencrypt/example.com/example.com.key;
	include /etc/nginx/snippets/ssl-params.conf;
	(...)
	location ~ /.well-known {
		allow all;
	}
	(...)
}
1 Like