Skip to content

Commit

Permalink
[FIXED] Killed server on restart could render encrypted stream unreco…
Browse files Browse the repository at this point in the history
…verable (#4210)

When a server was killed on restart before an encrypted stream was
recovered the keyfile was removed and could cause the stream to not be
recoverable.

We only needed to delete the key file when converting ciphers and right
before we add the stream itself.

Signed-off-by: Derek Collison <derek@nats.io>

Resolves #4195
  • Loading branch information
derekcollison committed Jun 4, 2023
2 parents 449b429 + 4c1b93d commit eb09ddd
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions server/jetstream.go
Expand Up @@ -1209,22 +1209,23 @@ func (a *Account) EnableJetStream(limits map[string]JetStreamAccountLimits) erro

// Check if we are encrypted.
keyFile := filepath.Join(mdir, JetStreamMetaFileKey)
if key, err := os.ReadFile(keyFile); err == nil {
keyBuf, err := os.ReadFile(keyFile)
if err == nil {
s.Debugf(" Stream metafile is encrypted, reading encrypted keyfile")
if len(key) < minMetaKeySize {
s.Warnf(" Bad stream encryption key length of %d", len(key))
if len(keyBuf) < minMetaKeySize {
s.Warnf(" Bad stream encryption key length of %d", len(keyBuf))
continue
}
// Decode the buffer before proceeding.
nbuf, err := s.decryptMeta(sc, key, buf, a.Name, fi.Name())
nbuf, err := s.decryptMeta(sc, keyBuf, buf, a.Name, fi.Name())
if err != nil {
// See if we are changing ciphers.
switch sc {
case ChaCha:
nbuf, err = s.decryptMeta(AES, key, buf, a.Name, fi.Name())
nbuf, err = s.decryptMeta(AES, keyBuf, buf, a.Name, fi.Name())
osc, convertingCiphers = AES, true
case AES:
nbuf, err = s.decryptMeta(ChaCha, key, buf, a.Name, fi.Name())
nbuf, err = s.decryptMeta(ChaCha, keyBuf, buf, a.Name, fi.Name())
osc, convertingCiphers = ChaCha, true
}
if err != nil {
Expand All @@ -1234,9 +1235,6 @@ func (a *Account) EnableJetStream(limits map[string]JetStreamAccountLimits) erro
}
buf = nbuf
plaintext = false

// Remove the key file to have system regenerate with the new cipher.
os.Remove(keyFile)
}

var cfg FileStreamInfo
Expand Down Expand Up @@ -1288,13 +1286,22 @@ func (a *Account) EnableJetStream(limits map[string]JetStreamAccountLimits) erro
s.Noticef(" Encrypting stream '%s > %s'", a.Name, cfg.StreamConfig.Name)
} else if convertingCiphers {
s.Noticef(" Converting from %s to %s for stream '%s > %s'", osc, sc, a.Name, cfg.StreamConfig.Name)
// Remove the key file to have system regenerate with the new cipher.
os.Remove(keyFile)
}
}

// Add in the stream.
mset, err := a.addStream(&cfg.StreamConfig)
if err != nil {
s.Warnf(" Error recreating stream %q: %v", cfg.Name, err)
// If we removed a keyfile from above make sure to put it back.
if convertingCiphers {
err := os.WriteFile(keyFile, keyBuf, defaultFilePerms)
if err != nil {
s.Warnf(" Error replacing meta keyfile for stream %q: %v", cfg.Name, err)
}
}
continue
}
if !cfg.Created.IsZero() {
Expand Down

0 comments on commit eb09ddd

Please sign in to comment.