Advice for a Newby

Your question covers quite a range of topics, which are all relatively common questions - they're difficult. Yet I couldn't readily find a nice point-to topic that covers most basics in one go, so I'm writing this slightly longer post instead.

Let us start with a few basics: What do certificates do?

In short, they provide authenticity. When you are browsing the web, you want transferred data to remain secure in-transit - no one listening on the wire should be able to see what you are sending or receiving. On a technical level, this requires three different things: Confidentiality, Authentication, and Integrity. Confidentiality and Integrity are provided by what we usually call "encryption algorithms" or "ciphers". I'm skipping over details here, but essentially we just encrypt the data, so no one can read them. However, in order for the data to be secure, we also need to authenticate it. Essentially, we want to know that the other side of the wire is who we believe it to be. If we establish an encrypted connection to an attacker, there's really no point in encrypting at all. We need assurance that the party we are connected to is what it claims to be. This authentication is provided by certificates. They're essentially proofs of identity, notarized by a trustworthy party - the Certificate Authority (CA). Let's Encrypt is one of such CAs.

A protocol providing all of this is called Transport Layer Security, or TLS in short. It's also known as Secure Socket Layer (SSL). This protocol is what the "S" in HTTPS stands for: HTTPS is HTTP over TLS.

An important misconception is, that certificates also provide trustworthiness - this is not the case. Certificates provide authenticity, but that does not assure that the authenticated party is honest. A sentence you commonly hear is "you could have a private, authenticated conversation with satan". A Domain Validated (DV) certificate assures you that you are really talking to example.com, but it doesn't tell you "the people running example.com are good people" (they probably are, but that's not something the certificate tells you). Most importantly, a certificate does not protect against phishing - phishing websites can have certificates, just like everyone else.


When you want to protect a service against an attacker, you always (even if implicitly) need to define a threat model: What do you want to protect against?

For the internet or web, this answer is usually always the same: Against an active or passive attacker having access to your data packets transferred over the internet. TLS, or HTTPS, provides protection against this type of attacker (if properly configured).

For a local (private) network, this threat model might differ. If you consider your private network to be secure, with no attackers present on it, you actually don't need HTTPS/TLS at all: It gives you absolutely no value, if your threat model does not include such an attacker. Browsers primarily warn about insecure (HTTP) websites, because the browser can't possibly know whether the entire data path taken by the network packet was already secure. It is common security practice to always assume that network packets are transmitted over insecured networks, so browsers warn you about this.

Best practice is to also consider your private network to be insecure, as this could give you an additional layer of defense in depth: Of course you will try to secure your local network, but if your data is still secure even if were not, that's better. This is why it can make sense to also employ TLS/HTTPS in your local network.


Once you've decided that you want TLS on your services, you need a certificate - to provide the authenticity we discussed earlier.

Now, we need to understand that Let's Encrypt is a publicly trusted CA. That means, almost every computer in the world trusts certificates issued by Let's Encrypt. This comes with a high level of responsibility: Let's Encrypt needs to validate that you actually control the identities you want to issue certificates for.

Let's Encrypt performs so called Domain-Validation (DV). It works by checking that you control the domains you are issuing certificates for. For a local network, you might use raw IP addresses, or use private domain names (.local, .lan...). Let's Encrypt cannot issue certificates for such domains, as it is impossible to validate global, unique control over them - anyone can use them in their own networks.

Therefore, if you want a local network secured with Let's Encrypt certificates, you need globally unique domain names for all of your machines you want to secure. In addition to this, you also need to be able to perform a challenge from Let's Encrypt to perform the proof of domain control. There are three different types of challenges, which I don't want to cover in more detail here. A short overview of the process is in the documentation. I have written a brief description of the challenge types in the past. However, for internal networks we need to know that we will need a mechanism that allows Let's Encrypt to connect either to our machines via HTTP(S), or we will need (automated) DNS access to perform domain validation via DNS.

Especially the HTTP challenge - which is normally the simplest to perform - can get difficult in an isolated network. This makes Let's Encrypt often unfavorable for these networks, as its difficult to obtain publicly trusted certificates for them. It is generally possible though, but it varies from setup to setup.


A different option is to obtain a certificate not issued by a publicly trusted CA. Certificates can be generated by absolutely everyone. The value of having them signed by a CA is that they obtain trust through this process: A public CA is trusted, and so everything signed by them is too. If you create your own CA, no one will trust it. For a public website, this is a problem, but for a network where you own all of the devices it might not be. You can configure your own machines to trust your own CA, and then issue certificates however you like, without being bound to restrictions.

This approach is often taken by enterprise networks, but setting up your own CA can be a complex and difficult task - especially if you want it automated, manual methods may be easier here. There are a few systems available that I know of: Plain OpenSSL (manual), XCA (manual), Smallstep (automated, partially commercial), EJBCA (automated/manual, community + commercial), and Dogtag (automated, requires RedHat products). Neither of these are particularly easy I'm afraid. Smallstep is probably the easiest, though some features are either not available at all or only available as part of a commercial closed-source product.

You can also manually configure trust exceptions in your browsers - generate one-time certificates for your services, write down their fingerprints, then set exceptions in the browser - or better, add the certificate as trusted to the browser by hand. This is easy and fast, and also fairly secure, as the browser remembers the exception (but only for this exact certificate).


So overall, what's the recommended solution? It varies for everyone. If you can perform one of the three Let's Encrypt challenges in an automated way, getting certificates from Let's Encrypt can be easy & secure. Remember that the lifetime of Let's Encrypt is only 90 days, so you want to do this automated.

If you can't get that to work, setting up your own CA or using trust exceptions is another perfectly valid way to go.

8 Likes