Write generated configs 0600, treat new keys as raw AES-256, keep PBKDF2 for unprefixed material, and cache derivation at startup.
This commit is contained in:
+19
-12
@@ -1,8 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -609,24 +607,33 @@ func GenerateExampleConfig(filename string) error {
|
||||
return fmt.Errorf("failed to marshal config: %v", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(filename, data, 0644)
|
||||
err = os.WriteFile(filename, data, 0o600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config file: %v", err)
|
||||
}
|
||||
if err := os.Chmod(filename, 0o600); err != nil {
|
||||
return fmt.Errorf("failed to set config file permissions: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Generated example configuration: %s\n", filename)
|
||||
fmt.Printf("Edit the configuration file and run: ./teleport -config %s\n", filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateStrongEncryptionKey generates a cryptographically secure encryption key
|
||||
// generateStrongEncryptionKey generates a raw 256-bit key (raw: + 64 hex chars).
|
||||
func generateStrongEncryptionKey() (string, error) {
|
||||
// Generate 32 random bytes (256 bits) for a strong encryption key
|
||||
bytes := make([]byte, 32)
|
||||
if _, err := rand.Read(bytes); err != nil {
|
||||
return "", fmt.Errorf("failed to generate random key: %v", err)
|
||||
}
|
||||
|
||||
// Convert to hexadecimal string for easy copying
|
||||
return hex.EncodeToString(bytes), nil
|
||||
return encryption.GenerateRawKey()
|
||||
}
|
||||
|
||||
// ApplyTCPKeepAlive enables TCP keep-alive when enabled is true.
|
||||
func ApplyTCPKeepAlive(conn net.Conn, enabled bool) {
|
||||
if conn == nil || !enabled {
|
||||
return
|
||||
}
|
||||
tcp, ok := conn.(*net.TCPConn)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
_ = tcp.SetKeepAlive(true)
|
||||
_ = tcp.SetKeepAlivePeriod(30 * time.Second)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"teleport/pkg/encryption"
|
||||
)
|
||||
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
@@ -585,3 +587,61 @@ func TestGenerateExampleConfigUsesLoopback(t *testing.T) {
|
||||
t.Fatalf("generated client local listen %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateExampleConfigMode0600(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
configFile := filepath.Join(tempDir, "server.yaml")
|
||||
if err := GenerateExampleConfig(configFile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st, err := os.Stat(configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if st.Mode().Perm() != 0o600 {
|
||||
t.Fatalf("generated config mode %04o want 0600", st.Mode().Perm())
|
||||
}
|
||||
cfg, err := LoadConfig(configFile)
|
||||
if err != nil {
|
||||
t.Fatalf("reload generated config: %v", err)
|
||||
}
|
||||
if !encryption.IsRawKey(cfg.EncryptionKey) {
|
||||
t.Fatalf("generated encryption_key is not raw: %q", cfg.EncryptionKey[:min(8, len(cfg.EncryptionKey))])
|
||||
}
|
||||
key, err := encryption.ResolveKey(cfg.EncryptionKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(key) != 32 {
|
||||
t.Fatalf("resolved key len %d", len(key))
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyTCPKeepAlive(t *testing.T) {
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ln.Close()
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
ApplyTCPKeepAlive(c, true)
|
||||
errCh <- nil
|
||||
}()
|
||||
conn, err := net.Dial("tcp", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
ApplyTCPKeepAlive(conn, true)
|
||||
ApplyTCPKeepAlive(conn, false)
|
||||
if err := <-errCh; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user