Fossil SCM

fossil-scm / www / ssl.wiki
Source Blame History 328 lines
f146e21… drh 1 <title>Securing a Repository with TLS</title>
062d2bf… wyoung 2
062d2bf… wyoung 3 <h2>Using TLS-Encrypted Communications with Fossil</h2>
062d2bf… wyoung 4
062d2bf… wyoung 5 If you are storing sensitive information in a repository accessible over
062d2bf… wyoung 6 a network whose integrity you do not fully trust, you should use TLS to
062d2bf… wyoung 7 encrypt all communications with it. This is most true for repositories
062d2bf… wyoung 8 accessed over the Internet, especially if they will be accessed from
062d2bf… wyoung 9 edge networks you do not control, since that admits of various forms of
062d2bf… wyoung 10 [https://en.wikipedia.org/wiki/Man-in-the-middle_attack|man in the
062d2bf… wyoung 11 middle attack].
062d2bf… wyoung 12
062d2bf… wyoung 13 TLS protects the credentials used to access the server, prevents
062d2bf… wyoung 14 eavesdropping, prevents in-flight data modification, prevents server
062d2bf… wyoung 15 identify spoofing, and more.
062d2bf… wyoung 16
062d2bf… wyoung 17 There are two major aspects to this, both of which have to be addressed
062d2bf… wyoung 18 in different ways. Those are the subjects of the next two major
062d2bf… wyoung 19 sections.
062d2bf… wyoung 20
062d2bf… wyoung 21
27458ef… wyoung 22 <h2 id="client">Client-Side Configuration</h2>
062d2bf… wyoung 23
27458ef… wyoung 24 You can build Fossil against [https://www.openssl.org/ |
27458ef… wyoung 25 OpenSSL] to allow it to clone and sync with a remote
062d2bf… wyoung 26 Fossil repository via <tt>https</tt> URIs.
062d2bf… wyoung 27
a13820d… wyoung 28
48b74fc… wyoung 29 <h3 id="openssl-bin">Building Against OpenSSL Automatically</h3>
a13820d… wyoung 30
062d2bf… wyoung 31 The <tt>configure</tt> script will attempt to find OpenSSL on your
48b74fc… wyoung 32 system automatically. It first tries asking the <tt>pkg-config</tt>
48b74fc… wyoung 33 system where the OpenSSL development files are, and if that fails, it
48b74fc… wyoung 34 falls back to looking through a list of likely directories.
48b74fc… wyoung 35
48b74fc… wyoung 36 If it can't find the files it needs, the most common solution is to
48b74fc… wyoung 37 install the OpenSSL development package on your system via your OS's
48b74fc… wyoung 38 package manager. Examples:
a13820d… wyoung 39
27458ef… wyoung 40 * <b>RHEL & Fedora</b>: <tt>sudo dnf install openssl-devel</tt>
a13820d… wyoung 41 * <b>Debian & Ubuntu</b>: <tt>sudo apt install libssl-dev</tt>
a13820d… wyoung 42 * <b>FreeBSD</b>: <tt>su -c 'pkg install openssl'</tt>
a13820d… wyoung 43 * <b>macOS</b>: <tt>sudo brew install openssl</tt>
a13820d… wyoung 44 * <b>Cygwin</b>: Install <tt>openssl-devel</tt> via Cygwin's
a13820d… wyoung 45 <tt>setup-*.exe</tt> program
a13820d… wyoung 46
a13820d… wyoung 47 The macOS case requires explanation. Apple last shipped OpenSSL
a13820d… wyoung 48 develpoment files in OS X 10.6 (Snow Leopard), choosing to deprecate it
a13820d… wyoung 49 from that point forward. (Apple wants you to use their proprietary
a13820d… wyoung 50 platform-specific encryption methods instead.) Since macOS has no
a13820d… wyoung 51 built-in package manager, a number have sprung up out of the FOSS world.
a13820d… wyoung 52 It is not known to this author whether Fossil's current build system can
a13820d… wyoung 53 find OpenSSL as installed with any of these other package managers, so
a13820d… wyoung 54 unless you have a particular reason to avoid it, we recomend that you
a13820d… wyoung 55 use [https://brew.sh|Homebrew] on macOS to install OpenSSL as above.
a13820d… wyoung 56 Fossil's build system will seek it out and use it automatically.
a13820d… wyoung 57
a13820d… wyoung 58
a13820d… wyoung 59 <h3 id="openssl-src">Building Against a Non-Platform Version of
a13820d… wyoung 60 OpenSSL</h3>
a13820d… wyoung 61
48b74fc… wyoung 62 The Fossil build system has a few other methods for finding OpenSSL when
48b74fc… wyoung 63 the automatic methods fail or when you'd prefer that Fossil use a
48b74fc… wyoung 64 different version of OpenSSL than the one Fossil's build system picks on
48b74fc… wyoung 65 its own.
48b74fc… wyoung 66
48b74fc… wyoung 67 A good reason to do this is when the Fossil build system finds a
48b74fc… wyoung 68 functioning version of OpenSSL which is nevertheless unsuitable. One
48b74fc… wyoung 69 common case is that your OS is sufficiently outdated that the platform
48b74fc… wyoung 70 version of OpenSSL can no longer communicate with remote systems
48b74fc… wyoung 71 adhering to the latest advice on secure communications. An old OpenSSL
48b74fc… wyoung 72 might not support any of the
48b74fc… wyoung 73 [https://en.wikipedia.org/wiki/Cipher_suite|cipher suites] the remote
48b74fc… wyoung 74 Fossil repository's HTTPS proxy is willing to offer, for example, so
48b74fc… wyoung 75 that even though both sides are speaking a variant of TLS/SSL, the peers
48b74fc… wyoung 76 cannot come to an agreement on the cryptography.
48b74fc… wyoung 77
48b74fc… wyoung 78 If you've installed the OpenSSL development files somewhere that
48b74fc… wyoung 79 Fossil's build system cannot find on its own, you can clue it in by
48b74fc… wyoung 80 passing the <tt>--with-openssl</tt> option to the <tt>configure</tt>
48b74fc… wyoung 81 script. Type <tt>./configure --help</tt> for details.
48b74fc… wyoung 82
48b74fc… wyoung 83 Another option is to download the source code to OpenSSL and build
48b74fc… wyoung 84 Fossil against that private version of OpenSSL:
062d2bf… wyoung 85
062d2bf… wyoung 86 <pre>
1e0c0d0… wyoung 87 cd compat # relative to the Fossil source tree root
1e0c0d0… wyoung 88 tar xf /path/to/openssl-*.tar.gz
1e0c0d0… wyoung 89 ln -fs openssl-x.y.z openssl
1e0c0d0… wyoung 90 cd openssl
1e0c0d0… wyoung 91 ./config # or, e.g. ./Configure darwin64-x86_64-cc
1e0c0d0… wyoung 92 make -j11
1e0c0d0… wyoung 93 cd ../..
1e0c0d0… wyoung 94 ./configure --with-openssl=tree
1e0c0d0… wyoung 95 make -j11
062d2bf… wyoung 96 </pre>
062d2bf… wyoung 97
062d2bf… wyoung 98 That will get you a Fossil binary statically linked to this in-tree
062d2bf… wyoung 99 version of OpenSSL.
062d2bf… wyoung 100
a13820d… wyoung 101 Beware, taking this path typically opens you up to new problems, which
a13820d… wyoung 102 are conveniently covered in the next section!
a13820d… wyoung 103
062d2bf… wyoung 104
062d2bf… wyoung 105 <h3 id="certs">Certificates</h3>
062d2bf… wyoung 106
062d2bf… wyoung 107 To verify the identify of a server, TLS uses
b3c0c07… wyoung 108 [https://en.wikipedia.org/wiki/X.509#Certificates|X.509 certificates], a
b3c0c07… wyoung 109 scheme that depends on a trust hierarchy of so-called
b3c0c07… wyoung 110 [https://en.wikipedia.org/wiki/Certificate_authority | Certificate
b3c0c07… wyoung 111 Authorities]. The tree of trust relationships ultimately ends in the
b3c0c07… wyoung 112 CA roots, which are considered the ultimate arbiters of who to trust in
b3c0c07… wyoung 113 this scheme.
b3c0c07… wyoung 114
b3c0c07… wyoung 115 The question then is, what CA roots does Fossil trust?
062d2bf… wyoung 116
b3c0c07… wyoung 117 If you are using a self-signed certificate, Fossil will initially not
b3c0c07… wyoung 118 know that it can trust your certificate, so you'll be asked if you want
062d2bf… wyoung 119 to accept the certificate the first time you communicate with the
062d2bf… wyoung 120 server. Verify the certificate fingerprint is correct, then answer
b3c0c07… wyoung 121 "always" if you want Fossil to remember your decision.
062d2bf… wyoung 122
062d2bf… wyoung 123 If you are cloning from or syncing to Fossil servers that use a
b3c0c07… wyoung 124 certificate signed by a well-known CA or one of its delegates, Fossil
3c0565a… wyoung 125 still has to know which CA roots to trust. When this fails, you get an
ad47a44… wyoung 126 error message that looks like this:
3c0565a… wyoung 127
3c0565a… wyoung 128 <pre>
1e0c0d0… wyoung 129 Unable to verify SSL cert from fossil-scm.org
1e0c0d0… wyoung 130 subject: CN = sqlite.org
1e0c0d0… wyoung 131 issuer: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
1e0c0d0… wyoung 132 sha256: bf26092dd97df6e4f7bf1926072e7e8d200129e1ffb8ef5276c1e5dd9bc95d52
1e0c0d0… wyoung 133 accept this cert and continue (y/N)?
3c0565a… wyoung 134 </pre>
3c0565a… wyoung 135
3c0565a… wyoung 136 In older versions, the message was much longer and began with this line:
b3c0c07… wyoung 137
b3c0c07… wyoung 138 <pre>
1e0c0d0… wyoung 139 SSL verification failed: unable to get local issuer certificate
b3c0c07… wyoung 140 </pre>
b3c0c07… wyoung 141
b3c0c07… wyoung 142 Fossil relies on the OpenSSL library to have some way to check a trusted
b3c0c07… wyoung 143 list of CA signing keys. There are two common ways this fails:
b3c0c07… wyoung 144
1fd407f… wyoung 145 # The OpenSSL library Fossil is linked to doesn't have a CA
062d2bf… wyoung 146 signing key set at all, so that it initially trusts no certificates
1fd407f… wyoung 147 at all.
1fd407f… wyoung 148
1fd407f… wyoung 149 # The OpenSSL library does have a CA cert set, but your Fossil server's
1fd407f… wyoung 150 TLS certificate was signed by a CA that isn't in that set.
062d2bf… wyoung 151
062d2bf… wyoung 152 A common reason to fall into the second trap is that you're using
062d2bf… wyoung 153 certificates signed by a local private CA, as often happens in large
062d2bf… wyoung 154 enterprises. You can solve this sort of problem by getting your local
062d2bf… wyoung 155 CA's signing certificate in PEM format and pointing OpenSSL at it:
062d2bf… wyoung 156
062d2bf… wyoung 157 <pre>
1e0c0d0… wyoung 158 fossil set --global ssl-ca-location /path/to/local-ca.pem
062d2bf… wyoung 159 </pre>
062d2bf… wyoung 160
062d2bf… wyoung 161 The use of <tt>--global</tt> with this option is common, since you may
e755561… danield 162 have multiple repositories served under certificates signed by that same
b3c0c07… wyoung 163 CA. However, if you have a mix of publicly-signed and locally-signed
b3c0c07… wyoung 164 certificates, you might want to drop the <tt>--global</tt> flag and set
b3c0c07… wyoung 165 this option on a per-repository basis instead.
062d2bf… wyoung 166
062d2bf… wyoung 167 A common way to run into the broader first problem is that you're on
062d2bf… wyoung 168 FreeBSD, which does not install a CA certificate set by default, even as
062d2bf… wyoung 169 a dependency of the OpenSSL library. If you're using a certificate
062d2bf… wyoung 170 signed by one of the major public CAs, you can solve this by installing
062d2bf… wyoung 171 the <tt>ca_root_nss</tt> package. That package contains the Mozilla NSS
062d2bf… wyoung 172 certificate bundle, which gets installed in a location that OpenSSL
062d2bf… wyoung 173 checks by default, so you don't need to change any Fossil settings.
062d2bf… wyoung 174 (This is the same certificate set that ships with Firefox, by the way.)
062d2bf… wyoung 175
062d2bf… wyoung 176 The same sort of thing happens with the Windows build of OpenSSL, but
062d2bf… wyoung 177 for a different core reason: Windows does ship with a stock CA
062d2bf… wyoung 178 certificate set, but it's not in a format that OpenSSL understands how
062d2bf… wyoung 179 to use. Rather than try to find a way to convert the data format, you
062d2bf… wyoung 180 may find it acceptable to use the same Mozilla NSS cert set. I do not
062d2bf… wyoung 181 know of a way to easily get this from Mozilla themselves, but I did find
af7bbdc… wyoung 182 a [https://curl.se/docs/caextract.html | third party source] for the
b3c0c07… wyoung 183 <tt>cacert.pem</tt> file. I suggest placing the file into your Windows
b3c0c07… wyoung 184 user home directory so that you can then point Fossil at it like so:
c563be1… wyoung 185
c563be1… wyoung 186 <pre>
1e0c0d0… wyoung 187 fossil set --global ssl-ca-location %userprofile%\cacert.pem
c563be1… wyoung 188 </pre>
c563be1… wyoung 189
c563be1… wyoung 190 This can also happen if you've linked Fossil to a version of OpenSSL
3982569… wyoung 191 [#openssl-src|built from source]. That same <tt>cacert.pem</tt> fix can
3982569… wyoung 192 work in that case, too.
b8b22d7… florian 193
b8b22d7… florian 194 <blockquote>
b8b22d7… florian 195 OpenSSL 3.2.0 or greater is able to use the stock CA certificates
b8b22d7… florian 196 managed by Windows, and Fossil 2.25 (still in development as of
b8b22d7… florian 197 2024-07-15) takes advantage of this feature. This <em>possibly</em>
b8b22d7… florian 198 eliminates the need to manually install the Mozilla certificate package,
b8b22d7… florian 199 for example when connecting to Fossil servers secured by the widely-used
b8b22d7… florian 200 Let's Encrypt certificates. Run the following command to check if the
b8b22d7… florian 201 feature is supported:
b8b22d7… florian 202
b8b22d7… florian 203 <pre>
b8b22d7… florian 204 fossil tls-config show -v
b8b22d7… florian 205 </pre>
b8b22d7… florian 206
b8b22d7… florian 207 (See the "OpenSSL-winstore" section, requires Fossil 2.25 or greater.)
b8b22d7… florian 208 </blockquote>
ad47a44… wyoung 209
c563be1… wyoung 210 When you build Fossil on Linux platforms against the binary OpenSSL
c563be1… wyoung 211 package provided with the OS, you typically get a root cert store along
c563be1… wyoung 212 with the platform OpenSSL package, either built-in or as a hard
c563be1… wyoung 213 dependency.
062d2bf… wyoung 214
062d2bf… wyoung 215
062d2bf… wyoung 216 <h4>Client-Side Certificates</h4>
062d2bf… wyoung 217
062d2bf… wyoung 218 You can also use client side certificates to add an extra layer of
062d2bf… wyoung 219 authentication, over and above Fossil's built in user management. If you
062d2bf… wyoung 220 are particularly paranoid, you'll want to use this to remove the ability
062d2bf… wyoung 221 of anyone on the internet from making any request to Fossil. Without
062d2bf… wyoung 222 presenting a valid client side certificate, the web server won't invoke
062d2bf… wyoung 223 the Fossil CGI handler.
062d2bf… wyoung 224
062d2bf… wyoung 225 Configure your server to request a client side certificate, and set up a
062d2bf… wyoung 226 certificate authority to sign your client certificates. For each person
062d2bf… wyoung 227 who needs to access the repository, create a private key and certificate
062d2bf… wyoung 228 signed with that CA.
062d2bf… wyoung 229
062d2bf… wyoung 230 The PEM encoded private key and certificate should be stored in a single
062d2bf… wyoung 231 file, simply by concatenating the key and certificate files. Specify the
062d2bf… wyoung 232 location of this file with the <tt>ssl-identity</tt> setting, or the
062d2bf… wyoung 233 <tt>--ssl-identity</tt> option to the <tt>clone</tt> command.
062d2bf… wyoung 234
062d2bf… wyoung 235 If you've password protected the private key, the password will be
062d2bf… wyoung 236 requested every time you connect to the server. This password is not
062d2bf… wyoung 237 stored by fossil, as doing so would defeat the purpose of having a
062d2bf… wyoung 238 password.
062d2bf… wyoung 239
062d2bf… wyoung 240 If you attempt to connect to a server which requests a client
062d2bf… wyoung 241 certificate, but don't provide one, fossil will show an error message
062d2bf… wyoung 242 which explains what to do to authenticate with the server.
062d2bf… wyoung 243
062d2bf… wyoung 244
27458ef… wyoung 245 <h2 id="server">Server-Side Configuration</h2>
27458ef… wyoung 246
ad47a44… wyoung 247 Before Fossil's built-in HTTP server gained [./ssl-server.md | TLS support],
ad47a44… wyoung 248 system administrators that wanted to add this
27458ef… wyoung 249 had to put it behind a reverse proxy that would do the translation.
27458ef… wyoung 250 Since advantages remain for delegating TLS to another layer in the
27458ef… wyoung 251 stack, instructions for doing so continue to be included in our
27458ef… wyoung 252 documentation, such as:
f146e21… drh 253
f146e21… drh 254 * <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
f146e21… drh 255 * <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
08c52c3… wyoung 256 * <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
062d2bf… wyoung 257
062d2bf… wyoung 258
062d2bf… wyoung 259 <h2 id="enforcing">Enforcing TLS Access</h2>
062d2bf… wyoung 260
062d2bf… wyoung 261 To use TLS encryption in cloning and syncing to a remote Fossil
062d2bf… wyoung 262 repository, be sure to use the <tt>https:</tt> URI scheme in
062d2bf… wyoung 263 <tt>clone</tt> and <tt>sync</tt> commands. If your server is configured
062d2bf… wyoung 264 to serve the repository via both HTTP and HTTPS, it's easy to
062d2bf… wyoung 265 accidentally use unencrypted HTTP if you forget the all-important 's'.
6b472ae… wyoung 266
6b472ae… wyoung 267 As of Fossil 2.9, using an <tt>http://</tt> URI with <tt>fossil
6b472ae… wyoung 268 clone</tt> or <tt>sync</tt> on a site that forwards to HTTPS will cause
6b472ae… wyoung 269 Fossil to remember the secure URL. However, there's a
6b472ae… wyoung 270 [https://en.wikipedia.org/wiki/Trust_on_first_use | TOFU problem] with
6b472ae… wyoung 271 this: it's still better to use <tt>https://</tt> from the start.
226b14f… wyoung 272
226b14f… wyoung 273 As of Fossil 2.8, there is a setting in the Fossil UI under Admin &rarr;
226b14f… wyoung 274 Access called "Redirect to HTTPS," which is set to "Off" by default.
226b14f… wyoung 275 Changing this only affects web UI access to the Fossil repository. It
226b14f… wyoung 276 doesn't affect clones and syncs done via the <tt>http</tt> URI scheme.
226b14f… wyoung 277
226b14f… wyoung 278 In Fossil 2.7 and earlier, there was a much weaker form of this setting
226b14f… wyoung 279 affecting the <tt>/login</tt> page only. If you're using this setting,
226b14f… wyoung 280 you should migrate to the new setting as soon as possible, because the
226b14f… wyoung 281 old setting allows multiple ways of defeating it.
226b14f… wyoung 282
226b14f… wyoung 283 <b id="rloop">WARNING:</b> Enabling HTTPS redirects at the Fossil repo
226b14f… wyoung 284 level while running Fossil behind an HTTPS proxy can result in an
226b14f… wyoung 285 infinite redirect loop. It happens when the proxy mechanism presents
485eda7… wyoung 286 "<tt>http</tt>" URIs to Fossil, so Fossil issues a redirect, so the browser
485eda7… wyoung 287 fetches the page again, causing Fossil to see an "<tt>http</tt>" URI again, so
226b14f… wyoung 288 it issues a redirect...'round and 'round it goes until the web browser
226b14f… wyoung 289 detects it's in a redirect loop and gives up. This problem prevents you
226b14f… wyoung 290 from getting back into the Admin UI to fix it, but there are several
226b14f… wyoung 291 ways to fix it:
226b14f… wyoung 292
1fd407f… wyoung 293 # <b>Reset via CLI.</b> You can turn the setting back off from the
226b14f… wyoung 294 CLI with the command "<tt>fossil -R /path/to/repo.fossil set
1fd407f… wyoung 295 redirect-to-https 0</tt>". (Currently doesn't work.)
1fd407f… wyoung 296
1fd407f… wyoung 297 # <b>Backup first.</b> This setting is stored in the Fossil
226b14f… wyoung 298 repository, so if you make a backup first <i>on the server</i>, you
226b14f… wyoung 299 can restore the repo file if enabling this feature creates a
1fd407f… wyoung 300 redirect loop.
1fd407f… wyoung 301
1fd407f… wyoung 302 # <b>Download, fix, and restore.</b> You can copy the remote
226b14f… wyoung 303 repository file down to a local machine, use <tt>fossil ui</tt> to
226b14f… wyoung 304 fix the setting, and then upload it to the repository server
1fd407f… wyoung 305 again.
226b14f… wyoung 306
226b14f… wyoung 307 It's best to enforce TLS-only access at the front-end proxy level
226b14f… wyoung 308 anyway. It not only avoids the problem entirely, it can be significantly
27458ef… wyoung 309 more secure. The [./server/debian/nginx.md#tls | nginx-on-Debian proxy guide] shows one way
1fd407f… wyoung 310 to achieve this.
062d2bf… wyoung 311
062d2bf… wyoung 312
062d2bf… wyoung 313 <h2>Terminology Note</h2>
062d2bf… wyoung 314
062d2bf… wyoung 315 This document is called <tt>ssl.wiki</tt> for historical reasons. The
062d2bf… wyoung 316 TLS protocol was originally called SSL, and it went through several
062d2bf… wyoung 317 revisions before being replaced by TLS. Years before this writing, SSL
062d2bf… wyoung 318 finally became entirely obsolete due to weaknesses in the protocol fixed
062d2bf… wyoung 319 in the later TLS series of protocols.
062d2bf… wyoung 320
062d2bf… wyoung 321 Some people still use the term "SSL" when they actually mean "TLS," but
062d2bf… wyoung 322 in the Fossil project, we always use "TLS" except when we must preserve
062d2bf… wyoung 323 some sort of historical compatibility, as with this document's name in
062d2bf… wyoung 324 order to avoid broken external URLs. The Fossil TLS-related settings
27458ef… wyoung 325 also often use "<tt>ssl</tt>" in their names for the same reason.
062d2bf… wyoung 326
062d2bf… wyoung 327 This series of protocols is also called "HTTPS" after the URI scheme
062d2bf… wyoung 328 used to specify "HTTP over TLS."

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button