mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 13:31:36 +00:00
889c1a5a9e
Phase 1 of the deploy-hardening II master bundle. Adds the 11 missing
target sidecars to deploy/docker-compose.test.yml under
profiles: [deploy-e2e] (windows-iis-test under [deploy-e2e-windows]
because Windows containers run only on Windows hosts).
Per frozen decision 0.2: pull pre-built images from official
registries where they exist (NGINX, HAProxy, Traefik, Caddy, Envoy,
Postfix via boky, Dovecot, OpenSSH via lscr.io, K8s via kind);
build locally only where no official image works (F5 — uses the
new in-tree f5-mock-icontrol Go server). Every FROM digest-pinned
per H-001 guard.
NEW deploy/test/f5-mock-icontrol/ — in-tree Go server implementing
the iControl REST surface the F5 connector exercises:
- POST /mgmt/shared/authn/login (token-based auth)
- POST /mgmt/shared/file-transfer/uploads/<filename>
- POST /mgmt/tm/sys/crypto/cert + /key (install)
- POST /mgmt/tm/transaction (create) + /<txn-id> (commit)
- PATCH /mgmt/tm/ltm/profile/client-ssl/<name> (update SSL profile)
- GET / DELETE variants
- /healthz for sidecar readiness probes
- HTTPS via per-process self-signed ECDSA P-256 cert
- In-memory state map (lost on container restart; CI tests handle
via test-init re-auth)
Per frozen decision 0.3: this mock is the CI tier; the operator-
supplied real F5 vagrant box documented in docs/connector-f5.md
(Phase 14 deliverable) is the validation tier above. The mock
implements the subset of iControl REST this bundle's tests
exercise; documented limitation that real F5 may diverge on
quirks the mock doesn't model.
NEW per-vendor config bind-mounts (deploy/test/<vendor>/):
- apache/httpd-ssl.conf + init-cert.sh
- haproxy/haproxy.cfg
- traefik/traefik-dynamic.yml
- caddy/Caddyfile
- envoy/envoy.yaml
- dovecot/dovecot.conf
Each minimal config: bind /etc/<vendor>/certs to a named volume
so the e2e tests rotate certs via the per-connector atomic-deploy
primitive (Bundle I Phase 4-9).
Network IPs: 10.30.50.{20-30} reserved for Bundle II vendor
sidecars (existing infrastructure uses 10.30.50.{2-9}).
f5-mock-icontrol Go binary: gofmt clean, go vet clean, go build
clean. Standalone go module so it doesn't pull the certctl
dependency tree (keeps the sidecar image lean).
Phase 2 next: NGINX vendor-edge audit + 10 e2e tests.
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"math/big"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// selfSignedCert generates a fresh ECDSA P-256 self-signed cert+key
|
|
// at startup. Real F5 ships with a system cert; the mock keeps it
|
|
// simple with a per-process self-signed pair (CI tests pin against
|
|
// an InsecureSkipVerify TLS dial).
|
|
func selfSignedCert() ([]byte, []byte) {
|
|
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
tmpl := x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{CommonName: "f5-mock-icontrol"},
|
|
NotBefore: time.Now().Add(-time.Hour),
|
|
NotAfter: time.Now().Add(365 * 24 * time.Hour),
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
DNSNames: []string{"f5-mock-icontrol", "localhost"},
|
|
}
|
|
der, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der})
|
|
keyDER, err := x509.MarshalECPrivateKey(priv)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER})
|
|
return certPEM, keyPEM
|
|
}
|
|
|
|
// writeAndServeTLS loads the in-memory cert+key into the server
|
|
// without touching disk.
|
|
func writeAndServeTLS(srv *http.Server, certPEM, keyPEM []byte) error {
|
|
pair, err := tls.X509KeyPair(certPEM, keyPEM)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
srv.TLSConfig = &tls.Config{
|
|
MinVersion: tls.VersionTLS12,
|
|
Certificates: []tls.Certificate{pair},
|
|
}
|
|
return srv.ListenAndServeTLS("", "")
|
|
}
|