mirror of
https://github.com/offen/docker-volume-backup.git
synced 2025-02-23 00:20:23 +01:00
Support passing standard ssh keys to age encryption (#530)
* Support passing standard ssh keys to age encryption * Cover SSH keys in age test case
This commit is contained in:
parent
2652e05169
commit
cbbaa6ba7a
@ -10,8 +10,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
"filippo.io/age/agessh"
|
||||||
"github.com/ProtonMail/go-crypto/openpgp/armor"
|
"github.com/ProtonMail/go-crypto/openpgp/armor"
|
||||||
openpgp "github.com/ProtonMail/go-crypto/openpgp/v2"
|
openpgp "github.com/ProtonMail/go-crypto/openpgp/v2"
|
||||||
"github.com/offen/docker-volume-backup/internal/errwrap"
|
"github.com/offen/docker-volume-backup/internal/errwrap"
|
||||||
@ -73,7 +75,7 @@ func (s *script) getConfiguredAgeRecipients() ([]age.Recipient, error) {
|
|||||||
recipients := []age.Recipient{}
|
recipients := []age.Recipient{}
|
||||||
if len(s.c.AgePublicKeys) > 0 {
|
if len(s.c.AgePublicKeys) > 0 {
|
||||||
for _, pk := range s.c.AgePublicKeys {
|
for _, pk := range s.c.AgePublicKeys {
|
||||||
pkr, err := age.ParseX25519Recipient(pk)
|
pkr, err := parseAgeRecipient(pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errwrap.Wrap(err, "failed to parse age public key")
|
return nil, errwrap.Wrap(err, "failed to parse age public key")
|
||||||
}
|
}
|
||||||
@ -94,6 +96,18 @@ func (s *script) getConfiguredAgeRecipients() ([]age.Recipient, error) {
|
|||||||
return recipients, nil
|
return recipients, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseAgeRecipient(arg string) (age.Recipient, error) {
|
||||||
|
// This logic is adapted from what the age CLI is doing
|
||||||
|
// stripping some special cases
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(arg, "age1"):
|
||||||
|
return age.ParseX25519Recipient(arg)
|
||||||
|
case strings.HasPrefix(arg, "ssh-"):
|
||||||
|
return agessh.ParseRecipient(arg)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unknown recipient type: %q", arg)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *script) encryptWithAge(rec []age.Recipient) error {
|
func (s *script) encryptWithAge(rec []age.Recipient) error {
|
||||||
return s.doEncrypt("age", func(ciphertextWriter io.Writer) (io.WriteCloser, error) {
|
return s.doEncrypt("age", func(ciphertextWriter io.Writer) (io.WriteCloser, error) {
|
||||||
return age.Encrypt(ciphertextWriter, rec...)
|
return age.Encrypt(ciphertextWriter, rec...)
|
||||||
|
@ -358,8 +358,8 @@ You can populate below template according to your requirements and use it as you
|
|||||||
# AGE_PASSPHRASE="<xxx>"
|
# AGE_PASSPHRASE="<xxx>"
|
||||||
|
|
||||||
# Backups can be encrypted asymmetrically using age in case publickeys are given.
|
# Backups can be encrypted asymmetrically using age in case publickeys are given.
|
||||||
# Multiple keys need to be provided as a comma separated list. Right now, this only
|
# Multiple keys need to be provided as a comma separated list. Right now, this
|
||||||
# support passing age keys, with no support for ssh keys.
|
# supports `age` and `ssh` keys
|
||||||
|
|
||||||
# AGE_PUBLIC_KEYS="<xxx>"
|
# AGE_PUBLIC_KEYS="<xxx>"
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -27,6 +27,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
github.com/cloudflare/circl v1.3.7 // indirect
|
github.com/cloudflare/circl v1.3.7 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -35,6 +35,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
|||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o=
|
filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o=
|
||||||
filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004=
|
filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004=
|
||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 h1:1mvYtZfWQAnwNah/C+Z+Jb9rQH95LPE2vlmMuWAHJk8=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 h1:1mvYtZfWQAnwNah/C+Z+Jb9rQH95LPE2vlmMuWAHJk8=
|
||||||
|
@ -13,7 +13,10 @@ PK_A="$(grep -E 'public key' <"$LOCAL_DIR/pk-a.txt" | cut -d: -f2 | xargs)"
|
|||||||
age-keygen >"$LOCAL_DIR/pk-b.txt"
|
age-keygen >"$LOCAL_DIR/pk-b.txt"
|
||||||
PK_B="$(grep -E 'public key' <"$LOCAL_DIR/pk-b.txt" | cut -d: -f2 | xargs)"
|
PK_B="$(grep -E 'public key' <"$LOCAL_DIR/pk-b.txt" | cut -d: -f2 | xargs)"
|
||||||
|
|
||||||
export BACKUP_AGE_PUBLIC_KEYS="$PK_A,$PK_B"
|
ssh-keygen -t ed25519 -m pem -f "$LOCAL_DIR/id_ed25519" -C "docker-volume-backup@local"
|
||||||
|
PK_C="$(cat $LOCAL_DIR/id_ed25519.pub)"
|
||||||
|
|
||||||
|
export BACKUP_AGE_PUBLIC_KEYS="$PK_A,$PK_B,$PK_C"
|
||||||
|
|
||||||
docker compose up -d --quiet-pull
|
docker compose up -d --quiet-pull
|
||||||
sleep 5
|
sleep 5
|
||||||
@ -41,3 +44,4 @@ do_decrypt() {
|
|||||||
|
|
||||||
do_decrypt "$LOCAL_DIR/pk-a.txt"
|
do_decrypt "$LOCAL_DIR/pk-a.txt"
|
||||||
do_decrypt "$LOCAL_DIR/pk-b.txt"
|
do_decrypt "$LOCAL_DIR/pk-b.txt"
|
||||||
|
do_decrypt "$LOCAL_DIR/id_ed25519"
|
||||||
|
Loading…
Reference in New Issue
Block a user