gleep fixes mtls and stuff

This commit is contained in:
boris committed 2026-04-18 18:17:29 +01:00
1 parent 31b726b439
commit 779db4cd94
16 files changed
+526 -45

No files matched your search

+11 -3
View File
@@ -12,11 +12,19 @@ go build -o keywarden-agent ./cmd/keywarden-agent
## Run
```
./keywarden-agent -config /etc/keywarden/agent.json -server-url https://keywarden.example.com -enroll-token <token>
```
./keywarden-agent --config /etc/keywarden/agent.json --server-url https://keywarden.example.com --enroll-token <token>
```
To rotate/re-enroll an existing agent identity, add `-force-enroll` with a fresh token.
Short aliases are also supported:
```bash
./keywarden-agent -c /etc/keywarden/agent.json -t <token> -f
```
To rotate/re-enroll an existing agent identity in place, use `-f/--force-enroll` with a fresh token.
When `server_id` already exists in config, force-enroll rotates the client certificate for that server
instead of creating a new server record.
You can also pass `KEYWARDEN_SERVER_URL` and `KEYWARDEN_ENROLL_TOKEN` as environment variables.
+25 -10
View File
@@ -32,9 +32,12 @@ var lastNoEventsNotice time.Time
func main() {
configPath := flag.String("config", config.DefaultConfigPath, "Path to agent config JSON")
flag.StringVar(configPath, "c", config.DefaultConfigPath, "Path to agent config JSON (shorthand)")
serverURL := flag.String("server-url", "", "Keywarden server URL (first boot)")
enrollToken := flag.String("enroll-token", "", "Enrollment token (first boot)")
flag.StringVar(enrollToken, "t", "", "Enrollment token (first boot, shorthand)")
forceEnroll := flag.Bool("force-enroll", false, "Force re-enrollment even if already bootstrapped")
flag.BoolVar(forceEnroll, "f", false, "Force re-enrollment even if already bootstrapped (shorthand)")
showVersion := flag.Bool("version", false, "Print version and exit")
flag.Parse()
@@ -236,17 +239,21 @@ func bootstrapIfNeeded(cfg *config.Config, configPath string, enrollToken string
previousServerID := strings.TrimSpace(cfg.ServerID)
if !forceEnroll && cfg.ServerID != "" && fileExists(cfg.ClientCertPath()) && fileExists(cfg.CACertPath()) {
if strings.TrimSpace(enrollToken) != "" {
log.Printf("enrollment token provided but bootstrap is already complete; skipping enrollment (use -force-enroll to rotate identity)")
log.Printf("enrollment token provided but bootstrap is already complete; skipping enrollment (use -f/--force-enroll to rotate identity)")
}
return nil
}
if enrollToken == "" {
return fmt.Errorf("missing enrollment token; set KEYWARDEN_ENROLL_TOKEN or -enroll-token")
return fmt.Errorf("missing enrollment token; set KEYWARDEN_ENROLL_TOKEN or -t/--enroll-token")
}
rotateServerID := ""
if forceEnroll {
log.Printf("force re-enrollment requested; replacing existing server identity")
cfg.ServerID = ""
cfg.AgentAPIToken = ""
rotateServerID = previousServerID
if rotateServerID != "" {
log.Printf("force re-enrollment requested; rotating certificate in-place for server_id=%s", rotateServerID)
} else {
log.Printf("force re-enrollment requested; no existing server_id, enrolling as new server identity")
}
}
keyPath := cfg.ClientKeyPath()
if !fileExists(keyPath) {
@@ -261,15 +268,23 @@ func bootstrapIfNeeded(cfg *config.Config, configPath string, enrollToken string
info := host.Detect()
hostname := info.Hostname
resp, err := client.Enroll(context.Background(), cfg.ServerURL, client.EnrollRequest{
Token: enrollToken,
CSRPEM: csrPEM,
Host: hostname,
IPv4: info.IPv4,
IPv6: info.IPv6,
Token: enrollToken,
CSRPEM: csrPEM,
Host: hostname,
IPv4: info.IPv4,
IPv6: info.IPv6,
ServerID: rotateServerID,
})
if err != nil {
return err
}
if rotateServerID != "" && strings.TrimSpace(resp.ServerID) != rotateServerID {
return fmt.Errorf(
"re-enrollment returned unexpected server_id=%s (expected %s)",
strings.TrimSpace(resp.ServerID),
rotateServerID,
)
}
if err := os.WriteFile(cfg.ClientCertPath(), []byte(resp.ClientCert), 0o600); err != nil {
return err
}
+3 -4
View File
@@ -1,7 +1,6 @@
{
"server_url": "https://keywarden.dev.ntbx.io/api/v1",
"server_id": "6",
"agent_api_token": "HV8MnbysmINShu9wkXzzNrQE5NyRlPJHfP2aU6SX4HERrlac8EQpoMEu02FX1TYv",
"server_url": "https://agent.keywarden.dev.ntbx.io/api/v1",
"server_id": "13",
"sync_interval_seconds": 5,
"log_batch_size": 2000,
"state_dir": "/var/lib/keywarden-agent",
@@ -12,4 +11,4 @@
"create_home": true,
"lock_on_revoke": true
}
}
}
+14 -6
View File
@@ -52,6 +52,7 @@ func New(cfg *config.Config) (*Client, error) {
if err != nil {
return nil, fmt.Errorf("load client cert: %w", err)
}
clientCert := cert
caPool, err := x509.SystemCertPool()
if err != nil || caPool == nil {
caPool = x509.NewCertPool()
@@ -70,6 +71,12 @@ func New(cfg *config.Config) (*Client, error) {
Certificates: []tls.Certificate{cert},
RootCAs: caPool,
MinVersion: tls.VersionTLS12,
// Always return the enrolled client certificate when the server
// requests mTLS credentials. This avoids edge cases where automatic
// certificate selection declines to send a cert.
GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
return &clientCert, nil
},
}
transport := &http.Transport{
@@ -122,12 +129,13 @@ func (c *Client) setAuth(req *http.Request) {
}
type EnrollRequest struct {
Token string `json:"token"`
CSRPEM string `json:"csr_pem"`
Host string `json:"host"`
IPv4 string `json:"ipv4,omitempty"`
IPv6 string `json:"ipv6,omitempty"`
AgentID string `json:"agent_id,omitempty"`
Token string `json:"token"`
CSRPEM string `json:"csr_pem"`
Host string `json:"host"`
IPv4 string `json:"ipv4,omitempty"`
IPv6 string `json:"ipv6,omitempty"`
ServerID string `json:"server_id,omitempty"`
AgentID string `json:"agent_id,omitempty"`
}
type EnrollResponse struct {
Binary file not shown.