132

Many companies have intranet websites that are not reachable via the internet. Usually they just use a self-signed certificate, which causes a bad habit for the users since they get used to just pressing OK on invalid CERT warnings.

Question: How can they generate a certificate for their HTTPS websites using Let's Encrypt? Does the LTS web browsers have the Let's Encrypt as CA?

Isn't it a privacy issue that private domain names, like my-company-private-intranet-site.com, could be leaked?

5
  • 38
    Employees should be taught to import the company's self signed cert into their browser's trusted store. So that bad habits of clicking OK on websites don't develop.
    – RoraΖ
    Commented Oct 23, 2015 at 16:17
  • 3
    I agree with @RoraZ if it is their computer and they have to remotely connect via the VPN. But if it is a computer at the office we generate a self signed root CA to trust our certificates, import it into the trusted store on their machine, and our employees interact with it like any other HTTPS site. Our employees are also less technical. It is wasted breath to try and talk them through the process.
    – Bacon Brad
    Commented Apr 21, 2016 at 18:34
  • 1
    And furthermore why are you using a public facing domain for a private facing website? Not only is it unnecessary but you are potentially routing internal traffic externally depending on your network/firewall/dns configuration.
    – Bacon Brad
    Commented Apr 22, 2016 at 1:29
  • 8
    I'm a little shocked by RoraZ's suggestion. You don't want users installing their own certs. Begging for disaster there.
    – Matthew
    Commented Apr 3, 2017 at 13:12
  • 2
    I think RoraZ meant the campany's CA cert with which the ssl certs have been signed, and not the actual self-signed ssl cert. Commented Oct 7, 2019 at 17:34

7 Answers 7

133
+50

Let's Encrypt can only issue certificates for valid DNS names. So if your intranet uses a made-up domain name like intranet.mycompany.local then it won't work.

