Skip to content
This repository was archived by the owner on Jun 23, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions cmd/kube-etcd-signer-server/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ var (
mCACrtFile string
mCAKeyFile string
mCASigner bool
sCrtFile string
sKeyFile string
sCrtFiles []string
sKeyFiles []string
addr string
peerCertDur string
serverCertDur string
Expand All @@ -38,8 +38,8 @@ func init() {
rootCmd.AddCommand(serveCmd)
serveCmd.PersistentFlags().StringVar(&serveOpts.caCrtFile, "cacrt", "", "CA certificate file for signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.caKeyFile, "cakey", "", "CA private key file for signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.sCrtFile, "servcrt", "", "Server certificate file for signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.sKeyFile, "servkey", "", "Server private key file for signer")
serveCmd.PersistentFlags().StringArrayVar(&serveOpts.sCrtFiles, "servcrt", []string{}, "Server certificate file for signer")
serveCmd.PersistentFlags().StringArrayVar(&serveOpts.sKeyFiles, "servkey", []string{}, "Server private key file for signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.mCACrtFile, "metric-cacrt", "", "CA certificate file for metrics signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.mCAKeyFile, "metric-cakey", "", "CA private key file for metrics signer")
serveCmd.PersistentFlags().StringVar(&serveOpts.addr, "address", "0.0.0.0:6443", "Address on which the signer listens for requests")
Expand All @@ -62,8 +62,10 @@ func validateServeOpts(cmd *cobra.Command, args []string) error {
return errors.New("no signer CA flags passed one cert/key pair is required")
}

if serveOpts.sCrtFile == "" || serveOpts.sKeyFile == "" {
return errors.New("both --servcrt and --servkey are required flags")
if cl, kl := len(serveOpts.sCrtFiles), len(serveOpts.sKeyFiles); cl == 0 || kl == 0 {
return errors.New("at least one pair of --servcrt and --servkey is required")
} else if cl != kl {
return fmt.Errorf("%d --servercrt does not match %d --servkey", cl, kl)
}
if serveOpts.csrDir == "" {
return errors.New("missing required flag: --csrdir")
Expand Down Expand Up @@ -93,11 +95,13 @@ func runCmdServe(cmd *cobra.Command, args []string) error {
MetricCACert: serveOpts.mCACrtFile,
MetricCAKey: serveOpts.mCAKeyFile,
}

servercerts := make([]signer.CertKey, len(serveOpts.sCrtFiles))
for idx := range serveOpts.sCrtFiles {
servercerts[idx] = signer.CertKey{CertFile: serveOpts.sCrtFiles[idx], KeyFile: serveOpts.sKeyFiles[idx]}
}
c := signer.Config{
SignerCAFiles: ca,
ServerCertFile: serveOpts.sCrtFile,
ServerKeyFile: serveOpts.sKeyFile,
ServerCertKeys: servercerts,
ListenAddress: serveOpts.addr,
EtcdMetricCertDuration: mCertDur,
EtcdPeerCertDuration: pCertDur,
Expand Down
31 changes: 25 additions & 6 deletions pkg/certsigner/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package certsigner

import (
"crypto"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
Expand Down Expand Up @@ -77,14 +78,17 @@ type CertSigner struct {
cfsslSigner *local.Signer
}

// CertKey stores files for the cert and key pair.
type CertKey struct {
CertFile, KeyFile string
}

// Config holds the configuration values required to start a new signer
type Config struct {
// SignerCAFiles
SignerCAFiles
// ServerCertFile is the file location of the server certificate
ServerCertFile string
// ServerKeyFile is the file location of the server private key
ServerKeyFile string
// ServerCertKeys is a list of server certificates for serving on TLS based on SNI
ServerCertKeys []CertKey
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Using []tls.Certificate here (and loading the cert/key pairs in cmd/kube-etcd-signer-server/serve.go) would let us simplify the pkg/certsigner API slightly by leaning on stdlib types instead of defining our own. But whatever, folks are unlikely to be using pkg/certsigner outside of this repository ;).

// ListenAddress is the address at which the server listens for requests
ListenAddress string
// EtcdMetricCertDuration
Expand Down Expand Up @@ -440,7 +444,22 @@ func StartSignerServer(c Config) error {
if err != nil {
return fmt.Errorf("error setting up signer: %v", err)
}

h := &loggingHandler{s.mux}
return http.ListenAndServeTLS(c.ListenAddress, c.ServerCertFile, c.ServerKeyFile, h)

certs := make([]tls.Certificate, len(c.ServerCertKeys))
for idx, pair := range c.ServerCertKeys {
certs[idx], err = tls.LoadX509KeyPair(pair.CertFile, pair.KeyFile)
if err != nil {
return fmt.Errorf("Failed to load key pair from (%q, %q): %v", pair.CertFile, pair.KeyFile, err)
}
}
tlsconfig := &tls.Config{
Certificates: certs,
}
tlsconfig.BuildNameToCertificate()
return (&http.Server{
TLSConfig: tlsconfig,
Handler: h,
Addr: c.ListenAddress,
}).ListenAndServeTLS("", "")
}
129 changes: 49 additions & 80 deletions pkg/certsigner/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,36 +97,28 @@ bA==
-----END CERTIFICATE-----`)

caMetricsCrtBytes = []byte(`-----BEGIN CERTIFICATE-----
MIIFXTCCA0WgAwIBAgIURQbfHSBCKeD2UL952fkS5lgYJowwDQYJKoZIhvcNAQEL
BQAwPjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEYMBYGA1UE
CgwPZmFrZS1tZXRyaWNzLWNhMB4XDTE5MDMyMDExNTMyM1oXDTE5MDQxOTExNTMy
M1owPjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEYMBYGA1UE
CgwPZmFrZS1tZXRyaWNzLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAyZEhO7Yfk7tupNZnuILlRfegg+8QNcbPbo0e/vyjBij2KvqDxWSjjF+cSc4m
OLhdvTYad1U0ylYFPEDk+mNMmhuMo6egTwkl2NPxxFT3tmfO8XTwxlNr6weaHh1R
UVw2dbw6Tg0NDPhfe2i6qUCl7bYQYxmhJiR/wweAakhjh/uXw04IAlmtDX4rHCzV
/fU5H429fnwv+2w6c94v9KKd+Kb0vob9VPbxS5Wac+4ppGuNpYesbrZzr1CLU7J4
M2dnPueKFJm9Vco4tTRu6xmVrB7Yz2F4Lx6vOYUMKpW1RWLdevaX3A0BmMMvjUof
OOwDfDkWtjkLeFfQfGU0w3Z+AkPd50zE8Cin9ncHE8Y/OAAZeHmBVjyMOsTrDxDg
rYDbMNhqQ+XLIe4XbIyNFjsPNX1HwPcW7XO0rz+b4pwsyLdkRN7Bbil0D5pVS67R
uZ0EIGh/x1xV8WCqyYRU4g8hmstaWrdVIQ25oqPAgnEoEoG/DvzPWUlVYdHxBzq9
nt/L6CtadFYB2dyEy+P2v9xMe9LAPz1s2L6xm/xToT9QkS8dArLUI1YKeHUKj5WS
Vst6sosmYEecQoMfZxJUSodp7SZsr/ZrDJmEFIDZrdrjx6DgGmAI+PZc+VbbbcF7
9t2MF9tDg13t3eqcA3ghmwY9gLZKdib3Oc+Ghv2asnkFFY8CAwEAAaNTMFEwHQYD
VR0OBBYEFBB/Exg1rCBHZOZJK24YrRKi7ArnMB8GA1UdIwQYMBaAFBB/Exg1rCBH
ZOZJK24YrRKi7ArnMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AJqp6IpzHjuM5Pnfv3L9HFbVYp/q4XrvUKw9vUXD4mADL8XQVYCOLi9Zixfz1Ke9
Gmk7sUZXlcAAQH80DecqB71XT0tuGobSrUOVVVM0qZsTt8pedDfQTwHqz+wl8MNE
Pd/Rte4VgwHQjaTYX6CnmqmnTvZVHwj5myi00xpU3sFxHk1brUEnEe7nyuR4dJ8k
DR/qtB9alR/mJwse0bWQI4lo9QakEoA5PLFSvUnXxNqOiQR3tRAxist6Td6g1Upe
/se6yv+1IRAuZXoSJpwmoRnxSLVZtD6EGLZK35hRjfvZx+G2422rst56thzVC4VS
yFrH5lgT66cyn3rw8cgqwufb5pspB4Qsc05Y0Ky1PQBst2rvhWiJaMJNma2+R/3/
EMyCIbsp2niXwPLkqSOCKhpbOBlPYlfvEY2PivI9CF2FnFv7vyhqk6n7L79puKJk
/1VriB6uUVG8HdAzEazXULYSOPsgZ7kwr+8hI6jkrMPsisjIPMbdvD/pkyEh9iu7
4lfBjgE382fdY2ShbHVdjq6dbPmH3Ds7/RaQQP8esZs29ll9Y7irr63RZkY3OiR0
/aYkCM2BLtayR9wuunBEFGPwAZLIQKHk5MJSLsix9l0uV+N897agsKQ87Luxn1vw
Rd1ImiuaAD0Dz9rSJQyZrzFGvZRCqTUC9c5Vp1/X8djW
-----END CERTIFICATE-----`)
MIIDoDCCAoigAwIBAgIJAKnsPQEyA7F4MA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRgwFgYD
VQQKDA9mYWtlLW1ldHJpY3MtY2ExGDAWBgNVBAsMD2Zha2UtbWV0cmljcy1jYTAe
Fw0xOTA0MjQyMjQ1MTNaFw0yOTA0MjEyMjQ1MTNaMGUxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJDQTEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRgwFgYDVQQKDA9mYWtl
LW1ldHJpY3MtY2ExGDAWBgNVBAsMD2Zha2UtbWV0cmljcy1jYTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAM9sN8qC5hvICzYXZ3xfD7nSG+w2dqv7cH7P
7zRDf9JNQpV9Pl/YwDPRUWF4RO4NGbPlH1sRsLYlX6HiRVx1v7iEY4g3mSvkCeUb
Matjj35iwwb3BHA+gTWcCLB8GU5oNVuycVOB2D7LG76UzTSp1aEkEbXFrJUmI+dR
TobYZB+ECvOrVCRcm/iz2rhiF/fEqJawxOU5A7qiJuV87NXRXNY48DmKTHBZHC//
cYzV+m99yQ0CWpz+Y7bxPKceLeUMUngvJlE/dgyHBLUebK1ZymzWTyU+to+nCfS9
B7CSSNUGauf5+LGrhzzGdxQ3n6fZG+f8uoo9ILKgfLyuwIOXpO0CAwEAAaNTMFEw
HQYDVR0OBBYEFBgrZJppU/8uMe2hLNqnNa/6j4pCMB8GA1UdIwQYMBaAFBgrZJpp
U/8uMe2hLNqnNa/6j4pCMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD
ggEBABMHy+0oA08iyP355WXW7QQR7sxASPzNOKyiHeZsg7cvAwWxUpK71Z3fcvR8
bcBqmT2wnCm1yOj2Mw5hbRnntTgKZAzbIoRtvAhI04i5e9SUjbI9RVQz5G11SKAm
tg2zZPvEu6OpCBc/PHE4BdazprvFJDSeQTG1Y+5/zJ04XOXCqhLndKZfYCnRAbgu
b367F/raoB/iVDZPmJQiXRuvkXpPl/a+2rwiltUzNbeHDPLCRfMsoWNBE5/Xrajs
lXXy+a/6GRLGk7Jt+HC1qDTskUNtexQsvh8yjw5gH3SmtWDP3TeV7HxaXhIr5GVo
0ARjPTCTS2mm7tNyRJLkFJonnjo=
-----END CERTIFICATE-----
`)

caKeyBytes = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEApOcWmKHVuJIy1mTWG4/PfDj1zL7YHpg2SQ4uIL2mUyGVT5sq
Expand Down Expand Up @@ -181,56 +173,33 @@ vCuqdwASd/1MJWpe/v+PPcIJzSLRfDcPkIWfOJKBaeIagnSHKqGECIs+Jv8F
-----END RSA PRIVATE KEY-----`)

caMetricsKeyBytes = []byte(`-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----`)
MIIEpAIBAAKCAQEAz2w3yoLmG8gLNhdnfF8PudIb7DZ2q/twfs/vNEN/0k1ClX0+
X9jAM9FRYXhE7g0Zs+UfWxGwtiVfoeJFXHW/uIRjiDeZK+QJ5Rsxq2OPfmLDBvcE
cD6BNZwIsHwZTmg1W7JxU4HYPssbvpTNNKnVoSQRtcWslSYj51FOhthkH4QK86tU
JFyb+LPauGIX98SolrDE5TkDuqIm5Xzs1dFc1jjwOYpMcFkcL/9xjNX6b33JDQJa
nP5jtvE8px4t5QxSeC8mUT92DIcEtR5srVnKbNZPJT62j6cJ9L0HsJJI1QZq5/n4
sauHPMZ3FDefp9kb5/y6ij0gsqB8vK7Ag5ek7QIDAQABAoIBAHU3xt+e0cNpbUyI
NWdHoW91mWoH7VCLq6s+fwOeEaIbH0GzoYgwyY1/AOqAORP+O0Q6e1nPyXll7YFi
iagSsuHnjwfvw5PWLvFWSN9+SB04WtaYyd1UtVhCcXaq6vIwWdcUJI74legGiAtP
tBfK0ntaEtgSedFf2HJktGfn6c0UoDdSMTpkua61bonAR4Z7JwyRj4SGHkEBOkhL
cHNRnTgVfCQ4jngqyGljMK0E+qkLdlqpGIL0qLC3Va1GXxXBLDwOUK9yBHCSMIpc
CDDVll4TgYUBX+MPfFTgu7U0/+9CfcIadQj6QQ9El1/0CVVBTgucO4ikCeFBxevr
h14ID4ECgYEA/O+mprUjesJQbAqRyjOYkaNifHjK/MJySMtCC2GfA/6cZDzH85gd
Igb8TZTL7hU6e7kk2G/9qBHmlK3EqxgPTHEnB9utUYKgD8cnqWLoDTwo/bLaBcsl
ebkHFn+1xE2g8hN2CGVQ3sfVqNGblHFBQo4cKchK2Vg2GH+0/6UmTKkCgYEA0e9u
UdR8s+u3FsLyDdnUkhmYWna7QjoT3UMxjtH+o96IXJXmoZx6BFyGUdY2nstN1yRe
VHHB3LP/20ky8DvUnWx1Gvad3dm70SXy39iTCJ5KnWT9xo1EqEkAnhCzc4z+B+iP
K4adcYIXDaeykZPOfOMjO4m9SUeW1C0mhY0v3KUCgYEA1+Gz25W/MoenHI/o3ywq
jCNna9Wtaw6LfJX/SLeJgV9PHD7EaqTqOKC9t3nIlOyJfhAH4rOzTD/7DetCcMWY
SSZKqepVg7x54P2aXHiOlr1CP0bnzwoUck/6PLnD6khXlkYF+CSBYaQuOGiu4YPI
r4WbhA3v1JH1mfNmCMxsZAECgYBfSE2I5GlI+/YYZZiZAsIBIY7NmE/7igKUDThD
+zmYxJqdcwe/WBblPd1U7WXTArEssXwC1bLIagX5UCrHcFBatuwbtc0G8RjWn2Ox
h0mMwtNYxoqMAHgl7SRTmX7pNhfiHQJGHg39g67U6sUYX757XlgSYLzBsrVZTbjL
Kr6LZQKBgQDGq4+tJYhT0+zYJ3Ds97SzAfFIXIPzDWhpRbbwvv98SQrfBppiiYqd
sDKkMqkhqffxfUae8TtI1dLEfs/+LA4YhcafoEb9zQ6BZ8g2n0zhaJ0S7NNHoMpj
AXT0pY+qS78LFp0sm+YSG4gIAO5MFvXhVo2uXgT/oBI/e2PzfLV+sA==
-----END RSA PRIVATE KEY-----
`)
)

func loadAllCrts(t *testing.T) {
Expand Down