Skip to content

Commit 446e9ee

Browse files
committed
Implement TLS client authentication
1 parent ad130de commit 446e9ee

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Kenny Keslar <r3dey3@r3dey3.com>
1010
Konrad Wojas <github@m.wojas.nl>
1111
Matthew Holt <mholt@users.noreply.github.com>
1212
Mebus <mebus.inbox@googlemail.com>
13+
Michael Zimmermann <sigmaepsilon92@gmail.com>
1314
Wayne Scott <wsc9tt@gmail.com>
1415
Zlatko Čalušić <zcalusic@bitsync.net>
1516
cgonzalez <chgonzalezg@gmail.com>

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Usage:
3232
rest-server [flags]
3333

3434
Flags:
35+
<<<<<<< HEAD
3536
--append-only enable append only mode
3637
--cpu-profile string write CPU profile to file
3738
--debug output debug messages
@@ -53,6 +54,27 @@ Flags:
5354
--tls-key string TLS key path
5455
--tls-min-ver string TLS min version, one of (1.2|1.3) (default "1.2")
5556
-v, --version version for rest-server
57+
=======
58+
--append-only enable append only mode
59+
--cpu-profile string write CPU profile to file
60+
--debug output debug messages
61+
-h, --help help for rest-server
62+
--htpasswd-file string location of .htpasswd file (default: "<data directory>/.htpasswd")
63+
--listen string listen address (default ":8000")
64+
--log filename write HTTP requests in the combined log format to the specified filename
65+
--max-size int the maximum size of the repository in bytes
66+
--no-auth disable .htpasswd authentication
67+
--no-verify-upload do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device
68+
--path string data directory (default "/tmp/restic")
69+
--private-repos users can only access their private repo
70+
--prometheus enable Prometheus metrics
71+
--prometheus-no-auth disable auth for Prometheus /metrics endpoint
72+
--tls turn on TLS support
73+
--tls-ca string TLS CA certificate path
74+
--tls-cert string TLS certificate path
75+
--tls-key string TLS key path
76+
-v, --version version for rest-server
77+
>>>>>>> a806291 (Implement TLS client authentication)
5678
```
5779

5880
By default the server persists backup data in the OS temporary directory (`/tmp/restic` on Linux/BSD and others, in `%TEMP%\\restic` in Windows, etc). **If `rest-server` is launched using the default path, all backups will be lost**. To start the server with a custom persistence directory and with authentication disabled:
@@ -71,7 +93,7 @@ If you want to disable authentication, you must add the `--no-auth` flag. If thi
7193

7294
NOTE: In older versions of rest-server (up to 0.9.7), this flag does not exist and the server disables authentication if `.htpasswd` is missing or cannot be opened.
7395

74-
By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, user name and passwords will be sent in clear text in every request. In order to enable TLS support just add the `--tls` argument and add a private and public key at the root of your persistence directory. You may also specify private and public keys by `--tls-cert` and `--tls-key` and set the minimum TLS version to 1.3 using `--tls-min-ver 1.3`.
96+
By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, user name and passwords will be sent in clear text in every request. In order to enable TLS support just add the `--tls` argument and add a private and public key at the root of your persistence directory. You may also specify private and public keys by `--tls-cert` and `--tls-key` and set the minimum TLS version to 1.3 using `--tls-min-ver 1.3`. Additionally, client authentication can be enabled by passing a CA certificate to `--tls-cacert`.
7597

7698
Signed certificate is normally required by the restic backend, but if you just want to test the feature you can generate password-less unsigned keys with the following command:
7799

changelog/unreleased/issue-73

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Enhancement: TLS Client Authentication
2+
3+
It is now possible to require clients to provide a certificate that was signed
4+
by a certain CA.
5+
6+
https://github.com/restic/rest-server/issues/73
7+
https://github.com/restic/rest-server/pull/193

cmd/rest-server/main.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package main
33
import (
44
"context"
55
"crypto/tls"
6+
"crypto/x509"
67
"errors"
78
"fmt"
9+
"io/ioutil"
810
"log"
911
"net"
1012
"net/http"
@@ -61,6 +63,7 @@ func newRestServerApp() *restServerApp {
6163
flags.Int64Var(&rv.Server.MaxRepoSize, "max-size", rv.Server.MaxRepoSize, "the maximum size of the repository in bytes")
6264
flags.StringVar(&rv.Server.Path, "path", rv.Server.Path, "data directory")
6365
flags.BoolVar(&rv.Server.TLS, "tls", rv.Server.TLS, "turn on TLS support")
66+
flags.StringVar(&rv.Server.TLSCACert, "tls-cacert", rv.Server.TLSCACert, "TLS CA certificate path")
6467
flags.StringVar(&rv.Server.TLSCert, "tls-cert", rv.Server.TLSCert, "TLS certificate path")
6568
flags.StringVar(&rv.Server.TLSKey, "tls-key", rv.Server.TLSKey, "TLS key path")
6669
flags.StringVar(&rv.Server.TLSMinVer, "tls-min-ver", rv.Server.TLSMinVer, "TLS min version, one of (1.2|1.3)")
@@ -199,6 +202,20 @@ func (app *restServerApp) runRoot(_ *cobra.Command, _ []string) error {
199202
return fmt.Errorf("Unsupported TLS min version: %s. Allowed versions are 1.2 or 1.3", app.Server.TLSMinVer)
200203
}
201204

205+
if app.Server.TLSCACert != "" {
206+
log.Printf("TLS Client Authentication enabled, CA cert %s", app.Server.TLSCACert)
207+
208+
caCert, err := ioutil.ReadFile(app.Server.TLSCACert)
209+
if err != nil {
210+
return fmt.Errorf("unable to read CA certificate: %w", err)
211+
}
212+
caCertPool := x509.NewCertPool()
213+
caCertPool.AppendCertsFromPEM(caCert)
214+
215+
tlscfg.ClientAuth = tls.RequireAndVerifyClientCert
216+
tlscfg.ClientCAs = caCertPool
217+
}
218+
202219
srv := &http.Server{
203220
Handler: handler,
204221
TLSConfig: tlscfg,

handlers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type Server struct {
2020
Listen string
2121
Log string
2222
CPUProfile string
23+
TLSCACert string
2324
TLSKey string
2425
TLSCert string
2526
TLSMinVer string

0 commit comments

Comments
 (0)