Skip to content

Commit 0171dcf

Browse files
committed
Implement TLS client authentication
1 parent ad130de commit 0171dcf

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Kenny Keslar <[email protected]>
1010
Konrad Wojas <[email protected]>
1111
Matthew Holt <[email protected]>
1212
13+
Michael Zimmermann <[email protected]>
1314
Wayne Scott <[email protected]>
1415
Zlatko Čalušić <[email protected]>
1516
cgonzalez <[email protected]>

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Flags:
4949
--prometheus-no-auth disable auth for Prometheus /metrics endpoint
5050
--proxy-auth-username string specifies the HTTP header containing the username for proxy-based authentication
5151
--tls turn on TLS support
52+
--tls-ca string TLS CA certificate path
5253
--tls-cert string TLS certificate path
5354
--tls-key string TLS key path
5455
--tls-min-ver string TLS min version, one of (1.2|1.3) (default "1.2")
@@ -71,7 +72,7 @@ If you want to disable authentication, you must add the `--no-auth` flag. If thi
7172

7273
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.
7374

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`.
75+
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`.
7576

7677
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:
7778

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)