github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarm-rafttool/common.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "github.com/coreos/etcd/pkg/fileutil" 11 "github.com/coreos/etcd/wal/walpb" 12 "github.com/docker/swarmkit/ca" 13 "github.com/docker/swarmkit/manager" 14 "github.com/docker/swarmkit/manager/encryption" 15 "github.com/docker/swarmkit/manager/state/raft/storage" 16 "github.com/docker/swarmkit/node" 17 ) 18 19 func certPaths(swarmdir string) *ca.SecurityConfigPaths { 20 return ca.NewConfigPaths(filepath.Join(swarmdir, "certificates")) 21 } 22 23 func getDEKData(krw *ca.KeyReadWriter) (manager.RaftDEKData, error) { 24 h, _ := krw.GetCurrentState() 25 dekData, ok := h.(manager.RaftDEKData) 26 if !ok { 27 return manager.RaftDEKData{}, errors.New("cannot read raft dek headers in TLS key") 28 } 29 30 if dekData.CurrentDEK == nil { 31 return manager.RaftDEKData{}, errors.New("no raft DEKs available") 32 } 33 34 return dekData, nil 35 } 36 37 func getKRW(swarmdir, unlockKey string) (*ca.KeyReadWriter, error) { 38 var ( 39 kek []byte 40 err error 41 ) 42 if unlockKey != "" { 43 kek, err = encryption.ParseHumanReadableKey(unlockKey) 44 if err != nil { 45 return nil, err 46 } 47 } 48 krw := ca.NewKeyReadWriter(certPaths(swarmdir).Node, kek, manager.RaftDEKData{}) 49 _, _, err = krw.Read() // loads all the key data into the KRW object 50 if err != nil { 51 return nil, err 52 } 53 return krw, nil 54 } 55 56 func moveDirAside(dirname string) error { 57 if fileutil.Exist(dirname) { 58 tempdir, err := ioutil.TempDir(filepath.Dir(dirname), filepath.Base(dirname)) 59 if err != nil { 60 return err 61 } 62 return os.Rename(dirname, tempdir) 63 } 64 return nil 65 } 66 67 func decryptRaftData(swarmdir, outdir, unlockKey string) error { 68 krw, err := getKRW(swarmdir, unlockKey) 69 if err != nil { 70 return err 71 } 72 deks, err := getDEKData(krw) 73 if err != nil { 74 return err 75 } 76 77 // always use false for FIPS, since we want to be able to decrypt logs written using 78 // any algorithm (not just FIPS-compatible ones) 79 _, d := encryption.Defaults(deks.CurrentDEK, false) 80 if deks.PendingDEK == nil { 81 _, d2 := encryption.Defaults(deks.PendingDEK, false) 82 d = encryption.NewMultiDecrypter(d, d2) 83 } 84 85 snapDir := filepath.Join(outdir, "snap-decrypted") 86 if err := moveDirAside(snapDir); err != nil { 87 return err 88 } 89 if err := storage.MigrateSnapshot( 90 filepath.Join(swarmdir, "raft", "snap-v3-encrypted"), snapDir, 91 storage.NewSnapFactory(encryption.NoopCrypter, d), storage.OriginalSnap); err != nil { 92 return err 93 } 94 95 var walsnap walpb.Snapshot 96 snap, err := storage.OriginalSnap.New(snapDir).Load() 97 if err != nil && !os.IsNotExist(err) { 98 return err 99 } 100 if snap != nil { 101 walsnap.Index = snap.Metadata.Index 102 walsnap.Term = snap.Metadata.Term 103 } 104 105 walDir := filepath.Join(outdir, "wal-decrypted") 106 if err := moveDirAside(walDir); err != nil { 107 return err 108 } 109 return storage.MigrateWALs(context.Background(), 110 filepath.Join(swarmdir, "raft", "wal-v3-encrypted"), walDir, 111 storage.NewWALFactory(encryption.NoopCrypter, d), storage.OriginalWAL, walsnap) 112 } 113 114 func downgradeKey(swarmdir, unlockKey string) error { 115 var ( 116 kek []byte 117 err error 118 ) 119 if unlockKey != "" { 120 kek, err = encryption.ParseHumanReadableKey(unlockKey) 121 if err != nil { 122 return err 123 } 124 } 125 126 n, err := node.New(&node.Config{ 127 StateDir: swarmdir, 128 UnlockKey: kek, 129 }) 130 if err != nil { 131 return err 132 } 133 134 return n.DowngradeKey() 135 }