bc486eb49d
CI / check-and-test (pull_request) Successful in 11s
Write generated configs 0600, treat new keys as raw AES-256, keep PBKDF2 for unprefixed material, and cache derivation at startup.
129 lines
3.2 KiB
Go
129 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"teleport/internal/client"
|
|
"teleport/internal/server"
|
|
"teleport/pkg/config"
|
|
"teleport/pkg/encryption"
|
|
"teleport/pkg/logger"
|
|
"teleport/pkg/version"
|
|
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
func main() {
|
|
var (
|
|
configFile = pflag.StringP("config", "c", "teleport.yaml", "Configuration file path")
|
|
generateConfig = pflag.BoolP("generate-config", "g", false, "Generate example configuration file and exit")
|
|
generateKey = pflag.BoolP("generate-key", "k", false, "Generate a random encryption key and exit")
|
|
showVersion = pflag.BoolP("version", "v", false, "Show version information and exit")
|
|
logLevel = pflag.String("log-level", "info", "Log level (debug, info, warn, error)")
|
|
logFormat = pflag.String("log-format", "text", "Log format (text, json)")
|
|
logFile = pflag.String("log-file", "", "Log file path (empty for stdout)")
|
|
)
|
|
pflag.Parse()
|
|
|
|
// Initialize logging
|
|
logConfig := logger.Config{
|
|
Level: *logLevel,
|
|
Format: *logFormat,
|
|
File: *logFile,
|
|
}
|
|
if err := logger.Init(logConfig); err != nil {
|
|
fmt.Printf("Failed to initialize logging: %v\n", err)
|
|
return
|
|
}
|
|
|
|
// Handle version flags
|
|
if *showVersion {
|
|
fmt.Println(version.String())
|
|
return
|
|
}
|
|
|
|
if *generateConfig {
|
|
if err := config.GenerateExampleConfig(*configFile); err != nil {
|
|
logger.Errorf("Failed to generate config: %v", err)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
if *generateKey {
|
|
key, err := generateRandomKey()
|
|
if err != nil {
|
|
logger.Errorf("Failed to generate key: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Generated encryption key: %s\n", key)
|
|
fmt.Println("Paste the entire value into encryption_key on both server and client.")
|
|
fmt.Println("This is a raw 256-bit AES key (no PBKDF2). Unprefixed keys in existing configs still use PBKDF2.")
|
|
return
|
|
}
|
|
|
|
// Load configuration
|
|
cfg, err := config.LoadConfig(*configFile)
|
|
if err != nil {
|
|
logger.Errorf("Failed to load configuration: %v", err)
|
|
return
|
|
}
|
|
|
|
// Detect mode (server or client)
|
|
mode, err := config.DetectMode(cfg)
|
|
if err != nil {
|
|
logger.Errorf("Mode detection failed: %v", err)
|
|
return
|
|
}
|
|
|
|
logger.Infof("Starting teleport in %s mode", mode)
|
|
|
|
// Set up signal handling
|
|
sigChan := make(chan os.Signal, 1)
|
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
// Start the appropriate mode
|
|
switch mode {
|
|
case "server":
|
|
srv := server.NewTeleportServer(cfg)
|
|
go func() {
|
|
if err := srv.Start(); err != nil {
|
|
logger.Errorf("Server error: %v", err)
|
|
}
|
|
}()
|
|
|
|
// Wait for shutdown signal
|
|
<-sigChan
|
|
logger.Info("Received shutdown signal, stopping server...")
|
|
srv.Stop()
|
|
|
|
case "client":
|
|
clt := client.NewTeleportClient(cfg)
|
|
go func() {
|
|
if err := clt.Start(); err != nil {
|
|
logger.Errorf("Client error: %v", err)
|
|
}
|
|
}()
|
|
|
|
// Wait for shutdown signal
|
|
<-sigChan
|
|
logger.Info("Received shutdown signal, stopping client...")
|
|
clt.Stop()
|
|
}
|
|
}
|
|
|
|
// generateRandomKey generates a raw 256-bit AES key (raw: + 64 hex chars).
|
|
func generateRandomKey() (string, error) {
|
|
key, err := encryption.GenerateRawKey()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if err := encryption.ValidateEncryptionKey(key); err != nil {
|
|
return "", fmt.Errorf("generated key failed validation: %v", err)
|
|
}
|
|
return key, nil
|
|
}
|