Implement an append only mode.

This commit is contained in:
Kenny Keslar 2017-09-02 20:16:21 -05:00 committed by Zlatko Čalušić
parent cff373e8aa
commit 618b530b88
4 changed files with 18 additions and 0 deletions

View file

@ -43,6 +43,7 @@ Usage:
rest-server [flags] rest-server [flags]
Flags: Flags:
--append-only Enable append only mode
--cpuprofile string write CPU profile to file --cpuprofile string write CPU profile to file
--debug output debug messages --debug output debug messages
-h, --help help for rest-server -h, --help help for rest-server
@ -88,6 +89,9 @@ keys with the following commands:
% openssl req -new -x509 -key private_key -out public_key -days 365 % openssl req -new -x509 -key private_key -out public_key -days 365
``` ```
Append only mode allows creation of new backups but prevents deletion and modification of existing backups. This
can be useful when backing up systems that have a potential of being hacked.
Rest Server uses exactly the same directory structure as local backend, so you should be able to access it both locally Rest Server uses exactly the same directory structure as local backend, so you should be able to access it both locally
and via HTTP, even simultaneously. and via HTTP, even simultaneously.

View file

@ -29,6 +29,7 @@ func init() {
flags.StringVar(&restserver.Config.Log, "log", restserver.Config.Log, "log HTTP requests in the combined log format") flags.StringVar(&restserver.Config.Log, "log", restserver.Config.Log, "log HTTP requests in the combined log format")
flags.StringVar(&restserver.Config.Path, "path", restserver.Config.Path, "data directory") flags.StringVar(&restserver.Config.Path, "path", restserver.Config.Path, "data directory")
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.BoolVar(&restserver.Config.AppendOnly, "append-only", restserver.Config.AppendOnly, "Enable append only mode")
} }
var version = "manually" var version = "manually"

View file

@ -194,6 +194,12 @@ func DeleteConfig(w http.ResponseWriter, r *http.Request) {
if Config.Debug { if Config.Debug {
log.Println("DeleteConfig()") log.Println("DeleteConfig()")
} }
if Config.AppendOnly {
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return
}
cfg, err := getPath(r, "config") cfg, err := getPath(r, "config")
if err != nil { if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -372,6 +378,11 @@ func DeleteBlob(w http.ResponseWriter, r *http.Request) {
log.Println("DeleteBlob()") log.Println("DeleteBlob()")
} }
if Config.AppendOnly && pat.Param(r, "type") != "locks" {
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return
}
path, err := getFilePath(r, pat.Param(r, "type"), pat.Param(r, "name")) path, err := getFilePath(r, pat.Param(r, "type"), pat.Param(r, "name"))
if err != nil { if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

2
mux.go
View file

@ -18,9 +18,11 @@ var Config = struct {
Log string Log string
CPUProfile string CPUProfile string
Debug bool Debug bool
AppendOnly bool
}{ }{
Path: "/tmp/restic", Path: "/tmp/restic",
Listen: ":8000", Listen: ":8000",
AppendOnly: false,
} }
func debugHandler(next http.Handler) http.Handler { func debugHandler(next http.Handler) http.Handler {