If you have a real DNS name like intranet.mycompany.com (even if it doesn't resolve externally to your intranet), then you can use Let's Encrypt to issue certificates for it. If the domain does resolve externally to a server that can respond on port 80 (which need not actually be part of your intranet, if you have split-horizon DNS), you can use the http-01 challenge.

Alternatively, you can use the dns-01 challenge (fully supported in Certbot 0.10.0 and later, as well as other clients such as dehydrated, getssl and acme.sh). Since this challenge works by provisioning DNS TXT records, you don't ever need to point an A record at a public IP address.

So your intranet does not need to be reachable from the Internet, but your domain name does need to exist in the public DNS under your control.

Let's Encrypt - and publicly trusted certificate authorities in general, due to Chrome's requirements - submit all issued certificates to public certificate transparency logs. As such, you should not expect your intranet (sub)domain name to remain secret if you obtain a certificate for it. Your intranet's security shouldn't be dependent on keeping its domain name secret anyway.

5
  • You would need to at least briefly allow it to resolve…
    – Ángel
    Commented Apr 25, 2016 at 21:15
  • 11
    Not if you use the dns-01 challenge. Commented Apr 26, 2016 at 7:32
  • 32
    If your intranet security depends on its domain name being a secret, then you have a much bigger homework to do.
    – Lie Ryan
    Commented Dec 22, 2016 at 2:13
  • 1
    I didn't think I was implying otherwise, but the upvotes on your comment have convinced me I was wrong :) So, edited. Commented Dec 17, 2017 at 0:16
  • Thanks! This led me to a useful article on how to utilise dns-01! dev.to/michaeldscherr/…
    – kiradotee
    Commented Jun 30, 2020 at 17:47
36

If you are looking for a internal CA-like service for an Intranet, then a public CA like Lets Encrypt may not work, as it want to connect back to its servers to manage the cert request and signing. This assumes you do not have internet access out from your intranet web server; you need to install a client on the webserver for it to communicate with the Lets Encrypt service.

How can they generate a CERT for their HTTPS website using Let's Encrypt?

LE has a dedicated client for this purpose. See How it Works

Does the LTS webbrowsers have the Let's Encrypt as CA?

There is limited support for browser ready CA root certs; see https://github.com/letsencrypt/letsencrypt#disclaimer. They do have public certs on the site at https://letsencrypt.org/certificates/

Let's get back to your main point, which was the issuance of browser accepted SSL certs that do not generate warnings. As RoraZ suggests you need to have users import the company's self signed cert to eliminate the recurring browser warnings, and prevent users developing habit of simply accepting invalid certificates.

We use OpenSSL to allow us to function as our own certificate authority, generating a root CA that all users must import, thereby allowing us to generate any additional certs that will automatically be accepted by all employees browser, or any service that rely on SSL. This is different than simply importing the self-signed cert as needed; you are actually creating a root CA certificate, and importing it. Going forward, you can issue any number of certificates for different common names, signed by this CA, and they are valid and trusted via your own private root certificate authority.

For creating and managing your own certificate authority, See http://www.flatmtn.com/article/setting-openssl-create-certificates

2
  • Thanks, this is a great answer. Could you quickly cover the main points of importing a certificate into a browser? I assume it may be different for Linux and Windows systems. My guess is that on Linux it would occur at the system level rather than browser.
    – r0berts
    Commented Jan 23, 2017 at 9:00
  • 1
    Ah good question. I prefer to place the final cert file in the root document folder, so that you can simply send a link to coworkers EG example.com/myrootca.crt. On Windows you just open the link in the browser and follow import prompts. For Linux it's a bit different. See unix.stackexchange.com/questions/90450/… Commented Jan 29, 2017 at 13:50
16

UPDATE 2019-03-30: Somebody actually found a large scale way of doing LE for internal servers: https://blog.heckel.xyz/2018/08/05/issuing-lets-encrypt-certificates-for-65000-internal-servers/

——————-

How can they generate a CERT for their HTTPS website using Let's Encrypt?

Not at all. This is for publicly reachable sites only.

(Update 2016-04-22: Maybe "not at all" is a little too hard. Here's a little more detail: LE is tailored to publicly reachable sites. You need some server that answers to the DNS name when LE comes asking. Now if you have configured your DNS server to give different answers depending on who is actually asking the question -- somebody from the inside or from the outside aka Split-Brain-DNS -- then you can redirect the verification request to any host that you want. -- But this is not a use case that LE really helps you with. On the contrary: In 2015, there was this explicit intention: "we plan to frequently change the set of IPs from which we validate". -- So that pretty much makes it impossible for you to just whitelist the IPs for the LE-validation-hosts on your firewall because these IPs may frequently change.

Does the LTS webbrowsers have the Let's Encrypt as CA?

Yes. Their CA is cross signed by a well known, well established CA. (Namely by IdenTrust.) So all clients that trust that old CA will also trust the new Let's-Encrypt CA right away.

4
  • 1
    @techraf: yes. But if in order to get the cert you have to make the site public, even if briefly, then I will answer "nope" to the question "Can I get a cert for an unreachable site?" -- And this is the same thing that the commenter in the link said: "private names can still get certs with ACME if they are public at the time of validation" -- I don't know if LE already allows DNS-only application. Then you could get around that. Even though I think your supposedly private DNS name would still end up in public Certificate Transparency logs. Commented Apr 22, 2016 at 6:09
  • @techraf: I agree. I works. But I think this is a hack. LE is not tailored to do this. Will change my post to accordingly. Commented Apr 22, 2016 at 6:24
  • @techraf: updated. Also: I like John Morahan's answer regarding this. Commented Apr 22, 2016 at 6:47
  • 1
    You don't necessarily need fancy DNS configuration to answer differently based on who is asking. If you configure your intranet VPN to favour internal DNS, that's configured to point to the real intranet, over the regular external DNS, that's normally run by your registrar configured to point to a publicly accessible server you trust to process domain verification, then you can pass the domain control verification, and then you can transfer the certificate over to your intranet.
    – Lie Ryan
    Commented Apr 22, 2016 at 12:33
3

For a proper solution you can run an own boulder instance, i.e. the letsencrypt server part, on your network. Then you can use all official and inofficial clients with your own ACME-Server if they support using different ACME urls (the official ones do, for others you need to look it up in their documentation or source code).

Then you need to import the CA certificate in the trust store of the clients using your servers.

If you're only having a few servers running boulder and "letsencrypt" yourself is probably not the best choice and you can use more simple tools like easy rsa.

2

the people suggesting putting internal names in a public certificate authority should look at public certificate transparency logs and understand this leaks information about internal systems names to the internet

https://blog.appsecco.com/certificate-transparency-part-3-the-dark-side-9d401809b025 https://www.ssl.com/faqs/questions-about-certificate-transparency/

I would suggest, you read the possible solutions. The best solution would be to implement your own Public Key Infrastructure(PKI) in your organization. This will avoid your internal hosts from getting listed in a CT log maintained by a public CA.

Its just another thing that a potential attacker would have to discover that you made more difficult by not disclosing your names.

0

So long as you own the real domains and don't want one for domains like localhost or internal network IP's, you could generate one on the public internet, pointing to a blank system, then transfer it to your intranet using rsync or similar.

You can even now apparently get a wildcard, so *.internal.yoursite.extension could work. It is obviously useless for spoofing sites like microsoft.com.

I Can understand why spoofing sites is undesirable, but I can also see how it can be useful to not have to install CA's on every workstation in the org.

1
  • 4
    Last label of a domain name is not an "extension". It is a TLD. Please use RFC2606 next time you want to do some obfuscation. Commented Apr 13, 2018 at 22:54
0

I found this article to be very useful at implementing certificates at my private (no public access to the websites) servers - https://dev.to/michaeldscherr/lets-encrypt-ssl-certificate-via-dns-challenge-8dd

The guide used Apache but this is a very flexible approach (I was using Nginx). Once the certificates are created you just point the configuration that uses them to their location and that should do the trick.

This is the implementation part:

...

Setup


We'll be discussing the DNS Challenge approach for the rest of the article.

In the examples below, I'll be using Apache & Ubuntu 16.04 following this guide. To find documentation for your specific web server / operating system, go to certbot's homepage.

First we need to install certbot along with all necessary dependencies.

# run as root

apt-get update \
    && apt-get install software-properties-common \
    && add-apt-repository -y universe \
    && add-apt-repository -y ppa:certbot/certbot \
    && apt-get update \
    && apt-get install -y python-certbot-apache

Configuration I won't be going over wildcard domains here, but they are an option. Refer to their documentation.

We now need to tell certbot which domains we would like to issue a certificate for. Remember to add each subdomain individually.

Since we may have multiple vhosts per server, we decided to use the --manual & certonly flags.

# run as root

# replace with your domain
# add all relevant subdomains
certbot --manual --preferred-challenges dns certonly \
    -d yourwebsite.com \
    -d www.yourwebsite.com \          # don't forget www binding
    -d staging.yourwebsite.com \      # example subdomain
    -d staging.stage1.yourwebsite.com # example long subdomain

Challenge Prompts


Once you run the command above, it will prompt you to add a DNS TXT record for each specified domain. It will look like this:

Please deploy a DNS TXT record under the name
_acme-challenge.yourwebsite.com with the following value:

[random-string-of-characters]

Before continuing, verify the record is deployed.
(This must be set up in addition to the previous challenges; do not remove,
replace, or undo the previous challenge tasks yet. Note that you might be
asked to create multiple distinct TXT records with the same name. This is
permitted by DNS standards.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Now here's the important part. You need to remove the base url from each record name, like so: enter image description here Once you add the DNS TXT records, and click Continue through each challenge prompt respectively, the validation should pass.

Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/yourwebsite.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/yourwebsite.com/privkey.pem
   Your cert will expire on 2019-04-24. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Updating Your VHost


Now that we have a valid certificate, we can update our vhost:

# inside the 443 binding

SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/yourwebsite.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourwebsite.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/yourwebsite.com/chain.pem

Then restart Apache:

sudo apachectl configtest

# if syntax ok
sudo apachectl restart

Bonus: Setup Auto Renewal


We'll leverage the crontab of the root user to automatically renew certificates that will expire soon.

# run as root

# edit the crontab
crontab -e

Then add the following two lines at the bottom:

# every Monday at 2:30am
30 2 * * 1 /usr/bin/certbot renew --deploy-hook "service apache2 reload" >> /var/log/letsencrypt/le-renew.log

The certbot will try and renew any certificates marked for renewal once a week. We then use the --deploy-hook to only reload apache if necessary.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .