So, we have several (3, so far) domains registered for our website (don’t ask me, why). And we need to host our website properly, so there is only one copy of it (obviously), but it should available from any of those domains. And on top of that we want to serve it via HTTPS, so we need a certificate.

Web domains TLS

In this article I’ll describe what needs to be done for that.

I want to declare right from the beginning - quite possible, that I did something wrong along the way, so if you’ll spot any errors, please let me know in the comments section under the article.

Register and set-up your domains

First you need to register domains with your domain name registrar and then point them to you hoster name servers.

Those are our current domains:

  1. protvshows.com;
  2. protvshows.ru;
  3. просериалы.рф.

I assume that you did the first part (registration), so I will start with the hoster.

We’re using DigitalOcean (the link is referral), but all the hosters share the same principle (because that’s how the internet works).

In case of weird domain names such as this просериалы.рф cyrillic name, you cannot add them just like that, so they need to be transformed. It can be done via this converter, for example, so просериалы.рф becomes xn--80ajjnlfhch9h.xn--p1ai.

Anyway, add all your domains here:

DigitalOcean domains

And then set-up their records. Basically, in addition to the standard NS records you only need to add A (pointing it to your droplet) and CNAME (so your website is accessible not only as protvshows.ru, but also as www.protvshows.ru (even though the whole www thing is absolutely not necessary)) records:

DigitalOcean normal domain

And just in case here’s how settings for our weird xn--80ajjnlfhch9h.xn--p1ai converted from просериалы.рф look like:

DigitalOcean cyrillic domain

Hoster part is done.

Set-up your web-server

In our case it is nginx. Here’s a config from /etc/nginx/sites-enabled/:

server {
    listen 80;
    listen [::]:80;
    server_name protvshows.com www.protvshows.com;

    # pass everything to Kestrel
    location / {
            proxy_pass http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection keep-alive;
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
}

server {
    listen 80;
    listen [::]:80;
    server_name protvshows.ru www.protvshows.ru xn--80ajjnlfhch9h.xn--p1ai;
    return 301 http://protvshows.com$request_uri;
}

Note, that my nginx runs as reverse-proxy, so your location setting most probably will be different.

So, what is happening here? We have a main domain protvshows.com, and additional protvshows.ru and xn--80ajjnlfhch9h.xn--p1ai (again, don’t use cyrillic form). Last two don’t have any location on them, they just redirect everything to the main one.

Why don’t we have www.xn--80ajjnlfhch9h.xn--p1ai? Because it looks kinda stupid: www.просериалы.рф, don’t you think? It should be either everything is english, or everything is cyrillic. By the way, the whole idea of having national (non-english) domains (cyrillic, arabic, chineese, etc) sucks big ass in the first place.

And why do we have both protvshows.com and www.protvshows.com (same for other two domains)? Because Let’s Encrypt doesn’t support wildcard domains so far, but they promised to do so on 27.02.2018. When they’ll do that, it will be enough to have just those in nginx config:

  • .protvshows.com
  • .protvshows.ru
  • .xn--80ajjnlfhch9h.xn--p1ai

Let’s Encrypt certificate

The only step left is to get a TLS certificate, and you are free to choose between any of certificate authorities. I decided to use Let’s Encrypt, because it is free and deadly easy - it literally does everything for you.

Go to Let’s Encrypt website and from there to Certbot. For me it was this page.

Having installed Certbot on your server, execute this:

certbot --nginx

Based on what it will discover in your web-server configs, it will be ask something like this:

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: protvshows.com
2: protvshows.ru
3: www.protvshows.ru
4: www.protvshows.com
5: xn--80ajjnlfhch9h.xn--p1ai

Then it will ask if you would like to redirect HTTP traffic, so every visitor would be forced to go through HTTPS:

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.

I chose to redirect.

After that it will request certificates for the domains you specified, download all the necessary files and modify your nginx config. For me it now looks like this:

server {
    listen 80;
    listen [::]:80;
    server_name protvshows.com www.protvshows.com;

    location / {
            proxy_pass http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection keep-alive;
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/protvshows.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/protvshows.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    } # managed by Certbot
}

server {
    listen 80;
    listen [::]:80;
    server_name protvshows.ru www.protvshows.ru xn--80ajjnlfhch9h.xn--p1ai;
    return 301 https://protvshows.com$request_uri;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/protvshows.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/protvshows.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Don’t forget to modify the 301 redirection scheme for secondary domains - it should be https now.

Reload nginx for changes to be applied:

nginx -s reload

Now your website should get a lock icon in the browser address bar:

Let's Encrypt certificate

One more thing you should know (and do). Those certificates expire in 90 days, so every 90 days you need to renew them by executing:

certbot renew

But instead you can just add this command to your crontab:

1 1 1 * * certbot renew

Here it actually runs every month (every 60 days). Just in case.