Fossil SCM

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

Keyboard Shortcuts

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