| 31 | ) |
| 32 | |
| 33 | func main() { |
| 34 | ctx := context.Background() |
| 35 | |
| 36 | // Configuration - adjust paths as needed |
| 37 | certDir := "../../dockers/standalone/tls" |
| 38 | username := "testcertuser" // Must match CN in certificate and ACL user |
| 39 | tlsPort := "6666" |
| 40 | nonTLSPort := "6379" |
| 41 | |
| 42 | // Step 1: First, ensure the ACL user exists (using non-TLS connection) |
| 43 | setupClient := redis.NewClient(&redis.Options{ |
| 44 | Addr: "localhost:" + nonTLSPort, |
| 45 | }) |
| 46 | defer setupClient.Close() |
| 47 | |
| 48 | // Create the ACL user if it doesn't exist |
| 49 | err := setupClient.ACLSetUser(ctx, |
| 50 | username, |
| 51 | "on", // Enable the user |
| 52 | "nopass", // No password - will use cert auth |
| 53 | "~*", // Access all keys |
| 54 | "+@all", // All commands (adjust as needed) |
| 55 | ).Err() |
| 56 | if err != nil { |
| 57 | log.Printf("Note: Could not create ACL user (may already exist): %v", err) |
| 58 | } |
| 59 | |
| 60 | // Step 2: Load CA certificate |
| 61 | caCert, err := os.ReadFile(certDir + "/ca.crt") |
| 62 | if err != nil { |
| 63 | log.Fatalf("Failed to load CA certificate: %v", err) |
| 64 | } |
| 65 | caCertPool := x509.NewCertPool() |
| 66 | caCertPool.AppendCertsFromPEM(caCert) |
| 67 | |
| 68 | // Step 3: Load client certificate (CN must match the Redis ACL username) |
| 69 | clientCert, err := tls.LoadX509KeyPair( |
| 70 | certDir+"/"+username+".crt", |
| 71 | certDir+"/"+username+".key", |
| 72 | ) |
| 73 | if err != nil { |
| 74 | log.Fatalf("Failed to load client certificate: %v", err) |
| 75 | } |
| 76 | |
| 77 | // Step 4: Create TLS config |
| 78 | tlsConfig := &tls.Config{ |
| 79 | RootCAs: caCertPool, |
| 80 | Certificates: []tls.Certificate{clientCert}, |
| 81 | ServerName: "localhost", |
| 82 | InsecureSkipVerify: true, // Only for self-signed certs in testing |
| 83 | } |
| 84 | |
| 85 | // Step 5: Connect to Redis with TLS - NO username/password needed! |
| 86 | client := redis.NewClient(&redis.Options{ |
| 87 | Addr: "localhost:" + tlsPort, |
| 88 | TLSConfig: tlsConfig, |
| 89 | // Note: No Username or Password fields - auth happens via certificate |
| 90 | }) |