Skip to content

Instantly share code, notes, and snippets.

@Syrup-tan
Last active February 5, 2017 13:19
Show Gist options
  • Save Syrup-tan/71a76394b3fe918dce8d to your computer and use it in GitHub Desktop.
Save Syrup-tan/71a76394b3fe918dce8d to your computer and use it in GitHub Desktop.

SSL over :80 with nginx

Using nginx's error_page directive we can support SSL over both :80 and :443

Why?

Some intrusive firewalls, ISPs, companies, and ``Anti-virus'' programs attempt to intercept SSL connections on :443. Some of these programs even offer their own certificate, in order to perform MiTM attacks. In more extreme cases, connections may be entirely blocked on :443.

By allowing SSL connections on :80, users with these threats may still access the server securely.

How?

Using nginx's error_page directive, and nginx's (non-standard) HTTP 497 error we can (internally or externally) redirect requests based on whether or not SSL was used.

See the example configuration directives in example.nginxconf

See a live server at https://denpa.moe/ (The content on the page is irrelevant to the demonstration)

Firefox Demo Chromium Demo Safari Demo

Some example URLs to try out:

Should I?

Probably not.

While I use this setup on my hobby server as a ``kind of neat feature'', I wouldn't reccomend it for production-use because it isn't an officially supported feature.


Hacker News discussion

/r/sysadmin discussion

## this is an incomplete config, do not use verbatim
server {
## Have nginx listen for SSL on both :80 and :443
listen 80 ssl spdy;
listen [::]:80 ssl default_server spdy ipv6only=on;
listen 443 ssl spdy;
listen [::]:443 ssl spdy ipv6only=on;
server_name denpa.moe;
root /srv/www/denpa.moe;
autoindex on;
index index.html index.txt;
## SSL-only; redirect plaintext to SSL on :443
## This mode allows SSL connections on both :80 and :443
## Any plaintext requests will be redirected to SSL over :443
## This mode is ideal for servers which are already SSL-only,
## as it refuses to send plaintext data while still allowing
## SSL connections over port 80
## e.g: http://denpa.moe/~syrup redirects to https://denpa.moe/~syrup
## e.g: http://denpa.moe:443/~syrup redirects to https://denpa.moe/~syrup
## e.g: https://denpa.moe:80/~syrup will load without redirects (already SSL)
## e.g: https://denpa.moe/~syrup will load without redirects (already SSL)
## It's good practice to use a 302 (temporary) redirect while testing
## This is the mode currently used on https://denpa.moe/
error_page 497 =302 https://$host$request_uri;
error_page 497 =301 https://$host$request_uri;
## Plaintext and SSL allowed
## This mode allows both plaintext and SSL requests on both :80 and :443
## This mode is the least likely to break anything
## e.g: http://denpa.moe/~syrup will load in plaintext
## e.g: http://denpa.moe:443/~syrup will load in plaintext
## e.g: https://denpa.moe:80/~syrup will load over SSL
## e.g: https://denpa.moe/~syrup will load over SSL
error_page 497 $request_uri;
## SSL-only; redirect plaintext:80 to ssl:80, plaintext:443 to ssl:443
## This mode allows SSL connections on both :80 and :443
## Any plaintext connections will be redirect to SSL on the same port
## While this mode is ideal for firewall dodging, it has weird problems with caching,
## and should not be used in production.
## e.g: http://denpa.moe/~syrup redirects to https://denpa.moe:80/~syrup
## e.g: http://denpa.moe:443/~syrup redirects to https://denpa.moe:443/~syrup
## e.g: https://denpa.moe:80/~syrup will load without redirects (already SSL)
## e.g: https://denpa.moe/~syrup will load without redirects (already SSL)
error_page 497 =302 https://$host:$server_port$request_uri;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment