mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 08:16:39 +00:00
Compare commits
3 Commits
set-min-pa
...
fix/events
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56d82a99e1 | ||
|
|
d25f543913 | ||
|
|
672b4c0401 |
@@ -170,6 +170,10 @@ if [ "$NETBIRD_DASH_AUTH_USE_AUDIENCE" = "false" ]; then
|
|||||||
export NETBIRD_AUTH_PKCE_AUDIENCE=
|
export NETBIRD_AUTH_PKCE_AUDIENCE=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Read the encryption key
|
||||||
|
encKey=$(grep DataStoreEncryptionKey management.json | awk -F'"' '{$0=$4}1')
|
||||||
|
export NETBIRD_DATASTORE_ENC_KEY=$encKey
|
||||||
|
|
||||||
env | grep NETBIRD
|
env | grep NETBIRD
|
||||||
|
|
||||||
envsubst <docker-compose.yml.tmpl >docker-compose.yml
|
envsubst <docker-compose.yml.tmpl >docker-compose.yml
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"Password": null
|
"Password": null
|
||||||
},
|
},
|
||||||
"Datadir": "",
|
"Datadir": "",
|
||||||
|
"DataStoreEncryptionKey": "$NETBIRD_DATASTORE_ENC_KEY",
|
||||||
"HttpConfig": {
|
"HttpConfig": {
|
||||||
"Address": "0.0.0.0:$NETBIRD_MGMT_API_PORT",
|
"Address": "0.0.0.0:$NETBIRD_MGMT_API_PORT",
|
||||||
"AuthIssuer": "$NETBIRD_AUTH_AUTHORITY",
|
"AuthIssuer": "$NETBIRD_AUTH_AUTHORITY",
|
||||||
|
|||||||
@@ -301,15 +301,23 @@ var (
|
|||||||
func initEventStore(dataDir string, key string) (activity.Store, string, error) {
|
func initEventStore(dataDir string, key string) (activity.Store, string, error) {
|
||||||
var err error
|
var err error
|
||||||
if key == "" {
|
if key == "" {
|
||||||
log.Debugf("generate new activity store encryption key")
|
log.Debugf("restore or generate new activity store encryption key")
|
||||||
key, err = sqlite.GenerateKey()
|
key, err = sqlite.RestoreKey(dataDir)
|
||||||
|
if err == nil {
|
||||||
|
goto CreateStore
|
||||||
|
} else {
|
||||||
|
log.Debugf("failed to restore encryption key for activity store: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("generate new encryption key for activity store")
|
||||||
|
key, err = sqlite.GenerateKey(dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CreateStore:
|
||||||
store, err := sqlite.NewSQLiteStore(dataDir, key)
|
store, err := sqlite.NewSQLiteStore(dataDir, key)
|
||||||
return store, key, err
|
return store, key, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func notifyStop(msg string) {
|
func notifyStop(msg string) {
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
backupFile = ".datastore.key"
|
||||||
)
|
)
|
||||||
|
|
||||||
var iv = []byte{10, 22, 13, 79, 05, 8, 52, 91, 87, 98, 88, 98, 35, 25, 13, 05}
|
var iv = []byte{10, 22, 13, 79, 05, 8, 52, 91, 87, 98, 88, 98, 35, 25, 13, 05}
|
||||||
@@ -15,16 +21,40 @@ type FieldEncrypt struct {
|
|||||||
block cipher.Block
|
block cipher.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateKey() (string, error) {
|
func RestoreKey(dataDir string) (string, error) {
|
||||||
|
fName := filepath.Join(dataDir, backupFile)
|
||||||
|
data, err := os.ReadFile(fName)
|
||||||
|
return string(data), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateKey(dataDir string) (string, error) {
|
||||||
key := make([]byte, 32)
|
key := make([]byte, 32)
|
||||||
_, err := rand.Read(key)
|
_, err := rand.Read(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
readableKey := base64.StdEncoding.EncodeToString(key)
|
readableKey := base64.StdEncoding.EncodeToString(key)
|
||||||
|
|
||||||
|
err = saveKey(dataDir, readableKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
return readableKey, nil
|
return readableKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func saveKey(dataDir, key string) error {
|
||||||
|
f, err := os.Create(filepath.Join(dataDir, backupFile))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
_, err = f.WriteString(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewFieldEncrypt(key string) (*FieldEncrypt, error) {
|
func NewFieldEncrypt(key string) (*FieldEncrypt, error) {
|
||||||
binKey, err := base64.StdEncoding.DecodeString(key)
|
binKey, err := base64.StdEncoding.DecodeString(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,11 +2,20 @@ package sqlite
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestRestoreKey(t *testing.T) {
|
||||||
|
_, err := RestoreKey(t.TempDir())
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGenerateKey(t *testing.T) {
|
func TestGenerateKey(t *testing.T) {
|
||||||
testData := "exampl@netbird.io"
|
testData := "exampl@netbird.io"
|
||||||
key, err := GenerateKey()
|
key, err := GenerateKey(t.TempDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to generate key: %s", err)
|
t.Fatalf("failed to generate key: %s", err)
|
||||||
}
|
}
|
||||||
@@ -32,7 +41,7 @@ func TestGenerateKey(t *testing.T) {
|
|||||||
|
|
||||||
func TestCorruptKey(t *testing.T) {
|
func TestCorruptKey(t *testing.T) {
|
||||||
testData := "exampl@netbird.io"
|
testData := "exampl@netbird.io"
|
||||||
key, err := GenerateKey()
|
key, err := GenerateKey(t.TempDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to generate key: %s", err)
|
t.Fatalf("failed to generate key: %s", err)
|
||||||
}
|
}
|
||||||
@@ -46,7 +55,7 @@ func TestCorruptKey(t *testing.T) {
|
|||||||
t.Fatalf("invalid encrypted text")
|
t.Fatalf("invalid encrypted text")
|
||||||
}
|
}
|
||||||
|
|
||||||
newKey, err := GenerateKey()
|
newKey, err := GenerateKey(t.TempDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to generate key: %s", err)
|
t.Fatalf("failed to generate key: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ const (
|
|||||||
"VALUES(?, ?, ?, ?, ?, ?)"
|
"VALUES(?, ?, ?, ?, ?, ?)"
|
||||||
|
|
||||||
insertDeleteUserQuery = `INSERT INTO deleted_users(id, email, name) VALUES(?, ?, ?)`
|
insertDeleteUserQuery = `INSERT INTO deleted_users(id, email, name) VALUES(?, ?, ?)`
|
||||||
|
|
||||||
|
fallbackName = "unknown"
|
||||||
|
fallbackEmail = "unknown@unknown.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store is the implementation of the activity.Store interface backed by SQLite
|
// Store is the implementation of the activity.Store interface backed by SQLite
|
||||||
@@ -128,6 +131,7 @@ func NewSQLiteStore(dataDir string, encryptionKey string) (*Store, error) {
|
|||||||
|
|
||||||
func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
||||||
events := make([]*activity.Event, 0)
|
events := make([]*activity.Event, 0)
|
||||||
|
var cryptErr error
|
||||||
for result.Next() {
|
for result.Next() {
|
||||||
var id int64
|
var id int64
|
||||||
var operation activity.Activity
|
var operation activity.Activity
|
||||||
@@ -156,8 +160,8 @@ func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
if targetUserName != nil {
|
if targetUserName != nil {
|
||||||
name, err := store.fieldEncrypt.Decrypt(*targetUserName)
|
name, err := store.fieldEncrypt.Decrypt(*targetUserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to decrypt username for target id: %s", target)
|
cryptErr = fmt.Errorf("failed to decrypt username for target id: %s", target)
|
||||||
meta["username"] = ""
|
meta["username"] = fallbackName
|
||||||
} else {
|
} else {
|
||||||
meta["username"] = name
|
meta["username"] = name
|
||||||
}
|
}
|
||||||
@@ -166,8 +170,8 @@ func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
if targetEmail != nil {
|
if targetEmail != nil {
|
||||||
email, err := store.fieldEncrypt.Decrypt(*targetEmail)
|
email, err := store.fieldEncrypt.Decrypt(*targetEmail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to decrypt email address for target id: %s", target)
|
cryptErr = fmt.Errorf("failed to decrypt email address for target id: %s", target)
|
||||||
meta["email"] = ""
|
meta["email"] = fallbackEmail
|
||||||
} else {
|
} else {
|
||||||
meta["email"] = email
|
meta["email"] = email
|
||||||
}
|
}
|
||||||
@@ -186,7 +190,8 @@ func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
if initiatorName != nil {
|
if initiatorName != nil {
|
||||||
name, err := store.fieldEncrypt.Decrypt(*initiatorName)
|
name, err := store.fieldEncrypt.Decrypt(*initiatorName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to decrypt username of initiator: %s", initiator)
|
cryptErr = fmt.Errorf("failed to decrypt username of initiator: %s", initiator)
|
||||||
|
event.InitiatorName = fallbackName
|
||||||
} else {
|
} else {
|
||||||
event.InitiatorName = name
|
event.InitiatorName = name
|
||||||
}
|
}
|
||||||
@@ -195,7 +200,8 @@ func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
if initiatorEmail != nil {
|
if initiatorEmail != nil {
|
||||||
email, err := store.fieldEncrypt.Decrypt(*initiatorEmail)
|
email, err := store.fieldEncrypt.Decrypt(*initiatorEmail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to decrypt email address of initiator: %s", initiator)
|
cryptErr = fmt.Errorf("failed to decrypt email address of initiator: %s", initiator)
|
||||||
|
event.InitiatorEmail = fallbackEmail
|
||||||
} else {
|
} else {
|
||||||
event.InitiatorEmail = email
|
event.InitiatorEmail = email
|
||||||
}
|
}
|
||||||
@@ -204,6 +210,10 @@ func (store *Store) processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
events = append(events, event)
|
events = append(events, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cryptErr != nil {
|
||||||
|
log.Warnf("%s", cryptErr)
|
||||||
|
}
|
||||||
|
|
||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func TestNewSQLiteStore(t *testing.T) {
|
func TestNewSQLiteStore(t *testing.T) {
|
||||||
dataDir := t.TempDir()
|
dataDir := t.TempDir()
|
||||||
key, _ := GenerateKey()
|
key, _ := GenerateKey(dataDir)
|
||||||
store, err := NewSQLiteStore(dataDir, key)
|
store, err := NewSQLiteStore(dataDir, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user