Fossil SCM
Edit pass on the www/ssl-server.md to cover some of the details brought up [forum:/forumpost/94c36cf8d2 | on the forum]. This also adds fragment IDs for section heads and improves the discussion generally.
Commit
f374a46337177bc2dedf37fe2b04acf4813ddb8e917c3e15698f77a14468de38
Parent
9859eb0308cf63c…
1 file changed
+197
-88
+197
-88
| --- www/ssl-server.md | ||
| +++ www/ssl-server.md | ||
| @@ -12,76 +12,107 @@ | ||
| 12 | 12 | |
| 13 | 13 | [0]: ./ssl.wiki |
| 14 | 14 | [1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13 |
| 15 | 15 | |
| 16 | 16 | Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13), |
| 17 | -this has been fixed. Commands like | |
| 17 | +Fossil servers are now able to converse directly over TLS. Commands like | |
| 18 | 18 | |
| 19 | 19 | * "[fossil server](/help?cmd=server)" |
| 20 | 20 | * "[fossil ui](/help?cmd=ui)", and |
| 21 | 21 | * "[fossil http](/help?cmd=http)" |
| 22 | 22 | |
| 23 | -now all handle server-mode SSL/TLS encryption natively. It is now possible | |
| 24 | -to run a secure Fossil server without having to put Fossil behind an encrypting | |
| 25 | -web server or reverse proxy. Hence, it is now possible to stand up a complete | |
| 26 | -Fossil project website on an inexpensive VPS with no added software other than | |
| 27 | -Fossil itself and something like [certbot](https://certbot.eff.org) for | |
| 28 | -obtaining a CA-signed certificate. | |
| 29 | - | |
| 30 | -## Usage | |
| 23 | +may now handle the encryption natively when suitably configured, without | |
| 24 | +requiring a third-party proxy layer. | |
| 25 | + | |
| 26 | +## <a id="usage"></a>Usage | |
| 31 | 27 | |
| 32 | 28 | To put any of the Fossil server commands into SSL/TLS mode, simply |
| 33 | -add the "--cert" command-line option. | |
| 29 | +add the "`--cert`" command-line option: | |
| 34 | 30 | |
| 35 | 31 | fossil ui --cert unsafe-builtin |
| 36 | 32 | |
| 37 | -The --cert option is what tells Fossil to use TLS encryption. | |
| 38 | -Normally, the argument to --cert is the name of a file containing | |
| 39 | -the certificate (the "fullchain.pem" file) for the website. In this | |
| 40 | -example, the magic name "unsafe-builtin" is used, which causes Fossil | |
| 41 | -to use a self-signed cert rather than a real cert obtained from a | |
| 42 | -[Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority) | |
| 43 | -or "CA". As the name implies, this self-signed cert is not secure and | |
| 44 | -should only be used for testing. Your web-browser will complain bitterly | |
| 45 | -and will refuse to display the pages using the "unsafe-builtin" cert. | |
| 46 | -Firefox will allow you to click an "I know the risks" button and continue. | |
| 47 | -Other web browsers will stubornly refuse to display the page, under the theory | |
| 48 | -that weak encryption is worse than no encryption at all. Continue reading | |
| 49 | -to see how to solve this. | |
| 50 | - | |
| 51 | -## About Certs | |
| 52 | - | |
| 53 | -Certs are based on public-key or asymmetric cryptography. To create a cert, | |
| 54 | -you first create a new "key pair" consisting of a public key and a private key. | |
| 55 | -The public key can be freely shared with the world, but you must keep the | |
| 56 | -private key secret. If anyone gains access to your private key then he will be | |
| 57 | -able to impersonate you and break into your system. | |
| 58 | - | |
| 59 | -To obtain a cert, you send your public key and the name of the domain you | |
| 60 | -want to protect to a certificate authority. The CA then digitally signs | |
| 61 | -the combination of those two things using their own private key and sends | |
| 62 | -the signed combination back to you. The CA's digital signature of your | |
| 63 | -public key and domain name is the cert. | |
| 64 | - | |
| 65 | -SSL/TLS servers need two things in order to prove their identity to clients: | |
| 66 | - | |
| 67 | - 1. The cert that was signed by a CA | |
| 68 | - 2. The private key | |
| 69 | - | |
| 70 | -The SSL/TLS servers send the cert to each client, so that the client | |
| 71 | -can verify it. But the private key is kept strictly private and is never | |
| 72 | -shared with anyone. | |
| 73 | - | |
| 74 | -## How To Tell Fossil About Your Cert And Private Key | |
| 75 | - | |
| 76 | -If you do not have your own cert and private key, you can ask Fossil | |
| 33 | +Here, we are passing the magic name "unsafe-builtin" to cause Fossil to | |
| 34 | +use a [hard-coded self-signed cert][hcssc] rather than one obtained from | |
| 35 | +a recognized [Certificate Authority][CA], or "CA". | |
| 36 | + | |
| 37 | +As the name implies, this self-signed cert is _not secure_ and should | |
| 38 | +only be used for testing. Your web browser is likely to complain | |
| 39 | +bitterly about it and will refuse to display the pages using the | |
| 40 | +"unsafe-builtin" cert until you placate it. The complexity of the | |
| 41 | +ceremony demanded depends on how paranoid your browser’s creators have | |
| 42 | +decided to be. It may require as little as clicking a single big "I know | |
| 43 | +the risks" type of button, or it may require a sequence be several | |
| 44 | +clicks designed to discourage the “yes, yes, just let me do the thing” | |
| 45 | +crowd lest they run themselves into trouble by disregarding well-meant | |
| 46 | +warnings. | |
| 47 | + | |
| 48 | +Our purpose here is to show you an alternate path that will avoid the | |
| 49 | +issue entirely, not weigh in on which browser handles self-signed | |
| 50 | +certificates best. | |
| 51 | + | |
| 52 | +[CA]: https://en.wikipedia.org/wiki/Certificate_authority | |
| 53 | +[hcssc]: /info/c2a7b14c3f541edb96?ln=89-116 | |
| 54 | + | |
| 55 | +## <a id="about"></a>About Certs | |
| 56 | + | |
| 57 | +The X.509 certificate system used by browsers to secure TLS connections | |
| 58 | +is based on asymmetric public-key cryptography. The methods for | |
| 59 | +obtaining one vary widely, with a resulting tradeoff we may summarize as | |
| 60 | +trustworthiness versus convenience, the latter characteristic falling as | |
| 61 | +the former rises.(^No strict correlation exists. CAs have invented | |
| 62 | +highly inconvenient certification schemes that offer little additional | |
| 63 | +real-world trustworthiness. Extreme cases along this axis may be fairly | |
| 64 | +characterized as [security theater][st]. We focus in this document on | |
| 65 | +well-balanced trade-offs between decreasing convenience and useful | |
| 66 | +levels of trustworthiness gained thereby.) | |
| 67 | + | |
| 68 | +The self-signed method demonstrated above offers approximately zero | |
| 69 | +trustworthiness, though not zero _value_ since it does still provide | |
| 70 | +connection encryption. | |
| 71 | + | |
| 72 | +More trustworthy methods are necessarily less convenient. One such is to | |
| 73 | +send your public key and the name of the domain you want to protect to a | |
| 74 | +recognized CA, which then performs one or more tests to convince itself | |
| 75 | +that the requester is in control of that domain. If the CA’s tests all | |
| 76 | +pass, it produces an X.509 certificate bound to that domain, which | |
| 77 | +includes assorted other information under the CA’s digital signature | |
| 78 | +attesting to the validity of the document’s contents. The result is sent | |
| 79 | +back to the requester, which may then use it to transitively attest to | |
| 80 | +these tests’ success: presuming one cannot fake the type of signature | |
| 81 | +used, the document must have been signed by the trusted, recognized CA. | |
| 82 | + | |
| 83 | +There is one element of the assorted information included with a | |
| 84 | +certificate that is neither supplied by the requester nor rubber-stamped | |
| 85 | +on it in passing by the CA. It also generates a one-time key pair and | |
| 86 | +stores the public half in the certificate. The cryptosystem this keypair | |
| 87 | +is intended to work with varies both by the CA and by time, as older | |
| 88 | +systems become obsolete. Details aside, the CA then puts this matching | |
| 89 | +private half of the key in a separate file, often encrypted under a | |
| 90 | +separate cryptosystem for security. | |
| 91 | + | |
| 92 | +SSL/TLS servers need both resulting halves to make these attestations, | |
| 93 | +but they send only the public half to the client when establishing the | |
| 94 | +connection. The client then makes its own checks to determine whether it | |
| 95 | +trusts the attestations being made. | |
| 96 | + | |
| 97 | +A properly written and administered server never releases the private | |
| 98 | +key to anyone. Ideally, it goes directly from the CA to the requesting | |
| 99 | +server and never moves from there; then when it expires, the server | |
| 100 | +deletes it permanently. | |
| 101 | + | |
| 102 | +[st]: https://en.wikipedia.org/wiki/Security_theater | |
| 103 | + | |
| 104 | +## <a id="startup"></a>How To Tell Fossil About Your Cert And Private Key | |
| 105 | + | |
| 106 | +As we saw [above](#usage), | |
| 107 | +if you do not have your own cert and private key, you can ask Fossil | |
| 77 | 108 | to use "unsafe-builtin", which is a self-signed cert that is built into |
| 78 | -Fossil. This is wildly insecure, since the private key is not really private - | |
| 79 | -it is [in plain sight](/info/c2a7b14c3f541edb96?ln=89-116) in the Fossil | |
| 109 | +Fossil. This is wildly insecure, since the private key is not really private; | |
| 110 | +it is [in plain sight][hcssc] in the Fossil | |
| 80 | 111 | source tree for anybody to read. <b>Never add the private key that is |
| 81 | 112 | built into Fossil to your OS's trust store</b> as doing so will severely |
| 82 | -compromise your computer. The built-in cert is only useful for testing. | |
| 113 | +compromise your computer.[^ssattack] This built-in cert is only useful for testing. | |
| 83 | 114 | If you want actual security, you will need to come up with your own private |
| 84 | 115 | key and cert. |
| 85 | 116 | |
| 86 | 117 | Fossil wants to read certs and public keys in the |
| 87 | 118 | [PEM format](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). |
| @@ -98,66 +129,142 @@ | ||
| 98 | 129 | *base-64 encoding of the certificate* |
| 99 | 130 | -----END CERTIFICATE----- |
| 100 | 131 | |
| 101 | 132 | In both formats, text outside of the delimiters is ignored. That means |
| 102 | 133 | that if you have a PEM-formatted private key and a separate PEM-formatted |
| 103 | -certificate, you can concatenate the two into a single file and the | |
| 134 | +certificate, you can concatenate the two into a single file, and the | |
| 104 | 135 | individual components will still be easily accessible. |
| 105 | 136 | |
| 106 | -If you have a single file that holds both your private key and your | |
| 137 | +### <a id="cat"></a>Separate or Concatenated? | |
| 138 | + | |
| 139 | +Given a single concatenated file that holds both your private key and your | |
| 107 | 140 | cert, you can hand it off to the "[fossil server](/help?cmd=server)" |
| 108 | -command using the --cert option. Like this: | |
| 141 | +command using the `--cert` option, like this: | |
| 109 | 142 | |
| 110 | 143 | fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil |
| 111 | 144 | |
| 112 | 145 | The command above is sufficient to run a fully-encrypted web site for |
| 113 | 146 | the "myproject.fossil" Fossil repository. This command must be run as |
| 114 | 147 | root, since it wants to listen on TCP port 443, and only root processes are |
| 115 | 148 | allowed to do that. This is safe, however, since before reading any |
| 116 | -information off of the wire, Fossil will put itself inside a chroot jail | |
| 117 | -at /home/www and drop all root privileges. | |
| 118 | - | |
| 119 | -### Keeping The Cert And Private Key In Separate Files | |
| 120 | - | |
| 121 | -If you do not want to combine your cert and private key into a single | |
| 122 | -big PEM file, you can keep them separate using the --pkey option to | |
| 123 | -Fossil. | |
| 149 | +information off of the wire, Fossil will [put itself inside a chroot | |
| 150 | +jail](./chroot.md) at `/home/www` and drop all root privileges. | |
| 151 | + | |
| 152 | +This method of combining your cert and private key into a single big PEM | |
| 153 | +file carries risks, one of which is that the system administrator must | |
| 154 | +make both halves readable by the user running the Fossil server. Given | |
| 155 | +the chroot jail feature, a more secure scheme separates the halves so | |
| 156 | +that only root can read the private half, which then means that when | |
| 157 | +Fossil drops its root privileges, it becomes unable to access the | |
| 158 | +private key on disk. Fossil’s `server` feature includes the `--pkey` | |
| 159 | +option to allow for that use case: | |
| 124 | 160 | |
| 125 | 161 | fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil |
| 126 | 162 | |
| 127 | -## The ACME Protocol | |
| 163 | +[^ssattack]: ^How, you ask? Because the keys are known, they can be used | |
| 164 | + to provide signed certificates for **any** other domain. One foolish | |
| 165 | + enough to tell their OS’s TLS mechanisms to trust the signing | |
| 166 | + certificate is implicitly handing over all TLS encryption controls | |
| 167 | + to any attacker that knows they did this. Don’t do it. | |
| 168 | + | |
| 169 | +### <a id="chain"></a>Chains and Links | |
| 170 | + | |
| 171 | +The file name “`fullchain.pem`” used above is a reference to a term of | |
| 172 | +art within this world of TLS protocols and their associated X.509 | |
| 173 | +certificates. Within the simplistic scheme originally envisioned by the | |
| 174 | +creators of SSL — the predecessor to TLS — we were all expected to agree | |
| 175 | +on a single set of CA root authorities, and we would all agree to get | |
| 176 | +our certificates from one of them. The real world is more complicated: | |
| 177 | + | |
| 178 | +* The closest we have to universal acceptance of CAs is via the | |
| 179 | + [CA/Browser Forum][CAB], and even within its select membership there | |
| 180 | + is continual argument over which roots are trustworthy. (Hashing | |
| 181 | + that out is arguably this group’s key purpose.) | |
| 182 | + | |
| 183 | +* CAB’s decision regarding trustworthiness may not match that of any | |
| 184 | + given system’s administrator. There are solid, defensible reasons to | |
| 185 | + prune back the stock CA root set included with your browser, then to | |
| 186 | + augment it with ones CAB _doesn’t_ trust. | |
| 187 | + | |
| 188 | +* TLS isn’t limited to use between web browsers and public Internet | |
| 189 | + sites. Several common use cases preclude use of the process CAB | |
| 190 | + envisions, with servers able to contact Internet-based CA roots as | |
| 191 | + part of proving their identity. Different use cases demand different | |
| 192 | + CA root authority stores. | |
| 193 | + | |
| 194 | + The most common of these divergent cases are servers behind strict | |
| 195 | + firewalls and edge devices that never interact with the public | |
| 196 | + Internet. This class ranges from cheap home IoT devices to the | |
| 197 | + internal equipment managed by IT for a massive global corporation. | |
| 198 | + | |
| 199 | +Your private Fossil server is liable to fall into that last category. | |
| 200 | +This may then require that you generate a more complicated “chain” of | |
| 201 | +certificates for Fossil to use here, without which the client may not be | |
| 202 | +able to get back to a CA root it trusts. This is true regardless of | |
| 203 | +whether that client is another copy of Fossil or a web browser | |
| 204 | +traversing Fossil’s web UI, though that fact complicates matters by | |
| 205 | +allowing for multiple classes of client, each of which may have their | |
| 206 | +own rules for modifying the stock certificate scheme. | |
| 207 | + | |
| 208 | +This is distressingly common, in fact: Fossil links to OpenSSL to | |
| 209 | +provide its TLS support, but there is a good chance that your browser | |
| 210 | +uses another TLS implementation entirely. They may or may not agree on a | |
| 211 | +single CA root store. | |
| 212 | + | |
| 213 | +How you accommodate all this complexity varies by the CA and other | |
| 214 | +details. As but one example, Firefox’s “View Certificate” feature offers | |
| 215 | +_two_ ways to download a given web site’s certificate: the cert alone or | |
| 216 | +the “chain” leading back to the root. Depending on the use case, the | |
| 217 | +standalone certificate might suffice, or you might need some type of | |
| 218 | +cert chain. Complicating this is that the last link in the chain may be | |
| 219 | +left off when it is for a mutually trusted CA root, implicitly | |
| 220 | +completing the chain. | |
| 221 | + | |
| 222 | +[CAB]: https://en.wikipedia.org/wiki/CA/Browser_Forum | |
| 223 | + | |
| 224 | +## <a id="acme"></a>The ACME Protocol | |
| 225 | + | |
| 226 | +The [ACME Protocol][2] simplifies all this by automating the process of | |
| 227 | +proving to a recognized public CA that you are in control of a given | |
| 228 | +website. Without this proof, no valid CA will issue a cert for that | |
| 229 | +domain, as that allows fraudulent impersonation. | |
| 128 | 230 | |
| 129 | -The [ACME Protocol][2] is used to prove to a CA that you control a | |
| 130 | -website. CAs require proof that you control a domain before they | |
| 131 | -will issue a cert for that domain. The usual means of dealing | |
| 132 | -with ACME is to run the separate [certbot](https://certbot.eff.org) tool. | |
| 231 | +The primary implementation of ACME is [certbot], a product of the Let’s | |
| 232 | +Encrypt organization. | |
| 133 | 233 | Here is, in a nutshell, what certbot will do to obtain your cert: |
| 134 | 234 | |
| 135 | - 1. Certbot sends your "signing request" (the document that contains | |
| 235 | + 1. It sends your "signing request" (the document that contains | |
| 136 | 236 | your public key and your domain name) to the CA. |
| 137 | 237 | |
| 138 | - 2. After receiving the signing request, the CA needs to verify that you | |
| 139 | - control the domain of the cert. To do this (or, one common | |
| 140 | - way of doing this, at least) the CA sends a secret token back to | |
| 141 | - certbot through a secure backchannel, and instructs certbot to make | |
| 142 | - that token accessible on the (unencrypted, ordinary "http:") web site | |
| 143 | - for the domain in a particular file under the ".well-known" subdirectory. | |
| 144 | - | |
| 145 | - 3. Certbot puts the token where the CA requested it, then notifies the | |
| 146 | - CA that it is there. | |
| 147 | - | |
| 148 | - 4. The CA accesses the token to confirm that you do indeed control the | |
| 149 | - website. It then creates the cert and sends it back to certbot. | |
| 150 | - | |
| 151 | - 5. Certbot stores your cert and deletes the ".well-known" token. | |
| 238 | + 2. After receiving the signing request, the CA needs to verify that | |
| 239 | + you control the domain of the cert. One of several methods certbot has | |
| 240 | + for accomplishing this is to create a secret token and place it at | |
| 241 | + a well-known location, then tell the CA about it over ACME. | |
| 242 | + | |
| 243 | + 3. The CA then tries pulling that token, which if successful proves | |
| 244 | + that the requester is able to create arbitrary data on the server, | |
| 245 | + implicitly proving control over that server. This must be done | |
| 246 | + over the unencrypted HTTP protocol since TLS isn’t working yet. | |
| 247 | + | |
| 248 | + 4. If satisfied by this proof of control, the CA then creates the | |
| 249 | + keypair described above and bakes the public half into the | |
| 250 | + certificate it signs. It then sends this and the private half of | |
| 251 | + the key back to certbot. | |
| 252 | + | |
| 253 | + 5. Certbot stores these halves separately for the reasons sketched | |
| 254 | + out above. | |
| 255 | + | |
| 256 | + 6. It then deletes the secret one-time-use token it used to prove | |
| 257 | + domain control. ACME’s design precludes replay attacks. | |
| 152 | 258 | |
| 153 | 259 | In order for all of this to happen, certbot needs to be able to create |
| 154 | -a subdirectory named ".well-known", within a directory you specify, and | |
| 260 | +a subdirectory named ".well-known", within a directory you specify, | |
| 155 | 261 | then populate that subdirectory with a token file of some kind. To support |
| 156 | 262 | this, the "[fossil server](/help?cmd=server)" and |
| 157 | 263 | "[fossil http](/help?cmd=http)" commands have the --acme option. |
| 158 | -When the --acme option is specified and Fossil sees a URL where the path | |
| 264 | + | |
| 265 | +When specified, Fossil sees a URL where the path | |
| 159 | 266 | begins with ".well-known", then instead of doing its normal processing, it |
| 160 | 267 | looks for a file with that pathname and returns it to the client. If |
| 161 | 268 | the "server" or "http" command is referencing a single Fossil repository, |
| 162 | 269 | then the ".well-known" sub-directory should be in the same directory as |
| 163 | 270 | the repository file. If the "server" or "http" command are run against |
| @@ -172,9 +279,11 @@ | ||
| 172 | 279 | Then you create your public/private key pair and run certbot, giving it |
| 173 | 280 | a --webroot of /home/www. Certbot will create the sub-directory |
| 174 | 281 | named "/home/www/.well-known" and put token files there, which the CA |
| 175 | 282 | will verify. Then certbot will store your new cert in a particular file. |
| 176 | 283 | |
| 177 | -Once certbot has obtained your cert, then you can concatenate that | |
| 178 | -cert with your private key and run Fossil in SSL/TLS mode as shown above. | |
| 284 | +Once certbot has obtained your cert, you may either pass the two halves | |
| 285 | +to Fossil separately using the `--pkey` and `--cert` options described | |
| 286 | +above, or you may concatenate them and pass that via `--cert` alone. | |
| 179 | 287 | |
| 180 | 288 | [2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment |
| 289 | +[certbot]: https://certbot.eff.org | |
| 181 | 290 |
| --- www/ssl-server.md | |
| +++ www/ssl-server.md | |
| @@ -12,76 +12,107 @@ | |
| 12 | |
| 13 | [0]: ./ssl.wiki |
| 14 | [1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13 |
| 15 | |
| 16 | Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13), |
| 17 | this has been fixed. Commands like |
| 18 | |
| 19 | * "[fossil server](/help?cmd=server)" |
| 20 | * "[fossil ui](/help?cmd=ui)", and |
| 21 | * "[fossil http](/help?cmd=http)" |
| 22 | |
| 23 | now all handle server-mode SSL/TLS encryption natively. It is now possible |
| 24 | to run a secure Fossil server without having to put Fossil behind an encrypting |
| 25 | web server or reverse proxy. Hence, it is now possible to stand up a complete |
| 26 | Fossil project website on an inexpensive VPS with no added software other than |
| 27 | Fossil itself and something like [certbot](https://certbot.eff.org) for |
| 28 | obtaining a CA-signed certificate. |
| 29 | |
| 30 | ## Usage |
| 31 | |
| 32 | To put any of the Fossil server commands into SSL/TLS mode, simply |
| 33 | add the "--cert" command-line option. |
| 34 | |
| 35 | fossil ui --cert unsafe-builtin |
| 36 | |
| 37 | The --cert option is what tells Fossil to use TLS encryption. |
| 38 | Normally, the argument to --cert is the name of a file containing |
| 39 | the certificate (the "fullchain.pem" file) for the website. In this |
| 40 | example, the magic name "unsafe-builtin" is used, which causes Fossil |
| 41 | to use a self-signed cert rather than a real cert obtained from a |
| 42 | [Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority) |
| 43 | or "CA". As the name implies, this self-signed cert is not secure and |
| 44 | should only be used for testing. Your web-browser will complain bitterly |
| 45 | and will refuse to display the pages using the "unsafe-builtin" cert. |
| 46 | Firefox will allow you to click an "I know the risks" button and continue. |
| 47 | Other web browsers will stubornly refuse to display the page, under the theory |
| 48 | that weak encryption is worse than no encryption at all. Continue reading |
| 49 | to see how to solve this. |
| 50 | |
| 51 | ## About Certs |
| 52 | |
| 53 | Certs are based on public-key or asymmetric cryptography. To create a cert, |
| 54 | you first create a new "key pair" consisting of a public key and a private key. |
| 55 | The public key can be freely shared with the world, but you must keep the |
| 56 | private key secret. If anyone gains access to your private key then he will be |
| 57 | able to impersonate you and break into your system. |
| 58 | |
| 59 | To obtain a cert, you send your public key and the name of the domain you |
| 60 | want to protect to a certificate authority. The CA then digitally signs |
| 61 | the combination of those two things using their own private key and sends |
| 62 | the signed combination back to you. The CA's digital signature of your |
| 63 | public key and domain name is the cert. |
| 64 | |
| 65 | SSL/TLS servers need two things in order to prove their identity to clients: |
| 66 | |
| 67 | 1. The cert that was signed by a CA |
| 68 | 2. The private key |
| 69 | |
| 70 | The SSL/TLS servers send the cert to each client, so that the client |
| 71 | can verify it. But the private key is kept strictly private and is never |
| 72 | shared with anyone. |
| 73 | |
| 74 | ## How To Tell Fossil About Your Cert And Private Key |
| 75 | |
| 76 | If you do not have your own cert and private key, you can ask Fossil |
| 77 | to use "unsafe-builtin", which is a self-signed cert that is built into |
| 78 | Fossil. This is wildly insecure, since the private key is not really private - |
| 79 | it is [in plain sight](/info/c2a7b14c3f541edb96?ln=89-116) in the Fossil |
| 80 | source tree for anybody to read. <b>Never add the private key that is |
| 81 | built into Fossil to your OS's trust store</b> as doing so will severely |
| 82 | compromise your computer. The built-in cert is only useful for testing. |
| 83 | If you want actual security, you will need to come up with your own private |
| 84 | key and cert. |
| 85 | |
| 86 | Fossil wants to read certs and public keys in the |
| 87 | [PEM format](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). |
| @@ -98,66 +129,142 @@ | |
| 98 | *base-64 encoding of the certificate* |
| 99 | -----END CERTIFICATE----- |
| 100 | |
| 101 | In both formats, text outside of the delimiters is ignored. That means |
| 102 | that if you have a PEM-formatted private key and a separate PEM-formatted |
| 103 | certificate, you can concatenate the two into a single file and the |
| 104 | individual components will still be easily accessible. |
| 105 | |
| 106 | If you have a single file that holds both your private key and your |
| 107 | cert, you can hand it off to the "[fossil server](/help?cmd=server)" |
| 108 | command using the --cert option. Like this: |
| 109 | |
| 110 | fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil |
| 111 | |
| 112 | The command above is sufficient to run a fully-encrypted web site for |
| 113 | the "myproject.fossil" Fossil repository. This command must be run as |
| 114 | root, since it wants to listen on TCP port 443, and only root processes are |
| 115 | allowed to do that. This is safe, however, since before reading any |
| 116 | information off of the wire, Fossil will put itself inside a chroot jail |
| 117 | at /home/www and drop all root privileges. |
| 118 | |
| 119 | ### Keeping The Cert And Private Key In Separate Files |
| 120 | |
| 121 | If you do not want to combine your cert and private key into a single |
| 122 | big PEM file, you can keep them separate using the --pkey option to |
| 123 | Fossil. |
| 124 | |
| 125 | fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil |
| 126 | |
| 127 | ## The ACME Protocol |
| 128 | |
| 129 | The [ACME Protocol][2] is used to prove to a CA that you control a |
| 130 | website. CAs require proof that you control a domain before they |
| 131 | will issue a cert for that domain. The usual means of dealing |
| 132 | with ACME is to run the separate [certbot](https://certbot.eff.org) tool. |
| 133 | Here is, in a nutshell, what certbot will do to obtain your cert: |
| 134 | |
| 135 | 1. Certbot sends your "signing request" (the document that contains |
| 136 | your public key and your domain name) to the CA. |
| 137 | |
| 138 | 2. After receiving the signing request, the CA needs to verify that you |
| 139 | control the domain of the cert. To do this (or, one common |
| 140 | way of doing this, at least) the CA sends a secret token back to |
| 141 | certbot through a secure backchannel, and instructs certbot to make |
| 142 | that token accessible on the (unencrypted, ordinary "http:") web site |
| 143 | for the domain in a particular file under the ".well-known" subdirectory. |
| 144 | |
| 145 | 3. Certbot puts the token where the CA requested it, then notifies the |
| 146 | CA that it is there. |
| 147 | |
| 148 | 4. The CA accesses the token to confirm that you do indeed control the |
| 149 | website. It then creates the cert and sends it back to certbot. |
| 150 | |
| 151 | 5. Certbot stores your cert and deletes the ".well-known" token. |
| 152 | |
| 153 | In order for all of this to happen, certbot needs to be able to create |
| 154 | a subdirectory named ".well-known", within a directory you specify, and |
| 155 | then populate that subdirectory with a token file of some kind. To support |
| 156 | this, the "[fossil server](/help?cmd=server)" and |
| 157 | "[fossil http](/help?cmd=http)" commands have the --acme option. |
| 158 | When the --acme option is specified and Fossil sees a URL where the path |
| 159 | begins with ".well-known", then instead of doing its normal processing, it |
| 160 | looks for a file with that pathname and returns it to the client. If |
| 161 | the "server" or "http" command is referencing a single Fossil repository, |
| 162 | then the ".well-known" sub-directory should be in the same directory as |
| 163 | the repository file. If the "server" or "http" command are run against |
| @@ -172,9 +279,11 @@ | |
| 172 | Then you create your public/private key pair and run certbot, giving it |
| 173 | a --webroot of /home/www. Certbot will create the sub-directory |
| 174 | named "/home/www/.well-known" and put token files there, which the CA |
| 175 | will verify. Then certbot will store your new cert in a particular file. |
| 176 | |
| 177 | Once certbot has obtained your cert, then you can concatenate that |
| 178 | cert with your private key and run Fossil in SSL/TLS mode as shown above. |
| 179 | |
| 180 | [2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment |
| 181 |
| --- www/ssl-server.md | |
| +++ www/ssl-server.md | |
| @@ -12,76 +12,107 @@ | |
| 12 | |
| 13 | [0]: ./ssl.wiki |
| 14 | [1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13 |
| 15 | |
| 16 | Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13), |
| 17 | Fossil servers are now able to converse directly over TLS. Commands like |
| 18 | |
| 19 | * "[fossil server](/help?cmd=server)" |
| 20 | * "[fossil ui](/help?cmd=ui)", and |
| 21 | * "[fossil http](/help?cmd=http)" |
| 22 | |
| 23 | may now handle the encryption natively when suitably configured, without |
| 24 | requiring a third-party proxy layer. |
| 25 | |
| 26 | ## <a id="usage"></a>Usage |
| 27 | |
| 28 | To put any of the Fossil server commands into SSL/TLS mode, simply |
| 29 | add the "`--cert`" command-line option: |
| 30 | |
| 31 | fossil ui --cert unsafe-builtin |
| 32 | |
| 33 | Here, we are passing the magic name "unsafe-builtin" to cause Fossil to |
| 34 | use a [hard-coded self-signed cert][hcssc] rather than one obtained from |
| 35 | a recognized [Certificate Authority][CA], or "CA". |
| 36 | |
| 37 | As the name implies, this self-signed cert is _not secure_ and should |
| 38 | only be used for testing. Your web browser is likely to complain |
| 39 | bitterly about it and will refuse to display the pages using the |
| 40 | "unsafe-builtin" cert until you placate it. The complexity of the |
| 41 | ceremony demanded depends on how paranoid your browser’s creators have |
| 42 | decided to be. It may require as little as clicking a single big "I know |
| 43 | the risks" type of button, or it may require a sequence be several |
| 44 | clicks designed to discourage the “yes, yes, just let me do the thing” |
| 45 | crowd lest they run themselves into trouble by disregarding well-meant |
| 46 | warnings. |
| 47 | |
| 48 | Our purpose here is to show you an alternate path that will avoid the |
| 49 | issue entirely, not weigh in on which browser handles self-signed |
| 50 | certificates best. |
| 51 | |
| 52 | [CA]: https://en.wikipedia.org/wiki/Certificate_authority |
| 53 | [hcssc]: /info/c2a7b14c3f541edb96?ln=89-116 |
| 54 | |
| 55 | ## <a id="about"></a>About Certs |
| 56 | |
| 57 | The X.509 certificate system used by browsers to secure TLS connections |
| 58 | is based on asymmetric public-key cryptography. The methods for |
| 59 | obtaining one vary widely, with a resulting tradeoff we may summarize as |
| 60 | trustworthiness versus convenience, the latter characteristic falling as |
| 61 | the former rises.(^No strict correlation exists. CAs have invented |
| 62 | highly inconvenient certification schemes that offer little additional |
| 63 | real-world trustworthiness. Extreme cases along this axis may be fairly |
| 64 | characterized as [security theater][st]. We focus in this document on |
| 65 | well-balanced trade-offs between decreasing convenience and useful |
| 66 | levels of trustworthiness gained thereby.) |
| 67 | |
| 68 | The self-signed method demonstrated above offers approximately zero |
| 69 | trustworthiness, though not zero _value_ since it does still provide |
| 70 | connection encryption. |
| 71 | |
| 72 | More trustworthy methods are necessarily less convenient. One such is to |
| 73 | send your public key and the name of the domain you want to protect to a |
| 74 | recognized CA, which then performs one or more tests to convince itself |
| 75 | that the requester is in control of that domain. If the CA’s tests all |
| 76 | pass, it produces an X.509 certificate bound to that domain, which |
| 77 | includes assorted other information under the CA’s digital signature |
| 78 | attesting to the validity of the document’s contents. The result is sent |
| 79 | back to the requester, which may then use it to transitively attest to |
| 80 | these tests’ success: presuming one cannot fake the type of signature |
| 81 | used, the document must have been signed by the trusted, recognized CA. |
| 82 | |
| 83 | There is one element of the assorted information included with a |
| 84 | certificate that is neither supplied by the requester nor rubber-stamped |
| 85 | on it in passing by the CA. It also generates a one-time key pair and |
| 86 | stores the public half in the certificate. The cryptosystem this keypair |
| 87 | is intended to work with varies both by the CA and by time, as older |
| 88 | systems become obsolete. Details aside, the CA then puts this matching |
| 89 | private half of the key in a separate file, often encrypted under a |
| 90 | separate cryptosystem for security. |
| 91 | |
| 92 | SSL/TLS servers need both resulting halves to make these attestations, |
| 93 | but they send only the public half to the client when establishing the |
| 94 | connection. The client then makes its own checks to determine whether it |
| 95 | trusts the attestations being made. |
| 96 | |
| 97 | A properly written and administered server never releases the private |
| 98 | key to anyone. Ideally, it goes directly from the CA to the requesting |
| 99 | server and never moves from there; then when it expires, the server |
| 100 | deletes it permanently. |
| 101 | |
| 102 | [st]: https://en.wikipedia.org/wiki/Security_theater |
| 103 | |
| 104 | ## <a id="startup"></a>How To Tell Fossil About Your Cert And Private Key |
| 105 | |
| 106 | As we saw [above](#usage), |
| 107 | if you do not have your own cert and private key, you can ask Fossil |
| 108 | to use "unsafe-builtin", which is a self-signed cert that is built into |
| 109 | Fossil. This is wildly insecure, since the private key is not really private; |
| 110 | it is [in plain sight][hcssc] in the Fossil |
| 111 | source tree for anybody to read. <b>Never add the private key that is |
| 112 | built into Fossil to your OS's trust store</b> as doing so will severely |
| 113 | compromise your computer.[^ssattack] This built-in cert is only useful for testing. |
| 114 | If you want actual security, you will need to come up with your own private |
| 115 | key and cert. |
| 116 | |
| 117 | Fossil wants to read certs and public keys in the |
| 118 | [PEM format](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). |
| @@ -98,66 +129,142 @@ | |
| 129 | *base-64 encoding of the certificate* |
| 130 | -----END CERTIFICATE----- |
| 131 | |
| 132 | In both formats, text outside of the delimiters is ignored. That means |
| 133 | that if you have a PEM-formatted private key and a separate PEM-formatted |
| 134 | certificate, you can concatenate the two into a single file, and the |
| 135 | individual components will still be easily accessible. |
| 136 | |
| 137 | ### <a id="cat"></a>Separate or Concatenated? |
| 138 | |
| 139 | Given a single concatenated file that holds both your private key and your |
| 140 | cert, you can hand it off to the "[fossil server](/help?cmd=server)" |
| 141 | command using the `--cert` option, like this: |
| 142 | |
| 143 | fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil |
| 144 | |
| 145 | The command above is sufficient to run a fully-encrypted web site for |
| 146 | the "myproject.fossil" Fossil repository. This command must be run as |
| 147 | root, since it wants to listen on TCP port 443, and only root processes are |
| 148 | allowed to do that. This is safe, however, since before reading any |
| 149 | information off of the wire, Fossil will [put itself inside a chroot |
| 150 | jail](./chroot.md) at `/home/www` and drop all root privileges. |
| 151 | |
| 152 | This method of combining your cert and private key into a single big PEM |
| 153 | file carries risks, one of which is that the system administrator must |
| 154 | make both halves readable by the user running the Fossil server. Given |
| 155 | the chroot jail feature, a more secure scheme separates the halves so |
| 156 | that only root can read the private half, which then means that when |
| 157 | Fossil drops its root privileges, it becomes unable to access the |
| 158 | private key on disk. Fossil’s `server` feature includes the `--pkey` |
| 159 | option to allow for that use case: |
| 160 | |
| 161 | fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil |
| 162 | |
| 163 | [^ssattack]: ^How, you ask? Because the keys are known, they can be used |
| 164 | to provide signed certificates for **any** other domain. One foolish |
| 165 | enough to tell their OS’s TLS mechanisms to trust the signing |
| 166 | certificate is implicitly handing over all TLS encryption controls |
| 167 | to any attacker that knows they did this. Don’t do it. |
| 168 | |
| 169 | ### <a id="chain"></a>Chains and Links |
| 170 | |
| 171 | The file name “`fullchain.pem`” used above is a reference to a term of |
| 172 | art within this world of TLS protocols and their associated X.509 |
| 173 | certificates. Within the simplistic scheme originally envisioned by the |
| 174 | creators of SSL — the predecessor to TLS — we were all expected to agree |
| 175 | on a single set of CA root authorities, and we would all agree to get |
| 176 | our certificates from one of them. The real world is more complicated: |
| 177 | |
| 178 | * The closest we have to universal acceptance of CAs is via the |
| 179 | [CA/Browser Forum][CAB], and even within its select membership there |
| 180 | is continual argument over which roots are trustworthy. (Hashing |
| 181 | that out is arguably this group’s key purpose.) |
| 182 | |
| 183 | * CAB’s decision regarding trustworthiness may not match that of any |
| 184 | given system’s administrator. There are solid, defensible reasons to |
| 185 | prune back the stock CA root set included with your browser, then to |
| 186 | augment it with ones CAB _doesn’t_ trust. |
| 187 | |
| 188 | * TLS isn’t limited to use between web browsers and public Internet |
| 189 | sites. Several common use cases preclude use of the process CAB |
| 190 | envisions, with servers able to contact Internet-based CA roots as |
| 191 | part of proving their identity. Different use cases demand different |
| 192 | CA root authority stores. |
| 193 | |
| 194 | The most common of these divergent cases are servers behind strict |
| 195 | firewalls and edge devices that never interact with the public |
| 196 | Internet. This class ranges from cheap home IoT devices to the |
| 197 | internal equipment managed by IT for a massive global corporation. |
| 198 | |
| 199 | Your private Fossil server is liable to fall into that last category. |
| 200 | This may then require that you generate a more complicated “chain” of |
| 201 | certificates for Fossil to use here, without which the client may not be |
| 202 | able to get back to a CA root it trusts. This is true regardless of |
| 203 | whether that client is another copy of Fossil or a web browser |
| 204 | traversing Fossil’s web UI, though that fact complicates matters by |
| 205 | allowing for multiple classes of client, each of which may have their |
| 206 | own rules for modifying the stock certificate scheme. |
| 207 | |
| 208 | This is distressingly common, in fact: Fossil links to OpenSSL to |
| 209 | provide its TLS support, but there is a good chance that your browser |
| 210 | uses another TLS implementation entirely. They may or may not agree on a |
| 211 | single CA root store. |
| 212 | |
| 213 | How you accommodate all this complexity varies by the CA and other |
| 214 | details. As but one example, Firefox’s “View Certificate” feature offers |
| 215 | _two_ ways to download a given web site’s certificate: the cert alone or |
| 216 | the “chain” leading back to the root. Depending on the use case, the |
| 217 | standalone certificate might suffice, or you might need some type of |
| 218 | cert chain. Complicating this is that the last link in the chain may be |
| 219 | left off when it is for a mutually trusted CA root, implicitly |
| 220 | completing the chain. |
| 221 | |
| 222 | [CAB]: https://en.wikipedia.org/wiki/CA/Browser_Forum |
| 223 | |
| 224 | ## <a id="acme"></a>The ACME Protocol |
| 225 | |
| 226 | The [ACME Protocol][2] simplifies all this by automating the process of |
| 227 | proving to a recognized public CA that you are in control of a given |
| 228 | website. Without this proof, no valid CA will issue a cert for that |
| 229 | domain, as that allows fraudulent impersonation. |
| 230 | |
| 231 | The primary implementation of ACME is [certbot], a product of the Let’s |
| 232 | Encrypt organization. |
| 233 | Here is, in a nutshell, what certbot will do to obtain your cert: |
| 234 | |
| 235 | 1. It sends your "signing request" (the document that contains |
| 236 | your public key and your domain name) to the CA. |
| 237 | |
| 238 | 2. After receiving the signing request, the CA needs to verify that |
| 239 | you control the domain of the cert. One of several methods certbot has |
| 240 | for accomplishing this is to create a secret token and place it at |
| 241 | a well-known location, then tell the CA about it over ACME. |
| 242 | |
| 243 | 3. The CA then tries pulling that token, which if successful proves |
| 244 | that the requester is able to create arbitrary data on the server, |
| 245 | implicitly proving control over that server. This must be done |
| 246 | over the unencrypted HTTP protocol since TLS isn’t working yet. |
| 247 | |
| 248 | 4. If satisfied by this proof of control, the CA then creates the |
| 249 | keypair described above and bakes the public half into the |
| 250 | certificate it signs. It then sends this and the private half of |
| 251 | the key back to certbot. |
| 252 | |
| 253 | 5. Certbot stores these halves separately for the reasons sketched |
| 254 | out above. |
| 255 | |
| 256 | 6. It then deletes the secret one-time-use token it used to prove |
| 257 | domain control. ACME’s design precludes replay attacks. |
| 258 | |
| 259 | In order for all of this to happen, certbot needs to be able to create |
| 260 | a subdirectory named ".well-known", within a directory you specify, |
| 261 | then populate that subdirectory with a token file of some kind. To support |
| 262 | this, the "[fossil server](/help?cmd=server)" and |
| 263 | "[fossil http](/help?cmd=http)" commands have the --acme option. |
| 264 | |
| 265 | When specified, Fossil sees a URL where the path |
| 266 | begins with ".well-known", then instead of doing its normal processing, it |
| 267 | looks for a file with that pathname and returns it to the client. If |
| 268 | the "server" or "http" command is referencing a single Fossil repository, |
| 269 | then the ".well-known" sub-directory should be in the same directory as |
| 270 | the repository file. If the "server" or "http" command are run against |
| @@ -172,9 +279,11 @@ | |
| 279 | Then you create your public/private key pair and run certbot, giving it |
| 280 | a --webroot of /home/www. Certbot will create the sub-directory |
| 281 | named "/home/www/.well-known" and put token files there, which the CA |
| 282 | will verify. Then certbot will store your new cert in a particular file. |
| 283 | |
| 284 | Once certbot has obtained your cert, you may either pass the two halves |
| 285 | to Fossil separately using the `--pkey` and `--cert` options described |
| 286 | above, or you may concatenate them and pass that via `--cert` alone. |
| 287 | |
| 288 | [2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment |
| 289 | [certbot]: https://certbot.eff.org |
| 290 |