mirror of
https://github.com/restic/rest-server.git
synced 2025-10-19 07:33:21 +00:00
Require auth by default, add --no-auth flag
In order to prevent users from accidentally exposing rest-server without authentication, rest-server now defaults to requiring a .htpasswd. If you want to disable authentication, you need to explicitly pass the new --no-auth flag.
This commit is contained in:
parent
02196a18d8
commit
4d2493388a
4 changed files with 72 additions and 13 deletions
11
README.md
11
README.md
|
@ -67,6 +67,7 @@ Flags:
|
||||||
-h, --help help for rest-server
|
-h, --help help for rest-server
|
||||||
--listen string listen address (default ":8000")
|
--listen string listen address (default ":8000")
|
||||||
--log string log HTTP requests in the combined log format
|
--log string log HTTP requests in the combined log format
|
||||||
|
--no-auth disable .htpasswd authentication
|
||||||
--path string data directory (default "/tmp/restic")
|
--path string data directory (default "/tmp/restic")
|
||||||
--private-repos users can only access their private repo
|
--private-repos users can only access their private repo
|
||||||
--prometheus enable Prometheus metrics
|
--prometheus enable Prometheus metrics
|
||||||
|
@ -77,20 +78,22 @@ Flags:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
By default the server persists backup data in `/tmp/restic`. Start the server with a custom persistence directory:
|
By default the server persists backup data in `/tmp/restic`. To start the server with a custom persistence directory and with authentication disabled:
|
||||||
|
|
||||||
```
|
```
|
||||||
rest-server --path /user/home/backup
|
rest-server --path /user/home/backup --no-auth
|
||||||
```
|
```
|
||||||
|
|
||||||
To authenticate users (for access to the rest-server), the server supports using a `.htpasswd` file to specify users. You can create such a file at the root of the persistence directory by executing the following command (note that you need the `htpasswd` program from Apache's http-tools). In order to append new user to the file, just omit the `-c` argument. Only bcrypt and SHA encryption methods are supported, so use -B (very secure) or -s (insecure by today's standards) when adding/changing passwords.
|
To authenticate users (for access to the rest-server), the server supports using a `.htpasswd` file to specify users. You can create such a file at the root of the persistence directory by executing the following command (note that you need the `htpasswd` program from Apache's http-tools). In order to append new user to the file, just omit the `-c` argument. Only bcrypt and SHA encryption methods are supported, so use -B (very secure) or -s (insecure by today's standards) when adding/changing passwords.
|
||||||
|
|
||||||
NOTE: Without a valid `.htaccess` file, the server will not authenticate users (it prints "Authentication disabled upon startup"), in which case anyone who can access the server will be able to back up to it.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
htpasswd -B -c .htpasswd username
|
htpasswd -B -c .htpasswd username
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to disable authentication, you must add the `--no-auth` flag. If this flag is not specified and the `.htpasswd` cannot be opened, rest-server will refuse to start.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, username and passwords will travel in cleartext 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`.
|
By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, username and passwords will travel in cleartext 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`.
|
||||||
|
|
||||||
Signed certificate is required by the restic backend, but if you just want to test the feature you can generate unsigned keys with the following commands:
|
Signed certificate is required by the restic backend, but if you just want to test the feature you can generate unsigned keys with the following commands:
|
||||||
|
|
|
@ -35,6 +35,7 @@ func init() {
|
||||||
flags.BoolVar(&restserver.Config.TLS, "tls", restserver.Config.TLS, "turn on TLS support")
|
flags.BoolVar(&restserver.Config.TLS, "tls", restserver.Config.TLS, "turn on TLS support")
|
||||||
flags.StringVar(&restserver.Config.TLSCert, "tls-cert", restserver.Config.TLSCert, "TLS certificate path")
|
flags.StringVar(&restserver.Config.TLSCert, "tls-cert", restserver.Config.TLSCert, "TLS certificate path")
|
||||||
flags.StringVar(&restserver.Config.TLSKey, "tls-key", restserver.Config.TLSKey, "TLS key path")
|
flags.StringVar(&restserver.Config.TLSKey, "tls-key", restserver.Config.TLSKey, "TLS key path")
|
||||||
|
flags.BoolVar(&restserver.Config.NoAuth, "no-auth", restserver.Config.NoAuth, "disable .htpasswd authentication")
|
||||||
flags.BoolVar(&restserver.Config.AppendOnly, "append-only", restserver.Config.AppendOnly, "enable append only mode")
|
flags.BoolVar(&restserver.Config.AppendOnly, "append-only", restserver.Config.AppendOnly, "enable append only mode")
|
||||||
flags.BoolVar(&restserver.Config.PrivateRepos, "private-repos", restserver.Config.PrivateRepos, "users can only access their private repo")
|
flags.BoolVar(&restserver.Config.PrivateRepos, "private-repos", restserver.Config.PrivateRepos, "users can only access their private repo")
|
||||||
flags.BoolVar(&restserver.Config.Prometheus, "prometheus", restserver.Config.Prometheus, "enable Prometheus metrics")
|
flags.BoolVar(&restserver.Config.Prometheus, "prometheus", restserver.Config.Prometheus, "enable Prometheus metrics")
|
||||||
|
@ -64,6 +65,21 @@ func tlsSettings() (bool, string, string, error) {
|
||||||
return enabledTLS, key, cert, nil
|
return enabledTLS, key, cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getHandler() (http.Handler, error) {
|
||||||
|
mux := restserver.NewMux()
|
||||||
|
if restserver.Config.NoAuth {
|
||||||
|
log.Println("Authentication disabled")
|
||||||
|
return mux, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Authentication enabled")
|
||||||
|
htpasswdFile, err := restserver.NewHtpasswdFromFile(filepath.Join(restserver.Config.Path, ".htpasswd"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot load .htpasswd (use --no-auth to disable): %v", err)
|
||||||
|
}
|
||||||
|
return restserver.AuthHandler(htpasswdFile, mux), nil
|
||||||
|
}
|
||||||
|
|
||||||
func runRoot(cmd *cobra.Command, args []string) error {
|
func runRoot(cmd *cobra.Command, args []string) error {
|
||||||
if restserver.Config.Version {
|
if restserver.Config.Version {
|
||||||
fmt.Printf("rest-server %s compiled with %v on %v/%v\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
fmt.Printf("rest-server %s compiled with %v on %v/%v\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||||
|
@ -86,16 +102,9 @@ func runRoot(cmd *cobra.Command, args []string) error {
|
||||||
defer pprof.StopCPUProfile()
|
defer pprof.StopCPUProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
mux := restserver.NewMux()
|
handler, err := getHandler()
|
||||||
|
|
||||||
var handler http.Handler
|
|
||||||
htpasswdFile, err := restserver.NewHtpasswdFromFile(filepath.Join(restserver.Config.Path, ".htpasswd"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler = mux
|
log.Fatalf("error: %v", err)
|
||||||
log.Println("Authentication disabled")
|
|
||||||
} else {
|
|
||||||
handler = restserver.AuthHandler(htpasswdFile, mux)
|
|
||||||
log.Println("Authentication enabled")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if restserver.Config.PrivateRepos {
|
if restserver.Config.PrivateRepos {
|
||||||
|
@ -122,6 +131,7 @@ func runRoot(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := cmdRoot.Execute(); err != nil {
|
if err := cmdRoot.Execute(); err != nil {
|
||||||
log.Fatalf("error: %v", err)
|
log.Fatalf("error: %v", err)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
restserver "github.com/restic/rest-server"
|
restserver "github.com/restic/rest-server"
|
||||||
|
@ -71,3 +74,45 @@ func TestTLSSettings(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetHandler(t *testing.T) {
|
||||||
|
// Save and restore config
|
||||||
|
defaultConfig := restserver.Config
|
||||||
|
defer func() { restserver.Config = defaultConfig }()
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "rest-server-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(dir)
|
||||||
|
restserver.Config.Path = dir
|
||||||
|
|
||||||
|
// With NoAuth = false and no .htpasswd
|
||||||
|
restserver.Config.NoAuth = false // default
|
||||||
|
_, err = getHandler()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("NoAuth=false: expected error, got nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// With NoAuth = true and no .htpasswd
|
||||||
|
restserver.Config.NoAuth = true
|
||||||
|
_, err = getHandler()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("NoAuth=true: expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create .htpasswd
|
||||||
|
htpasswd := filepath.Join(dir, ".htpasswd")
|
||||||
|
err = ioutil.WriteFile(htpasswd, []byte(""), 0644)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(htpasswd)
|
||||||
|
|
||||||
|
// With NoAuth = false and with .htpasswd
|
||||||
|
restserver.Config.NoAuth = false // default
|
||||||
|
_, err = getHandler()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("NoAuth=false with .htpasswd: expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
mux.go
1
mux.go
|
@ -21,6 +21,7 @@ var Config = struct {
|
||||||
TLSKey string
|
TLSKey string
|
||||||
TLSCert string
|
TLSCert string
|
||||||
TLS bool
|
TLS bool
|
||||||
|
NoAuth bool
|
||||||
AppendOnly bool
|
AppendOnly bool
|
||||||
PrivateRepos bool
|
PrivateRepos bool
|
||||||
Prometheus bool
|
Prometheus bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue