Skip to content

Commit

Permalink
generate random keys
Browse files Browse the repository at this point in the history
  • Loading branch information
creativeprojects committed Jul 17, 2020
1 parent 67e24a4 commit fce69a1
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
54 changes: 40 additions & 14 deletions README.md
Expand Up @@ -14,20 +14,21 @@ With resticprofile:
* You can run the forget command before or after a backup (in a section called *retention*)
* You can check a repository before or after a backup
* You can create groups of profiles that will run sequentially
* You can run shell commands before or after a backup
* You can also run shell commands before or after running a profile (any command): useful if you need to mount your backup disk
* You can run shell commands before or after running a profile: useful if you need to mount and unmount your backup disk for example
* You can run a shell command if an error occurred (at any time)
* You can send a backup stream via _stdin_
* You can start restic at a lower or higher priority (Priority Class in Windows, *nice* in all unixes) and/or _ionice_ (only available on Linux)
* Check you have enough memory before starting a backup. (I've had some backups that literally killed a server with swap disabled)
* It can check that you have enough memory before starting a backup. (I've had some backups that literally killed a server with swap disabled)
* **[new for v0.9.0]** You can easily schedule backups, retentions and checks (works for *systemd*, *launchd* and *windows task scheduler*)
* You can generate cryptographically secure random keys to use as a restic key file

The configuration file accepts various formats:
* [TOML](https://github.com/toml-lang/toml) : configuration file with extension _.toml_ and _.conf_ to keep compatibility with versions before 0.6.0
* [JSON](https://en.wikipedia.org/wiki/JSON) : configuration file with extension _.json_
* [YAML](https://en.wikipedia.org/wiki/YAML) : configuration file with extension _.yaml_
* [HCL](https://github.com/hashicorp/hcl): configuration file with extension _.hcl_

For the rest of the documentation, I'll be showing examples using the TOML file configuration format (because it was the only one supported before version 0.6.0) but you can pick your favourite: they all work with resticprofile :-)
For the rest of the documentation, I'll be mostly showing examples using the TOML file configuration format (because it was the only one supported before version 0.6.0) but you can pick your favourite: they all work with resticprofile.

# Table of Contents

Expand All @@ -50,9 +51,10 @@ For the rest of the documentation, I'll be showing examples using the TOML file
* [Using resticprofile](#using-resticprofile)
* [Command line reference](#command-line-reference)
* [Minimum memory required](#minimum-memory-required)
* [Generating random keys](#generating-random-keys)
* [Scheduled backups (please note this is work in progress for version 0\.9\.0)](#scheduled-backups-please-note-this-is-work-in-progress-for-version-090)
* [Schedule configuration](#schedule-configuration)
* [schedule\-type](#schedule-type)
* [schedule\-permission](#schedule-permission)
* [schedule](#schedule)
* [Scheduling commands](#scheduling-commands)
* [Configuration file reference](#configuration-file-reference)
Expand All @@ -61,9 +63,10 @@ For the rest of the documentation, I'll be showing examples using the TOML file
* [systemd calendars](#systemd-calendars)



## Requirements

Since version 0.6.0, **resticprofile** **no longer needs** python installed on your machine. It is distributed as an executable (same as restic).
Since version 0.6.0, resticprofile no longer needs python installed on your machine. It is distributed as an executable (same as restic).

It's been actively tested on macOS X and Linux, and regularly tested on Windows.

Expand Down Expand Up @@ -331,6 +334,7 @@ keep-within = "30d"
compact = false
prune = true

# check command of profile src
[src.check]
read-data = true
# if scheduled, will check the repository the first day of each month at 3am
Expand Down Expand Up @@ -513,13 +517,12 @@ resticprofile own commands:
self-update update resticprofile to latest version (does not update restic)
profiles display profile names from the configuration file
show show all the details of the current profile
random-key generate a cryptographically secure random key to use as a restic key file
schedule schedule a backup
unschedule remove a scheduled backup
status display the status of a scheduled backup job
```

A command is either a restic command or a resticprofile own command.
Expand Down Expand Up @@ -551,6 +554,25 @@ For that matter I've introduced a parameter in the `global` section called `min-

It compares against `(total - used)` which is probably the best way to know how much memory is available (that is including the memory used for disk buffers/cache).

## Generating random keys

resticprofile has a handy tool to generate cryptographically secure random keys encoded in base64. You can simply put this key into a file and use it as a strong key for restic

On Linux and FreeBSD, the generator uses getrandom(2) if available, /dev/urandom otherwise. On OpenBSD, the generator uses getentropy(2). On other Unix-like systems, the generator reads from /dev/urandom. On Windows systems, the generator uses the CryptGenRandom API. On Wasm, the generator uses the Web Crypto API.
[Reference from the Go documentation](https://golang.org/pkg/crypto/rand/#pkg-variables)

```
$ resticprofile random-key
```

generates a 1024 bytes random key (converted into 1368 base64 characters) and displays it on the console

To generate a different size of key, you can specify the bytes length on the command line:

```
$ resticprofile random-key 2048
```

## Scheduled backups (please note this is work in progress for version 0.9.0)

resticprofile is capable of managing scheduled backups for you:
Expand All @@ -569,25 +591,29 @@ which mean you can schedule backup, retention (`forget` command) and repository

### Schedule configuration

The schedule configuration consists on two parameters which can be added on each profile:
The schedule configuration consists of two parameters which can be added on each profile:

```ini
[profile.backup]
schedule-type = "system"
schedule-permission = "system"
schedule = "*:00,30"
```



#### schedule-type
#### schedule-permission

`schedule-permission` accepts two parameters: `user` or `system`:

* `user`: your backup will be running using your current user permissions on files. That's probably what you want if you're only saving your documents (or any other file inside your profile).

`schedule-type` accepts two parameters: `system` or `user`. You can always run the schedule commands for a user schedule, but your backup will be running using your current user permissions on files. That's probably what you want if you're only saving your documents (or any other file inside your profile).
* `system`: if you need to access some system or protected files. You will need to run resticprofile with `sudo` on unixes and with elevated prompt on Windows (please note on Windows resticprofile will ask you for elevated permissions automatically if needed)

If you need to access some system or protected files, set the `schedule-type` to `system`. You will need to run resticprofile with `sudo` on unixes and with elevated prompt on Windows (please note on Windows resticprofile will ask you for elevated permissions automatically if needed)
* *empty*: resticprofile will try its best guess based on how you started it (with sudo or as a normal user)

#### schedule

The `schedule` parameter accepts many forms of input from the [systemd calendar event](https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events) type. This is by far the easiest to use. **It is the same format used to schedule on macOS and Windows**.
The `schedule` parameter accepts many forms of input from the [systemd calendar event](https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events) type. This is by far the easiest to use: **It is the same format used to schedule on macOS and Windows**.

The most general form is:
```
Expand Down
36 changes: 36 additions & 0 deletions commands.go
@@ -1,11 +1,14 @@
package main

import (
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"os"
"runtime"
"sort"
"strconv"
"strings"
"text/tabwriter"

Expand Down Expand Up @@ -44,6 +47,12 @@ var (
action: showProfile,
needConfiguration: true,
},
{
name: "random-key",
description: "generate a cryptographically secure random key to use as a restic keyfile",
action: randomKey,
needConfiguration: false,
},
{
name: "schedule",
description: "schedule a backup",
Expand Down Expand Up @@ -197,6 +206,33 @@ func showProfile(c *config.Config, flags commandLineFlags, args []string) error
return nil
}

// randomKey simply display a base64'd random key to the console
func randomKey(c *config.Config, flags commandLineFlags, args []string) error {
var err error
size := uint64(1024)
// flags.resticArgs contain the command and the rest of the command line
if len(flags.resticArgs) > 1 {
// second parameter should be an integer
size, err = strconv.ParseUint(flags.resticArgs[1], 10, 32)
if err != nil {
return fmt.Errorf("cannot parse the key size: %w", err)
}
if size < 1 {
return fmt.Errorf("invalid key size: %v", size)
}
}
buffer := make([]byte, size)
_, err = rand.Read(buffer)
if err != nil {
return err
}
encoder := base64.NewEncoder(base64.StdEncoding, os.Stdout)
_, err = encoder.Write(buffer)
encoder.Close()
fmt.Println("")
return err
}

func createSchedule(c *config.Config, flags commandLineFlags, args []string) error {
// If this is running in elevated mode we'll need to send a finished signal
if flags.isChild {
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Expand Up @@ -41,8 +41,6 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creativeprojects/clog v0.0.1 h1:eSZmosNvSnBi5njTlm/hLFhpliMIA/FPmhdwUH0or2E=
github.com/creativeprojects/clog v0.0.1/go.mod h1:ePe00iA7srKh7dcFksHHIGEeRjLmiXvk1afuDXw+CN4=
github.com/creativeprojects/clog v0.1.0 h1:ECX/W0MldH+R3xqYtMFr9tfkw1RWNoWyqtcO/x4z9Co=
github.com/creativeprojects/clog v0.1.0/go.mod h1:ePe00iA7srKh7dcFksHHIGEeRjLmiXvk1afuDXw+CN4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down

0 comments on commit fce69a1

Please sign in to comment.