6

LetsEncrypt certificates have been created for example.com and www.example.com. This is a Linux server on IP 123.123.123.1.

I would like to add foo.example.com and bar.example.com, but these subdomains are set to 123.123.123.2 (MS2012 server, IPs set in DNS records).

I need the SSL certs to be able to transfer data without throwing browser errors. Apparently, the certs created on server 123.123.123.1 just need to be copied over to 123.123.123.2.

The problem is that using

sudo certbot --apache --cert-name example.com -d example.com,www.example.com,foo.example.com,bar.example.com

to add the subdomains, I get an unauthorized error and 404.

How can I add subdomains to the certificate, provided that they are on another server (which I have access to)?

Fid
  • 161
  • 1
  • 3
  • You need to use the manual method of certbot where you will have to create the challenge file yourself on the target servers. Details can be found at https://certbot.eff.org/docs/using.html#manual – void_in Jun 11 '18 at 17:43
  • Don't copy the certificate and key if you don't have to. It complicates the process and makes it more error-prone (even if you automate it). I suggest having separate certificates on each server. The server probably doesn't need cert for subdomains hosted on the other server. – v6ak Jun 11 '18 at 19:36
  • I tried using --manual with DNS challenge (since I can change DNS at will), but it returned an error (which I can't see now that I've switched networks and don't see my terminal history). Would adding wildcards to the certificate work? – Fid Jun 11 '18 at 22:38

3 Answers3

1

Assuming you have ssh access to server where foo.example.com and bar.example.com are hosted, just run the certbot command with above two domains only, and it should work without any errors and browser warnings. For certbot to be able to generate certs, it needs to be run on the same server where the domains are hosted.

secf00tprint
  • 202
  • 1
  • 11
1lastBr3ath
  • 909
  • 6
  • 13
  • The subdomains are hosted on the second server, but the main (www) domain is hosted on the first. I have been told to create the certificates on the first server and then copy them over to the second server, but now I'm confused since certbot can't do the challenges on the second server. – Fid Jun 11 '18 at 15:16
  • Why cannot it? Did you get any error or something? I have cm2.pw which doesn't have SSL at all, while blog.cm2.pw and raw.cm2.pw are using Let's Encrypt and are hosted on a different server. – 1lastBr3ath Jun 11 '18 at 16:05
0

I ended up using

certbot certonly --manual --cert-name example.com --preferred-challenge dns -d example.com,www.example.com,x.example.com,y.example.com,z.example.com --agree-tos --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory

Also important is to wait until the DNS records propagate in the web or in my case (being in the same network), wait 5 minutes until the DNS settings take affect.

Fid
  • 161
  • 1
  • 3
0

I've been doing this for over a year with a few scripts from one Linux box to another. Let me outline what I'm doing, since I won't be able to share the scripts. Besides, you are using Windows on one end, so some shell scripts would be fairly useless.

The certbot client uses a well-known URI named /.well-known to place the token file used for automated domain validation via HTTP (using the webroot authenticator/plugin).

Now what I did for those handful of domains located on what's in your case 123.123.123.2, was to enable HTTP (i.e. port 80) on 123.123.123.1 and configure the virtual hosts for foo.example.com and bar.example.com respectively.

That virtual host was then configured (in Nginx) to point to a physical location for URI /.well-known so that certbot would be able to place the token file into that path:

location /.well-known/ {
    alias /your/path/.well-known/;
    autoindex on;
    try_files $uri $uri/ =404;
    limit_except GET {
        deny  all;
    }
}

This way I can use the webroot authenticator of certbot and point to the web root of said "fake domain" (it's fake because it's a virtual host on 123.123.123.1 whereas the DNS entries for that domain point to 123.123.123.2).

Now this isn't where it ends, but it's the first step.

On the other machine where the DNS actually points to I installed rinetd to point back to 123.123.123.1 (the machine running certbot) on port 80. In /etc/rinetd.conf this looks like:

127.0.0.1       8080      123.123.123.1  80

At the same time any requests to /.well-known for sites foo.example.com and bar.example.com on 123.123.123.2 are silently proxied to 127.0.0.1 port 80, while leaving the HTTP parameters (host name and URI intact).

By using this methods certbot (running on .1) will, for example, create a token file /your/path/.well-known/foobar and Letsencrypt will attempt to access http://foo.example.com/.well-known/foobar. That request will - as usual - end up on the machine to which the DNS record(s) point(s). So it ends up on .2 where the HTTP server is configured to silently forward requests for items underneath URI /.well-known to 127.0.0.1 port 8080, which rinetd uses to forward the packets to 123.123.123.1 port 80. And thereby we close the circle and certbot will be able to do its domain validation routine.

Alas, I am running this on Linux, so with your setup seemingly being a Windows Server, you'll have to find (or create) something like rinetd for Windows. Even though this may not help directly, perhaps it helps someone else having a similar issue with two Linux boxes.

The whole rinetd routine is aimed at getting the HTTP headers to 123.123.123.1 intact, such that the virtual host for that domain takes effect on 123.123.123.1.

Using this routine one of my servers does the renewal for an array of other machines that actually host individual subdomains.


Oh and on another note. Your scenario is just a very explicit one. If you want to run XMPP or an MTA and the lookup of the service isn't strictly tied just to the DNS lookup of the A/AAAA or CNAME records, you'll end up in a situation that is technically just the same as yours.

If someone has a smarter idea how to solve this, give me a shout in the comments to this answer.

0xC0000022L
  • 1,604
  • 2
  • 15
  • 20