mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 04:06:03 +00:00
Merge pull request #109024 from stlaz/sha1_sig_deprecation
webhooks,aggregation: add metrics to count certs with SHA1 signatures
This commit is contained in:
commit
e0ca5cfd73
@ -20,184 +20,266 @@ limitations under the License.
|
|||||||
package webhook
|
package webhook
|
||||||
|
|
||||||
var caKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
var caKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----`)
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
|
||||||
var caCert = []byte(`-----BEGIN CERTIFICATE-----
|
var caCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
VzryJj1NmnSqA3zd3jBMuK37Ei3pRvVbO7Uxf14=
|
HsNKnE0CSPZ65ENVNfJjB1fVEYbbpjr8kizOCDE=
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
var badCACert = []byte(`-----BEGIN CERTIFICATE-----
|
var badCACert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
36VxjlPiERA2m5tmNNy4hZ4zUXKlsJgeY+bAdVM=
|
YqXbFLxSCtUNhKuW5ejbvHAYp/QgtjAtu81HOkQ=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var caCertInter = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEIwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl
|
||||||
|
cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt
|
||||||
|
uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq
|
||||||
|
EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4
|
||||||
|
M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT
|
||||||
|
al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK
|
||||||
|
SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z
|
||||||
|
ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD
|
||||||
|
bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E
|
||||||
|
BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARYbIpIidgAVb
|
||||||
|
5ra9zd7F902+xC13/nmlrKL/dRMrRdZxk1kVVww3FbXSp7k7oHsih42KUCVDBevw
|
||||||
|
0ZZiolZlLneU57dEKKiTMkuPdVbNbIBPXIQpHLrXpVIR5BRRdRZ5OJZY24hYCvce
|
||||||
|
50XV8ITIU0R/U4sQ6NFHv8NJ5BB+2u1M3HF2LSKZFLnfP5FBcTCg84Jd6gEmTU2j
|
||||||
|
wZELnHy1AVdQnKMP9VrdAr9Wn6omWxAfO/PSb9YeKhGH5vtX+Bpb9bSPQIpXeBdB
|
||||||
|
LLCkme0M+1UsF7xua0KVi4DSuJc+RBl4aOH0ZvKmrIWzLzZhRS0vaO/fPArVCvvI
|
||||||
|
VrUba0E3WQ==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var caCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEMwDQYJKoZIhvcNAQEF
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl
|
||||||
|
cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt
|
||||||
|
uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq
|
||||||
|
EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4
|
||||||
|
M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT
|
||||||
|
al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK
|
||||||
|
SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z
|
||||||
|
ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD
|
||||||
|
bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E
|
||||||
|
BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAAhMQTwrpAeIQ
|
||||||
|
nShHfTERiwg/tx3dL971d3pFS5wi4kEIbbYCUGpzkmK/FTw4hfUnLpwcjjAbOWkk
|
||||||
|
45glOmrLJXM4RvH5PQF3GZmZvxv8Dl4zuhH1QvWbJHUiC+gyrBWI0moyLSmNiutZ
|
||||||
|
d3TZGEehZGwivMdHHuhgiyFM4i33EQTW1vdMdOvdu8yNpAeXM2h1PcJwbEML9PO3
|
||||||
|
LONzVKhz/RsyEwv7PkX1gdmi6eyAE61BWJGwzxE4K0xIYmcr6iOjsJhEf/5Qc93P
|
||||||
|
IGSHsG/HjWwZ47gbobtv7L+8uKP/0ky+k1cE4nIB1gKYey+SYwvkQTsj24oG9xcL
|
||||||
|
XhgnIl+qDw==
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||||
MIIEowIBAAKCAQEA0Gi/3oXPU0oRP38xNAQ1js4Py1fVqy5OW+3rcaZONdUiiHJ4
|
MIIEowIBAAKCAQEA52b4byIJpUDyTKo5FiCa5Ekiy7CCd8UoleSomQjh5zZGsIbg
|
||||||
6K1mIMKuEH2nrFAq2cFiXIm9prrSN8hyLY9lUguyAlecdHe6he/7/PAoX7NM8NX1
|
z9RqjaTMLF0jqbzh9ix2DQSnY+w32LqPM2sOK1+/atmeCa8m5bvZrRoDxP2T3pQH
|
||||||
LzOfUotcO+iZtrnMVCut2vlqjsGsnxppLKnFnp17ycOy7yKCuQHowPln5xp6JkhR
|
Tye0C9WI7jqosmMquRFakaY1ODxDRPWF9CRghFF62NcHfnztW2rMiEYtuDRkZGsp
|
||||||
F0bxDXIFFmve4uHHlRsWcEoNQRJZTaOMrfrFYfqbc5iBitI7/5xgMPZNq282TQDc
|
JL/B5OAzEgLr4iP8TKMlqSuhaQhi52dEZo0pJ1Ie4up8xxXKeoqfO3WSVDeRpj/n
|
||||||
GeJmbFHEu/L1qO6uTg1LkbNbZKNfXeAU46K+eecGCwPyTMlDYuREdoVpH9GYW7Cx
|
0tYSALhOCdGn0RMav5wfZmxdfZpKUhBrcxFfeiDB5c7xdlnziHrY5lqSQPCHxAQb
|
||||||
OIRTYgCLWVok96yk2jeVCq21BbxZ8+NBJ2rhqQIDAQABAoIBAB8bY3gdVOLDrWti
|
S1jMaV4adhxDzF56t5RU6/5eWPZ4IvlTRtYmNwIDAQABAoIBAAb0r28XxNZ011O6
|
||||||
2r8+2ZelHiplw9i3Iq8KBhiCkC3s0Ci5nV5tc070f/KqLrrDhIHYIYxaatpWDEaT
|
ojCqFj3afPNGgQV8pbWrw+2luLSsiv9vbn6Q0gsj8wc6XYISrXAq8fl+NFHqndsj
|
||||||
PqeaPa9PW5SJ6ypfLJINTfllB0Gxi4xvAxe2htNVRcETaM4jUWJG2r5SeBsywUdG
|
8H4JL8nZ/PUHSZrc6vxo4ygy6f4X6UP9iyKz/NOGPbF7jeqe1H/vp5tNNbhVB2ih
|
||||||
M+ictoiETRPCiBS1e/mNVWZoU5/kyMApP+5U9+THKhV4V2Pi2OHon/AeTP1Yc/1A
|
QL+QAF653El8XTtOIgxnb3KBOYqZ6e0rWvC5XlZrfT4EGqpokW4zQ6ROQUbnWyCk
|
||||||
lTB9giQIysDK11j9zbpL2ICW9HSbbeLJlsw8/wCOdnPHFn5kun6EuesOF6MingvM
|
LC4CtQpcLLd7fdGfA2cB2xDdGJ3Er8gAnU/X+tAtcghWanoNARKGU6opyGpwhipe
|
||||||
vL9ZHsh6N7oOHupqRvDPImM3QTYSuBe1hTJSvhi7hmnl9dolsBKKxJz0wjCO1N+V
|
+31CivIUhtASWdbS73ay5QaDQSlgNM1/2hk5Beal7D9bGfKtwT/VGDSpKc4EKP8j
|
||||||
wdPzrwECgYEA9PH+5RSWJtUb2riDpM0QB/Cci6UEFeTJbaCSluog/EH1/E+mOo2J
|
ktQSE0ECgYEA/jHMLQyvJ2VuqBdMI5hbaw5jzUAQwaJof5iQNuvFrbtWDeotAf+6
|
||||||
VbLCMhWwF8kJYToG0sTFGbJ1J1SiaYan7pxH2YIZkgXePC8Vj5WJnLhv05kKRanq
|
HomwoqzZ9+juiil4PHLQJzkArHwMWXbc+3FAznN1foS+YlOmIgJrjKa+EP+sz/X2
|
||||||
kOE1hVnaaCeFJFiLjDW2WeEaNLo6Ap1Qnb6ObzwV+0QvWCMUnVQwfjECgYEA2dCh
|
GxuyH3RD9+TH4EGd4TbeDr0eZOnIbKVybj4ueE+um7jtdLzYW2Y8iCcCgYEA6Qu6
|
||||||
JKDXdsuLUklTc39VKCXXhqO/5FFOzNrZhPEo6KV2mY0BZnNjau4Ff2F6UJb6NMza
|
x5WOQaPaEOQwEP5AqVBZnZl1ogeEVanlPYl6amPFFnlc41+M61p3ebwRqikaC9Dv
|
||||||
fFSLScEZTdbCv5lElGAxJueqC+p2LR3dS/1JfdWJ0zrP1BZa+MWr8O510Go/NOC2
|
hePiOcTTJyt4h7qzgd5rJTjy5bNYDx9F61NGagF0xJLQiMnXM/TsoFABVWetLepG
|
||||||
/s5cR2aVBdJ2WK4d/3XShOr6W8T6hPisr5wFZPkCgYBptUIWpNLEAXZa5wRRC/pe
|
DTzgvCf7wmB9QTgdLct7KyG4suDBJlEAvr70q3ECgYEAxx4pC0z5U4oAMYn2aZeq
|
||||||
ItW8YkOoGytet0xr+rCvjNvWvpzzaf+Zz2KFcNyk9yqoHf2x2h9hnqV2iszok6dH
|
XOUrxpcdySC4bOMMbQkpk1rBIStEUGGK4OsIw5VVNP5xBSdQ+UESzva3EWYmoloa
|
||||||
j4RmdwIIBaZJ/NvmMlfIHcSM4eAP/mtviPGrEgLyrhOEgv3+TXPbyAyiMrg0RqXy
|
5pgjpNUKv62qGQnfhJqStt3S2yv8qfbI7xk14a/IokHDVGbyDn5VWgRI79G1322G
|
||||||
3bjkgl7OKDfyZnlQCHRBEQKBgCfmLK6N/AoZzQKcxfmhOJMrI2jZdBw5vKqP6EqO
|
gtcQvcvlQjSNRbm8XXRrjFcCgYA66x1Awl3h2IQUSyyfzzgX1lmhz59+5HmfksGD
|
||||||
9oRvUuNbzgbbWjnLMhycWZCLp3emkts1jXJMOftlPLVmOQbI/Bf5Vc/q+gzXrKLv
|
SlOpvCmi4fILBihBhHC6VUL+C0ArhppX9mJGiq17tLDXV+t0RQA/u+MlEa+MuzJZ
|
||||||
2deAF0gnPMzH75AkfZObyt8Lp1pjU4IngQXfR6sSW3VxJ7OU/KQ2evf2hEF5YACn
|
KYee21ljLV8NhkIjP6Pnb/K2XezZs+YcCK0kxNMQtIZWS9KMtmogYHkquEn83vPa
|
||||||
HuHZAoGBAI+i6KI0WiWadenDctkuzLgxEPXaQ3oLBJjhE9CjpcdF6mRMWaU8lPgj
|
Rbrj8QKBgHifm6Z9F4qTz2b2RsYPoMHOdsX0DrZ8xQOH8jioTAy/Xi2hrL5Klp7h
|
||||||
D1bo9L8wxvqIW5qIrX9dKnGgYAxnomhBNQn3C+5XDgtq6UiANalilqs3AoaWlQiF
|
zaLifWtOdtckFxIk+6D/zLLn1icC7cc8n4TMwQ1ikY+9IPnkTXVx4b/r/NSbAVxZ
|
||||||
WKaPuWf2T2ypFVzdzPl/0fsFUo8Rw5D4VO4nHeglOrkGQx+OdXA6
|
J821mkhGdqKJGAzk6uh/Sn4rNGubH+I1x2Xa9hWbARCLsj8tp6TX
|
||||||
-----END RSA PRIVATE KEY-----`)
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
|
||||||
var serverCert = []byte(`-----BEGIN CERTIFICATE-----
|
var serverCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE-----
|
var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
var clientKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
var clientKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----`)
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
|
||||||
var clientCert = []byte(`-----BEGIN CERTIFICATE-----
|
var clientCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
uL8+zNieoQkyj84eXfkyiSs03TrqOsj9
|
vhrAcrxy49UrY03GqZwmaf79vF+c2oKk
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var sha1ServerCertInter = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDITCCAgmgAwIBAgIUaVjtC++/JGFoZRtkpo/j5q1nQ/4wDQYJKoZIhvcNAQEF
|
||||||
|
BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN
|
||||||
|
MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs
|
||||||
|
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq
|
||||||
|
ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6
|
||||||
|
jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1
|
||||||
|
hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn
|
||||||
|
RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ
|
||||||
|
a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5
|
||||||
|
U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw
|
||||||
|
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z
|
||||||
|
dDANBgkqhkiG9w0BAQUFAAOCAQEATpiJFBwcRFIfZ9ffvS1WDzHqNElEnvocv/ul
|
||||||
|
3KVtoX4gmKRoOy344s3oJ5APPHYWUFuZVc3uofjW265r2uOW1Cb4P9yAtNc4htBS
|
||||||
|
+hYsdS3MQlzZCS9rItaT25R6Ieq5TbHGRCof387jzvo1NNhcAQ5akQlQKI87km77
|
||||||
|
VzoEBdAw68Q0ZE+X34Q9eAA44oCcLAgCpGvs6hQuUSInribSR3vtsjuaLjdJ5F1f
|
||||||
|
GCu2QGM4cVLaezmoa1J54ETZggT2xFw2IyWJ2g/kXFpo+HnoyaDrPthud3Pe5xEt
|
||||||
|
JMzX0s3jPSjfeAv34Pr37s0Or18r1bS1hrgxE0SV2vk31fsImg==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var serverCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDITCCAgmgAwIBAgIUfSzzygvth1xlpa9DtyGpHuY2V+swDQYJKoZIhvcNAQEL
|
||||||
|
BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN
|
||||||
|
MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs
|
||||||
|
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq
|
||||||
|
ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6
|
||||||
|
jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1
|
||||||
|
hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn
|
||||||
|
RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ
|
||||||
|
a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5
|
||||||
|
U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw
|
||||||
|
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z
|
||||||
|
dDANBgkqhkiG9w0BAQsFAAOCAQEAwe/JUeIiJ5ugiO4tM0ZtvgHuFC3hK+ZWndRE
|
||||||
|
z4JfVXTW9soxpa/cOU9QdJhZzouIu9yqZasY4zSEerC1e6grBYP95vMbN6xUAown
|
||||||
|
wNzrQzyJ6yP526txiIdOkKf+yVNdz0OWNHMPtwTWIr8kKGK23ABF94aUa0VlkErp
|
||||||
|
Qrd8NQ3guIPI+/upuxirJCFdhE+U3U0pLHpGaGvhkOytfnLYiINwR9norVCDGbQG
|
||||||
|
ITH0tOz8gVWWWwxa9s5CmbqTnasgUMDh1jHa5xOo+riX8H5lwQUaItKU1JM+QMIR
|
||||||
|
6Z+M0Isdw647A6tmX7DqNcmHlBKxPN1GDcVXalwYJUoXwTb9Hw==
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
@ -148,8 +148,11 @@ func (cm *ClientManager) HookClient(cc ClientConfig) (*rest.RESTClient, error) {
|
|||||||
cfg.ContentConfig.ContentType = runtime.ContentTypeJSON
|
cfg.ContentConfig.ContentType = runtime.ContentTypeJSON
|
||||||
|
|
||||||
// Add a transport wrapper that allows detection of TLS connections to
|
// Add a transport wrapper that allows detection of TLS connections to
|
||||||
// servers without SAN extension in their serving certificates
|
// servers with serving certificates with deprecated characteristics
|
||||||
cfg.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter))
|
cfg.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor(
|
||||||
|
x509MissingSANCounter,
|
||||||
|
x509InsecureSHA1Counter,
|
||||||
|
))
|
||||||
|
|
||||||
client, err := rest.UnversionedRESTClientFor(cfg)
|
client, err := rest.UnversionedRESTClientFor(cfg)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -23,6 +23,14 @@ set -e
|
|||||||
|
|
||||||
CN_BASE="webhook_tests"
|
CN_BASE="webhook_tests"
|
||||||
|
|
||||||
|
cat > intermediate_ca.conf << EOF
|
||||||
|
[ v3_ca ]
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer
|
||||||
|
basicConstraints = critical,CA:true
|
||||||
|
keyUsage = cRLSign, keyCertSign
|
||||||
|
EOF
|
||||||
|
|
||||||
cat > server.conf << EOF
|
cat > server.conf << EOF
|
||||||
[req]
|
[req]
|
||||||
req_extensions = v3_req
|
req_extensions = v3_req
|
||||||
@ -71,6 +79,15 @@ openssl req -x509 -new -nodes -key caKey.pem -days 100000 -out caCert.pem -subj
|
|||||||
openssl genrsa -out badCAKey.pem 2048
|
openssl genrsa -out badCAKey.pem 2048
|
||||||
openssl req -x509 -new -nodes -key badCAKey.pem -days 100000 -out badCACert.pem -subj "/CN=${CN_BASE}_ca"
|
openssl req -x509 -new -nodes -key badCAKey.pem -days 100000 -out badCACert.pem -subj "/CN=${CN_BASE}_ca"
|
||||||
|
|
||||||
|
# Create an intermediate certificate authority
|
||||||
|
openssl genrsa -out caKeyInter.pem 2048
|
||||||
|
openssl req -new -nodes -key caKeyInter.pem -days 100000 -out caCertInter.csr -subj "/CN=${CN_BASE}_intermediate_ca"
|
||||||
|
openssl x509 -req -in caCertInter.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out caCertInter.pem -days 100000 -extensions v3_ca -extfile intermediate_ca.conf
|
||||||
|
|
||||||
|
# Create an intermediate certificate authority with sha1 signature
|
||||||
|
openssl req -new -nodes -key caKeyInter.pem -days 100000 -out caCertInterSHA1.csr -subj "/CN=${CN_BASE}_intermediate_ca"
|
||||||
|
openssl x509 -sha1 -req -in caCertInterSHA1.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out caCertInterSHA1.pem -days 100000 -extensions v3_ca -extfile intermediate_ca.conf
|
||||||
|
|
||||||
# Create a server certiticate
|
# Create a server certiticate
|
||||||
openssl genrsa -out serverKey.pem 2048
|
openssl genrsa -out serverKey.pem 2048
|
||||||
openssl req -new -key serverKey.pem -out server.csr -subj "/CN=${CN_BASE}_server" -config server.conf
|
openssl req -new -key serverKey.pem -out server.csr -subj "/CN=${CN_BASE}_server" -config server.conf
|
||||||
@ -80,6 +97,14 @@ openssl x509 -req -in server.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial
|
|||||||
openssl req -new -key serverKey.pem -out serverNoSAN.csr -subj "/CN=localhost" -config server_no_san.conf
|
openssl req -new -key serverKey.pem -out serverNoSAN.csr -subj "/CN=localhost" -config server_no_san.conf
|
||||||
openssl x509 -req -in serverNoSAN.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCertNoSAN.pem -days 100000 -extensions v3_req -extfile server_no_san.conf
|
openssl x509 -req -in serverNoSAN.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCertNoSAN.pem -days 100000 -extensions v3_req -extfile server_no_san.conf
|
||||||
|
|
||||||
|
# Create a server certiticate with SHA1 signature signed by OK intermediate CA
|
||||||
|
openssl req -new -key serverKey.pem -out serverSHA1.csr -subj "/CN=localhost" -config server.conf
|
||||||
|
openssl x509 -sha1 -req -in serverSHA1.csr -CA caCertInter.pem -CAkey caKeyInter.pem -CAcreateserial -out sha1ServerCertInter.pem -days 100000 -extensions v3_req -extfile server.conf
|
||||||
|
|
||||||
|
# Create a server certiticate signed by SHA1-signed intermediate CA
|
||||||
|
openssl req -new -key serverKey.pem -out serverInterSHA1.csr -subj "/CN=localhost" -config server.conf
|
||||||
|
openssl x509 -req -in serverInterSHA1.csr -CA caCertInterSHA1.pem -CAkey caKeyInter.pem -CAcreateserial -out serverCertInterSHA1.pem -days 100000 -extensions v3_req -extfile server.conf
|
||||||
|
|
||||||
# Create a client certiticate
|
# Create a client certiticate
|
||||||
openssl genrsa -out clientKey.pem 2048
|
openssl genrsa -out clientKey.pem 2048
|
||||||
openssl req -new -key clientKey.pem -out client.csr -subj "/CN=${CN_BASE}_client" -config client.conf
|
openssl req -new -key clientKey.pem -out client.csr -subj "/CN=${CN_BASE}_client" -config client.conf
|
||||||
@ -110,7 +135,7 @@ limitations under the License.
|
|||||||
package webhook
|
package webhook
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
for file in caKey caCert badCAKey badCACert serverKey serverCert serverCertNoSAN clientKey clientCert; do
|
for file in caKey caCert badCAKey badCACert caCertInter caCertInterSHA1 serverKey serverCert serverCertNoSAN clientKey clientCert sha1ServerCertInter serverCertInterSHA1; do
|
||||||
data=$(cat ${file}.pem)
|
data=$(cat ${file}.pem)
|
||||||
echo "" >> $outfile
|
echo "" >> $outfile
|
||||||
echo "var $file = []byte(\`$data\`)" >> $outfile
|
echo "var $file = []byte(\`$data\`)" >> $outfile
|
||||||
|
@ -34,6 +34,19 @@ var x509MissingSANCounter = metrics.NewCounter(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var x509InsecureSHA1Counter = metrics.NewCounter(
|
||||||
|
&metrics.CounterOpts{
|
||||||
|
Subsystem: "webhooks",
|
||||||
|
Namespace: "apiserver",
|
||||||
|
Name: "x509_insecure_sha1_total",
|
||||||
|
Help: "Counts the number of requests to servers with insecure SHA1 signatures " +
|
||||||
|
"in their serving certificate OR the number of connection failures " +
|
||||||
|
"due to the insecure SHA1 signatures (either/or, based on the runtime environment)",
|
||||||
|
StabilityLevel: metrics.ALPHA,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
legacyregistry.MustRegister(x509MissingSANCounter)
|
legacyregistry.MustRegister(x509MissingSANCounter)
|
||||||
|
legacyregistry.MustRegister(x509InsecureSHA1Counter)
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,10 @@ func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFact
|
|||||||
codec := codecFactory.LegacyCodec(groupVersions...)
|
codec := codecFactory.LegacyCodec(groupVersions...)
|
||||||
clientConfig.ContentConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
|
clientConfig.ContentConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
|
||||||
|
|
||||||
clientConfig.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter))
|
clientConfig.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor(
|
||||||
|
x509MissingSANCounter,
|
||||||
|
x509InsecureSHA1Counter,
|
||||||
|
))
|
||||||
|
|
||||||
restClient, err := rest.UnversionedRESTClientFor(clientConfig)
|
restClient, err := rest.UnversionedRESTClientFor(clientConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -334,11 +334,12 @@ func TestMissingKubeConfigFile(t *testing.T) {
|
|||||||
func TestTLSConfig(t *testing.T) {
|
func TestTLSConfig(t *testing.T) {
|
||||||
invalidCert := []byte("invalid")
|
invalidCert := []byte("invalid")
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
test string
|
test string
|
||||||
clientCert, clientKey, clientCA []byte
|
clientCert, clientKey, clientCA []byte
|
||||||
serverCert, serverKey, serverCA []byte
|
serverCert, serverKey, serverCA []byte
|
||||||
errRegex string
|
errRegex string
|
||||||
increaseSANWarnCounter bool
|
increaseSANWarnCounter bool
|
||||||
|
increaseSHA1SignatureWarnCounter bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
test: "invalid server CA",
|
test: "invalid server CA",
|
||||||
@ -402,8 +403,23 @@ func TestTLSConfig(t *testing.T) {
|
|||||||
errRegex: "x509: certificate relies on legacy Common Name field",
|
errRegex: "x509: certificate relies on legacy Common Name field",
|
||||||
increaseSANWarnCounter: true,
|
increaseSANWarnCounter: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: "server cert with SHA1 signature",
|
||||||
|
clientCA: caCert,
|
||||||
|
serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...), serverKey: serverKey,
|
||||||
|
errRegex: "x509: cannot verify signature: insecure algorithm SHA1-RSA \\(temporarily override with GODEBUG=x509sha1=1\\)",
|
||||||
|
increaseSHA1SignatureWarnCounter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: "server cert signed by an intermediate CA with SHA1 signature",
|
||||||
|
clientCA: caCert,
|
||||||
|
serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...), serverKey: serverKey,
|
||||||
|
errRegex: "x509: cannot verify signature: insecure algorithm SHA1-RSA \\(temporarily override with GODEBUG=x509sha1=1\\)",
|
||||||
|
increaseSHA1SignatureWarnCounter: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastSHA1SigCounter := 0
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
// Use a closure so defer statements trigger between loop iterations.
|
// Use a closure so defer statements trigger between loop iterations.
|
||||||
func() {
|
func() {
|
||||||
@ -483,6 +499,20 @@ func TestTLSConfig(t *testing.T) {
|
|||||||
t.Errorf("expected the x509_common_name_error_count to be 1, but it's %d", errorCounter)
|
t.Errorf("expected the x509_common_name_error_count to be 1, but it's %d", errorCounter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tt.increaseSHA1SignatureWarnCounter {
|
||||||
|
errorCounter := getSingleCounterValueFromRegistry(t, legacyregistry.DefaultGatherer, "apiserver_webhooks_x509_insecure_sha1_total")
|
||||||
|
|
||||||
|
if errorCounter == -1 {
|
||||||
|
t.Errorf("failed to get the apiserver_webhooks_x509_insecure_sha1_total metrics: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(errorCounter) != lastSHA1SigCounter+1 {
|
||||||
|
t.Errorf("expected the apiserver_webhooks_x509_insecure_sha1_total counter to be 1, but it's %d", errorCounter)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSHA1SigCounter++
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package x509metrics
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
|
||||||
"k8s.io/component-base/metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ utilnet.RoundTripperWrapper = &x509MissingSANErrorMetricsRTWrapper{}
|
|
||||||
|
|
||||||
type x509MissingSANErrorMetricsRTWrapper struct {
|
|
||||||
rt http.RoundTripper
|
|
||||||
|
|
||||||
counter *metrics.Counter
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMissingSANRoundTripperWrapperConstructor returns a RoundTripper wrapper that's usable
|
|
||||||
// within ClientConfig.Wrap that increases the `metricCounter` whenever:
|
|
||||||
// 1. we get a x509.HostnameError with string `x509: certificate relies on legacy Common Name field`
|
|
||||||
// which indicates an error caused by the deprecation of Common Name field when veryfing remote
|
|
||||||
// hostname
|
|
||||||
// 2. the server certificate in response contains no SAN. This indicates that this binary run
|
|
||||||
// with the GODEBUG=x509ignoreCN=0 in env
|
|
||||||
func NewMissingSANRoundTripperWrapperConstructor(metricCounter *metrics.Counter) func(rt http.RoundTripper) http.RoundTripper {
|
|
||||||
return func(rt http.RoundTripper) http.RoundTripper {
|
|
||||||
return &x509MissingSANErrorMetricsRTWrapper{
|
|
||||||
rt: rt,
|
|
||||||
counter: metricCounter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *x509MissingSANErrorMetricsRTWrapper) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
||||||
resp, err := w.rt.RoundTrip(req)
|
|
||||||
checkForHostnameError(err, w.counter)
|
|
||||||
checkRespForNoSAN(resp, w.counter)
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *x509MissingSANErrorMetricsRTWrapper) WrappedRoundTripper() http.RoundTripper {
|
|
||||||
return w.rt
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkForHostnameError increases the metricCounter when we're running w/o GODEBUG=x509ignoreCN=0
|
|
||||||
// and the client reports a HostnameError about the legacy CN fields
|
|
||||||
func checkForHostnameError(err error, metricCounter *metrics.Counter) {
|
|
||||||
if err != nil && errors.As(err, &x509.HostnameError{}) && strings.Contains(err.Error(), "x509: certificate relies on legacy Common Name field") {
|
|
||||||
// increase the count of registered failures due to Go 1.15 x509 cert Common Name deprecation
|
|
||||||
metricCounter.Inc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkRespForNoSAN increases the metricCounter when the server response contains
|
|
||||||
// a leaf certificate w/o the SAN extension
|
|
||||||
func checkRespForNoSAN(resp *http.Response, metricCounter *metrics.Counter) {
|
|
||||||
if resp != nil && resp.TLS != nil && len(resp.TLS.PeerCertificates) > 0 {
|
|
||||||
if serverCert := resp.TLS.PeerCertificates[0]; !hasSAN(serverCert) {
|
|
||||||
metricCounter.Inc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasSAN(c *x509.Certificate) bool {
|
|
||||||
sanOID := []int{2, 5, 29, 17}
|
|
||||||
|
|
||||||
for _, e := range c.Extensions {
|
|
||||||
if e.Id.Equal(sanOID) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,301 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package x509metrics
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/component-base/metrics"
|
|
||||||
"k8s.io/component-base/metrics/testutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// taken from pkg/util/webhook/certs_test.go
|
|
||||||
var caCert = []byte(`-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDGTCCAgGgAwIBAgIUOS2MkobR2t4rguefcC78gLuXkc0wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa
|
|
||||||
GA8yMjk0MDcyMzEyMzE0MVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC
|
|
||||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy8o1sRSe8viuSxh8a7Ou8n
|
|
||||||
vyDJxeJA9son+clZdSwa1YpbhSsYPr2svTGLT4ZxX3JkvHZGDaB+G6QrZNIWOssJ
|
|
||||||
4+fjvEsVSnk9q7Yr8wX8QdShksnSP0qdB1xFKlqwTFcZyQHqjlyctV93/LEosM9D
|
|
||||||
RZzgPpXJuC6wD7qdLRSPxQwuegZYcMGT2Y4/8CfBgiEUkZNrGYJiDFrblI0N9jX2
|
|
||||||
jUeP/g8xWJIKLTBedVbAzj02Y66WdNecYcyTMROdclPB1IbF4ABbCGynnP0fbiaf
|
|
||||||
0+4v0pLedqwCYSWD/ujajyDtYuhI8U+OkENwkZ/h5jw/6aWq7esMZDbEAT6UPgEC
|
|
||||||
AwEAAaNTMFEwHQYDVR0OBBYEFBgvyZWkRJCRjxclYA0mMlnzc/GmMB8GA1UdIwQY
|
|
||||||
MBaAFBgvyZWkRJCRjxclYA0mMlnzc/GmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
|
|
||||||
hvcNAQELBQADggEBAHigaFJ8DqYFMGXNUT5lYM8oLLWYcbivGxR7ofDm8rXWGLdQ
|
|
||||||
tKsWeusSlgpzeO1PKCzwSrYQhlFIZI6AH+ch7EAWt84MfAaMz/1DiXF6Q8fAcR0h
|
|
||||||
QoyFIAKTiVkcgOQjSQOIM2SS5cyGeDRaHGVWfaJOwdIYo6ctFzI2asPJ4yU0QsA7
|
|
||||||
0WTD2+sBG6AXGhfafGUHEmou8sGQ+QT8rgi4hs1bfyHuT5dPgC4TbwknD1G8pMqm
|
|
||||||
ID3CIiCF8hhF5C2hjrW0LTJ6zTlg1c1K0NmmUL1ucsfzEk//c7GsU8dk+FYmtW9A
|
|
||||||
VzryJj1NmnSqA3zd3jBMuK37Ei3pRvVbO7Uxf14=
|
|
||||||
-----END CERTIFICATE-----`)
|
|
||||||
|
|
||||||
var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEowIBAAKCAQEA0Gi/3oXPU0oRP38xNAQ1js4Py1fVqy5OW+3rcaZONdUiiHJ4
|
|
||||||
6K1mIMKuEH2nrFAq2cFiXIm9prrSN8hyLY9lUguyAlecdHe6he/7/PAoX7NM8NX1
|
|
||||||
LzOfUotcO+iZtrnMVCut2vlqjsGsnxppLKnFnp17ycOy7yKCuQHowPln5xp6JkhR
|
|
||||||
F0bxDXIFFmve4uHHlRsWcEoNQRJZTaOMrfrFYfqbc5iBitI7/5xgMPZNq282TQDc
|
|
||||||
GeJmbFHEu/L1qO6uTg1LkbNbZKNfXeAU46K+eecGCwPyTMlDYuREdoVpH9GYW7Cx
|
|
||||||
OIRTYgCLWVok96yk2jeVCq21BbxZ8+NBJ2rhqQIDAQABAoIBAB8bY3gdVOLDrWti
|
|
||||||
2r8+2ZelHiplw9i3Iq8KBhiCkC3s0Ci5nV5tc070f/KqLrrDhIHYIYxaatpWDEaT
|
|
||||||
PqeaPa9PW5SJ6ypfLJINTfllB0Gxi4xvAxe2htNVRcETaM4jUWJG2r5SeBsywUdG
|
|
||||||
M+ictoiETRPCiBS1e/mNVWZoU5/kyMApP+5U9+THKhV4V2Pi2OHon/AeTP1Yc/1A
|
|
||||||
lTB9giQIysDK11j9zbpL2ICW9HSbbeLJlsw8/wCOdnPHFn5kun6EuesOF6MingvM
|
|
||||||
vL9ZHsh6N7oOHupqRvDPImM3QTYSuBe1hTJSvhi7hmnl9dolsBKKxJz0wjCO1N+V
|
|
||||||
wdPzrwECgYEA9PH+5RSWJtUb2riDpM0QB/Cci6UEFeTJbaCSluog/EH1/E+mOo2J
|
|
||||||
VbLCMhWwF8kJYToG0sTFGbJ1J1SiaYan7pxH2YIZkgXePC8Vj5WJnLhv05kKRanq
|
|
||||||
kOE1hVnaaCeFJFiLjDW2WeEaNLo6Ap1Qnb6ObzwV+0QvWCMUnVQwfjECgYEA2dCh
|
|
||||||
JKDXdsuLUklTc39VKCXXhqO/5FFOzNrZhPEo6KV2mY0BZnNjau4Ff2F6UJb6NMza
|
|
||||||
fFSLScEZTdbCv5lElGAxJueqC+p2LR3dS/1JfdWJ0zrP1BZa+MWr8O510Go/NOC2
|
|
||||||
/s5cR2aVBdJ2WK4d/3XShOr6W8T6hPisr5wFZPkCgYBptUIWpNLEAXZa5wRRC/pe
|
|
||||||
ItW8YkOoGytet0xr+rCvjNvWvpzzaf+Zz2KFcNyk9yqoHf2x2h9hnqV2iszok6dH
|
|
||||||
j4RmdwIIBaZJ/NvmMlfIHcSM4eAP/mtviPGrEgLyrhOEgv3+TXPbyAyiMrg0RqXy
|
|
||||||
3bjkgl7OKDfyZnlQCHRBEQKBgCfmLK6N/AoZzQKcxfmhOJMrI2jZdBw5vKqP6EqO
|
|
||||||
9oRvUuNbzgbbWjnLMhycWZCLp3emkts1jXJMOftlPLVmOQbI/Bf5Vc/q+gzXrKLv
|
|
||||||
2deAF0gnPMzH75AkfZObyt8Lp1pjU4IngQXfR6sSW3VxJ7OU/KQ2evf2hEF5YACn
|
|
||||||
HuHZAoGBAI+i6KI0WiWadenDctkuzLgxEPXaQ3oLBJjhE9CjpcdF6mRMWaU8lPgj
|
|
||||||
D1bo9L8wxvqIW5qIrX9dKnGgYAxnomhBNQn3C+5XDgtq6UiANalilqs3AoaWlQiF
|
|
||||||
WKaPuWf2T2ypFVzdzPl/0fsFUo8Rw5D4VO4nHeglOrkGQx+OdXA6
|
|
||||||
-----END RSA PRIVATE KEY-----`)
|
|
||||||
|
|
||||||
var serverCert = []byte(`-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDHzCCAgegAwIBAgIUZIt+6zrmR41Be/CrcPHLsj3pCAQwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa
|
|
||||||
GA8yMjk0MDcyMzEyMzE0MVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19zZXJ2
|
|
||||||
ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQaL/ehc9TShE/fzE0
|
|
||||||
BDWOzg/LV9WrLk5b7etxpk411SKIcnjorWYgwq4QfaesUCrZwWJcib2mutI3yHIt
|
|
||||||
j2VSC7ICV5x0d7qF7/v88Chfs0zw1fUvM59Si1w76Jm2ucxUK63a+WqOwayfGmks
|
|
||||||
qcWenXvJw7LvIoK5AejA+WfnGnomSFEXRvENcgUWa97i4ceVGxZwSg1BEllNo4yt
|
|
||||||
+sVh+ptzmIGK0jv/nGAw9k2rbzZNANwZ4mZsUcS78vWo7q5ODUuRs1tko19d4BTj
|
|
||||||
or555wYLA/JMyUNi5ER2hWkf0ZhbsLE4hFNiAItZWiT3rKTaN5UKrbUFvFnz40En
|
|
||||||
auGpAgMBAAGjVTBTMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG
|
|
||||||
CCsGAQUFBwMCBggrBgEFBQcDATAaBgNVHREEEzARhwR/AAABgglsb2NhbGhvc3Qw
|
|
||||||
DQYJKoZIhvcNAQELBQADggEBAFXNoW48IHJAcO84Smb+/k8DvJBwOorOPspJ/6DY
|
|
||||||
pYITCANq9kQ54bv3LgPuel5s2PytVL1dVQmAya1cT9kG3nIjNaulR2j5Sgt0Ilyd
|
|
||||||
Dk/HOE/zBi6KyifV3dgQSbzua8AI9VboR3o3FhmA9C9jDDxAS+q9+NQjB40/aG8m
|
|
||||||
TBx+oKgeYHee5llKNTsY1Jqh6TT47om70+sjvmgZ4blAV7ft+WG/h3ZVtAZJuFee
|
|
||||||
tchgUEpGR8ZGyK0r/vWBIKHNSqtG5gdOS9swQLdUFG90OivhddKUU8Zt52uUXbc/
|
|
||||||
/ggEd4dM4X6B21xKJQY6vCnTvHFXcVJezV3g1xaNN0yR0DA=
|
|
||||||
-----END CERTIFICATE-----`)
|
|
||||||
|
|
||||||
var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC+DCCAeCgAwIBAgIUZIt+6zrmR41Be/CrcPHLsj3pCAUwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa
|
|
||||||
GA8yMjk0MDcyMzEyMzE0MVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkq
|
|
||||||
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Gi/3oXPU0oRP38xNAQ1js4Py1fVqy5O
|
|
||||||
W+3rcaZONdUiiHJ46K1mIMKuEH2nrFAq2cFiXIm9prrSN8hyLY9lUguyAlecdHe6
|
|
||||||
he/7/PAoX7NM8NX1LzOfUotcO+iZtrnMVCut2vlqjsGsnxppLKnFnp17ycOy7yKC
|
|
||||||
uQHowPln5xp6JkhRF0bxDXIFFmve4uHHlRsWcEoNQRJZTaOMrfrFYfqbc5iBitI7
|
|
||||||
/5xgMPZNq282TQDcGeJmbFHEu/L1qO6uTg1LkbNbZKNfXeAU46K+eecGCwPyTMlD
|
|
||||||
YuREdoVpH9GYW7CxOIRTYgCLWVok96yk2jeVCq21BbxZ8+NBJ2rhqQIDAQABozkw
|
|
||||||
NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI
|
|
||||||
KwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAGgrpuQ4n0W/TaaXhdbfFELziXoN
|
|
||||||
eT89eFYOqgtx/o97sj8B/y+n8tm+lBopfmdnifta3e8iNVULAd6JKjBhkFL1NY3Q
|
|
||||||
tR+VqT8uEZthDM69cyuGTv1GybnUCY9mtW9dSgHHkcJNsZGn9oMTCYDcBrgoA4s3
|
|
||||||
vZc4wuPj8wyiSJBDYMNZfLWHCvLTOa0XUfh0Pf0/d26KuAUTNQkJZLZ5cbNXZuu3
|
|
||||||
fVN5brtOw+Md5nUa60z+Xp0ESaGvOLUjnmd2SWUfAzcbFbbV4fAyYZF/93zCVTJ1
|
|
||||||
ig9gRWmPqLcDDLf9LPyDR5yHRTSF4USH2ykun4PiPfstjfv0xwddWgG2+S8=
|
|
||||||
-----END CERTIFICATE-----`)
|
|
||||||
|
|
||||||
// Test_checkForHostnameError tests that the upstream message for remote server
|
|
||||||
// certificate's hostname hasn't changed when no SAN extension is present and that
|
|
||||||
// the metrics counter increases properly when such an error is encountered
|
|
||||||
//
|
|
||||||
// Requires GODEBUG=x509ignoreCN=0 to not be set in the environment
|
|
||||||
func TestCheckForHostnameError(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
serverCert []byte
|
|
||||||
counterIncrease bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "no SAN",
|
|
||||||
serverCert: serverCertNoSAN,
|
|
||||||
counterIncrease: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "with SAN",
|
|
||||||
serverCert: serverCert,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// register the test metrics
|
|
||||||
x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkForHostnameError"})
|
|
||||||
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
|
||||||
registry.MustRegister(x509MissingSANCounter)
|
|
||||||
|
|
||||||
var lastCounterVal int
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
tlsServer, serverURL := testServer(t, tt.serverCert)
|
|
||||||
defer tlsServer.Close()
|
|
||||||
|
|
||||||
client := tlsServer.Client()
|
|
||||||
req, err := http.NewRequest(http.MethodGet, serverURL.String(), nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to create an http request: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.Transport.RoundTrip(req)
|
|
||||||
|
|
||||||
checkForHostnameError(err, x509MissingSANCounter)
|
|
||||||
|
|
||||||
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkForHostnameError")
|
|
||||||
if errorCounterVal == -1 {
|
|
||||||
t.Fatalf("failed to get the error counter from the registry")
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
|
||||||
t.Errorf("expected the Test_checkForHostnameError metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
|
||||||
t.Errorf("expected the Test_checkForHostnameError metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
lastCounterVal = errorCounterVal
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckRespForNoSAN(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
serverCert []byte
|
|
||||||
counterIncrease bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "no certs",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no SAN",
|
|
||||||
serverCert: serverCertNoSAN,
|
|
||||||
counterIncrease: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "with SAN",
|
|
||||||
serverCert: serverCert,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// register the test metrics
|
|
||||||
x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkRespForNoSAN"})
|
|
||||||
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
|
||||||
registry.MustRegister(x509MissingSANCounter)
|
|
||||||
|
|
||||||
var lastCounterVal int
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
var tlsConnectionState *tls.ConnectionState
|
|
||||||
if tt.serverCert != nil {
|
|
||||||
block, _ := pem.Decode([]byte(tt.serverCert))
|
|
||||||
if block == nil {
|
|
||||||
t.Fatal("failed to parse certificate PEM")
|
|
||||||
}
|
|
||||||
|
|
||||||
serverCert, err := x509.ParseCertificate(block.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to parse certificate: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConnectionState = &tls.ConnectionState{
|
|
||||||
PeerCertificates: []*x509.Certificate{serverCert},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := &http.Response{
|
|
||||||
TLS: tlsConnectionState,
|
|
||||||
}
|
|
||||||
|
|
||||||
checkRespForNoSAN(resp, x509MissingSANCounter)
|
|
||||||
|
|
||||||
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkRespForNoSAN")
|
|
||||||
if errorCounterVal == -1 {
|
|
||||||
t.Fatalf("failed to get the error counter from the registry")
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
|
||||||
t.Errorf("expected the Test_checkRespForNoSAN metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
|
||||||
t.Errorf("expected the Test_checkRespForNoSAN metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
lastCounterVal = errorCounterVal
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testServer(t *testing.T, serverCert []byte) (*httptest.Server, *url.URL) {
|
|
||||||
rootCAs := x509.NewCertPool()
|
|
||||||
rootCAs.AppendCertsFromPEM(caCert)
|
|
||||||
|
|
||||||
cert, err := tls.X509KeyPair(serverCert, serverKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to init x509 cert/key pair: %v", err)
|
|
||||||
}
|
|
||||||
tlsConfig := &tls.Config{
|
|
||||||
Certificates: []tls.Certificate{cert},
|
|
||||||
RootCAs: rootCAs,
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
||||||
w.WriteHeader(200)
|
|
||||||
w.Write([]byte("ok"))
|
|
||||||
}))
|
|
||||||
|
|
||||||
tlsServer.TLS = tlsConfig
|
|
||||||
tlsServer.StartTLS()
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(tlsServer.URL)
|
|
||||||
if err != nil {
|
|
||||||
tlsServer.Close()
|
|
||||||
t.Fatalf("failed to parse the testserver URL: %v", err)
|
|
||||||
}
|
|
||||||
serverURL.Host = net.JoinHostPort("localhost", serverURL.Port())
|
|
||||||
|
|
||||||
return tlsServer, serverURL
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSingleCounterValueFromRegistry(t *testing.T, r metrics.Gatherer, name string) int {
|
|
||||||
mfs, err := r.Gather()
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("failed to gather local registry metrics: %v", err)
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, mf := range mfs {
|
|
||||||
if mf.Name != nil && *mf.Name == name {
|
|
||||||
mfMetric := mf.GetMetric()
|
|
||||||
for _, m := range mfMetric {
|
|
||||||
if m.GetCounter() != nil {
|
|
||||||
return int(m.GetCounter().GetValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1
|
|
||||||
}
|
|
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package x509metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/x509"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
|
"k8s.io/component-base/metrics"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ utilnet.RoundTripperWrapper = &x509DeprecatedCertificateMetricsRTWrapper{}
|
||||||
|
|
||||||
|
type x509DeprecatedCertificateMetricsRTWrapper struct {
|
||||||
|
rt http.RoundTripper
|
||||||
|
|
||||||
|
checkers []deprecatedCertificateAttributeChecker
|
||||||
|
}
|
||||||
|
|
||||||
|
type deprecatedCertificateAttributeChecker interface {
|
||||||
|
// CheckRoundTripError returns true if the err is an error specific
|
||||||
|
// to this deprecated certificate attribute
|
||||||
|
CheckRoundTripError(err error) bool
|
||||||
|
// CheckPeerCertificates returns true if the deprecated attribute/value pair
|
||||||
|
// was found in a given certificate in the http.Response.TLS.PeerCertificates bundle
|
||||||
|
CheckPeerCertificates(certs []*x509.Certificate) bool
|
||||||
|
// IncreaseCounter increases the counter internal to this interface
|
||||||
|
// Use the req to derive and log information useful for troubleshooting the certificate issue
|
||||||
|
IncreaseMetricsCounter(req *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
// counterRaiser is a helper structure to include in certificate deprecation checkers.
|
||||||
|
// It implements the IncreaseMetricsCounter() method so that, when included in the checker,
|
||||||
|
// it does not have to be reimplemented.
|
||||||
|
type counterRaiser struct {
|
||||||
|
counter *metrics.Counter
|
||||||
|
reason string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *counterRaiser) IncreaseMetricsCounter(req *http.Request) {
|
||||||
|
if req != nil && req.URL != nil {
|
||||||
|
if hostname := req.URL.Hostname(); len(hostname) > 0 {
|
||||||
|
klog.Infof("invalid certificate detected while connecting to %q: %s", req.URL.Hostname(), c.reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.counter.Inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeprecatedCertificateRoundTripperWrapperConstructor returns a RoundTripper wrapper that's usable within ClientConfig.Wrap.
|
||||||
|
//
|
||||||
|
// It increases the `missingSAN` counter whenever:
|
||||||
|
// 1. we get a x509.HostnameError with string `x509: certificate relies on legacy Common Name field`
|
||||||
|
// which indicates an error caused by the deprecation of Common Name field when veryfing remote
|
||||||
|
// hostname
|
||||||
|
// 2. the server certificate in response contains no SAN. This indicates that this binary run
|
||||||
|
// with the GODEBUG=x509ignoreCN=0 in env
|
||||||
|
//
|
||||||
|
// It increases the `sha1` counter whenever:
|
||||||
|
// 1. we get a x509.InsecureAlgorithmError with string `SHA1`
|
||||||
|
// which indicates an error caused by an insecure SHA1 signature
|
||||||
|
// 2. the server certificate in response contains a SHA1WithRSA or ECDSAWithSHA1 signature.
|
||||||
|
// This indicates that this binary run with the GODEBUG=x509sha1=1 in env
|
||||||
|
func NewDeprecatedCertificateRoundTripperWrapperConstructor(missingSAN, sha1 *metrics.Counter) func(rt http.RoundTripper) http.RoundTripper {
|
||||||
|
return func(rt http.RoundTripper) http.RoundTripper {
|
||||||
|
return &x509DeprecatedCertificateMetricsRTWrapper{
|
||||||
|
rt: rt,
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{
|
||||||
|
NewSANDeprecatedChecker(missingSAN),
|
||||||
|
NewSHA1SignatureDeprecatedChecker(sha1),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *x509DeprecatedCertificateMetricsRTWrapper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
resp, err := w.rt.RoundTrip(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
for _, checker := range w.checkers {
|
||||||
|
if checker.CheckRoundTripError(err) {
|
||||||
|
checker.IncreaseMetricsCounter(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if resp != nil {
|
||||||
|
if resp.TLS != nil && len(resp.TLS.PeerCertificates) > 0 {
|
||||||
|
for _, checker := range w.checkers {
|
||||||
|
if checker.CheckPeerCertificates(resp.TLS.PeerCertificates) {
|
||||||
|
checker.IncreaseMetricsCounter(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *x509DeprecatedCertificateMetricsRTWrapper) WrappedRoundTripper() http.RoundTripper {
|
||||||
|
return w.rt
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ deprecatedCertificateAttributeChecker = &missingSANChecker{}
|
||||||
|
|
||||||
|
type missingSANChecker struct {
|
||||||
|
counterRaiser
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSANDeprecatedChecker(counter *metrics.Counter) *missingSANChecker {
|
||||||
|
return &missingSANChecker{
|
||||||
|
counterRaiser: counterRaiser{
|
||||||
|
counter: counter,
|
||||||
|
reason: "relies on a legacy Common Name field instead of the SAN extension for subject validation",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRoundTripError returns true when we're running w/o GODEBUG=x509ignoreCN=0
|
||||||
|
// and the client reports a HostnameError about the legacy CN fields
|
||||||
|
func (c *missingSANChecker) CheckRoundTripError(err error) bool {
|
||||||
|
if err != nil && errors.As(err, &x509.HostnameError{}) && strings.Contains(err.Error(), "x509: certificate relies on legacy Common Name field") {
|
||||||
|
// increase the count of registered failures due to Go 1.15 x509 cert Common Name deprecation
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckPeerCertificates returns true when the server response contains
|
||||||
|
// a leaf certificate w/o the SAN extension
|
||||||
|
func (c *missingSANChecker) CheckPeerCertificates(peerCertificates []*x509.Certificate) bool {
|
||||||
|
if len(peerCertificates) > 0 {
|
||||||
|
if serverCert := peerCertificates[0]; !hasSAN(serverCert) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasSAN(c *x509.Certificate) bool {
|
||||||
|
sanOID := []int{2, 5, 29, 17}
|
||||||
|
|
||||||
|
for _, e := range c.Extensions {
|
||||||
|
if e.Id.Equal(sanOID) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type sha1SignatureChecker struct {
|
||||||
|
*counterRaiser
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSHA1SignatureDeprecatedChecker(counter *metrics.Counter) *sha1SignatureChecker {
|
||||||
|
return &sha1SignatureChecker{
|
||||||
|
counterRaiser: &counterRaiser{
|
||||||
|
counter: counter,
|
||||||
|
reason: "uses an insecure SHA-1 signature",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRoundTripError returns true when we're running w/o GODEBUG=x509sha1=1
|
||||||
|
// and the client reports an InsecureAlgorithmError about a SHA1 signature
|
||||||
|
func (c *sha1SignatureChecker) CheckRoundTripError(err error) bool {
|
||||||
|
var unknownAuthorityError x509.UnknownAuthorityError
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !errors.As(err, &unknownAuthorityError) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
errMsg := err.Error()
|
||||||
|
if strIdx := strings.Index(errMsg, "x509: cannot verify signature: insecure algorithm"); strIdx != -1 && strings.Contains(errMsg[strIdx:], "SHA1") {
|
||||||
|
// increase the count of registered failures due to Go 1.18 x509 sha1 signature deprecation
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckPeerCertificates returns true when the server response contains
|
||||||
|
// a non-root non-self-signed certificate with a deprecated SHA1 signature
|
||||||
|
func (c *sha1SignatureChecker) CheckPeerCertificates(peerCertificates []*x509.Certificate) bool {
|
||||||
|
// check all received non-self-signed certificates for deprecated signing algorithms
|
||||||
|
for _, cert := range peerCertificates {
|
||||||
|
if cert.SignatureAlgorithm == x509.SHA1WithRSA || cert.SignatureAlgorithm == x509.ECDSAWithSHA1 {
|
||||||
|
// the SHA-1 deprecation does not involve self-signed root certificates
|
||||||
|
if !reflect.DeepEqual(cert.Issuer, cert.Subject) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
@ -0,0 +1,675 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package x509metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"k8s.io/component-base/metrics"
|
||||||
|
"k8s.io/component-base/metrics/testutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// taken from pkg/util/webhook/certs_test.go
|
||||||
|
var caCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDGTCCAgGgAwIBAgIUealQGELTHLUVcpsNNwz8XexiWvswDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC
|
||||||
|
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeW0Jkq6ViZkyhaLCUgbqsN
|
||||||
|
7+6HLwfZK/ljy/KnZ7W7QlJ65Q2tkptL0fY4DPumT7JgVTGnXyTXJ35Ss5A4yhm9
|
||||||
|
yyMH8pNVR19udK1fU74YVmbXJkc0nP7n+AXX9lD2Yy9pDvtaq1E+erN2nR1XaCS9
|
||||||
|
n0ph4C/fB1Rh7mIv/u7WW7/aRz/rJjBBZIbg7hgZPwFsukEifGi0U4uitVYR6MWp
|
||||||
|
jHj++e1G38+4JrZR9vhBoHtBJ1DBpmjAQaAtkSZAxXJnma4awE0Bv0Q4lxkUeY+D
|
||||||
|
th8OxPXxgTbwTKDaguHlWLTapppygA8FnKqmcUkwHZO5OVldi/ZKOUm2YCuJlfEC
|
||||||
|
AwEAAaNTMFEwHQYDVR0OBBYEFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMB8GA1UdIwQY
|
||||||
|
MBaAFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
|
||||||
|
hvcNAQELBQADggEBAJaRryxp0iYWGfLiZ0uIdOiYRVZUtmpqUSqT9/y29ffDAnCS
|
||||||
|
5labJS8FjaiQdlyaH+E9gzo0+nkO9NyfemJRLTEsU4Mz9AAvxs/NuWucqiyF0Y6d
|
||||||
|
JSYt7+2liGK5WvJMbHfW3jloWlv3oX+qL4iGFkJN+L9G+vf0GnKZCxgNIOqM4otv
|
||||||
|
cviCA9ouPwnSfnCeTsBoaUJqhLMizvUx7avvUyZTuV+t9+aN/qH4V//hTBqz9CNq
|
||||||
|
koodzngbUuyaGFI8QISUAhU+pbt6npb69LlhJHC0icDXCc4uTsd+SDsBOorZDuUL
|
||||||
|
HsNKnE0CSPZ65ENVNfJjB1fVEYbbpjr8kizOCDE=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var caCertInter = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEIwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl
|
||||||
|
cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt
|
||||||
|
uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq
|
||||||
|
EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4
|
||||||
|
M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT
|
||||||
|
al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK
|
||||||
|
SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z
|
||||||
|
ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD
|
||||||
|
bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E
|
||||||
|
BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARYbIpIidgAVb
|
||||||
|
5ra9zd7F902+xC13/nmlrKL/dRMrRdZxk1kVVww3FbXSp7k7oHsih42KUCVDBevw
|
||||||
|
0ZZiolZlLneU57dEKKiTMkuPdVbNbIBPXIQpHLrXpVIR5BRRdRZ5OJZY24hYCvce
|
||||||
|
50XV8ITIU0R/U4sQ6NFHv8NJ5BB+2u1M3HF2LSKZFLnfP5FBcTCg84Jd6gEmTU2j
|
||||||
|
wZELnHy1AVdQnKMP9VrdAr9Wn6omWxAfO/PSb9YeKhGH5vtX+Bpb9bSPQIpXeBdB
|
||||||
|
LLCkme0M+1UsF7xua0KVi4DSuJc+RBl4aOH0ZvKmrIWzLzZhRS0vaO/fPArVCvvI
|
||||||
|
VrUba0E3WQ==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var caCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEMwDQYJKoZIhvcNAQEF
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl
|
||||||
|
cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt
|
||||||
|
uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq
|
||||||
|
EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4
|
||||||
|
M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT
|
||||||
|
al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK
|
||||||
|
SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z
|
||||||
|
ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD
|
||||||
|
bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E
|
||||||
|
BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAAhMQTwrpAeIQ
|
||||||
|
nShHfTERiwg/tx3dL971d3pFS5wi4kEIbbYCUGpzkmK/FTw4hfUnLpwcjjAbOWkk
|
||||||
|
45glOmrLJXM4RvH5PQF3GZmZvxv8Dl4zuhH1QvWbJHUiC+gyrBWI0moyLSmNiutZ
|
||||||
|
d3TZGEehZGwivMdHHuhgiyFM4i33EQTW1vdMdOvdu8yNpAeXM2h1PcJwbEML9PO3
|
||||||
|
LONzVKhz/RsyEwv7PkX1gdmi6eyAE61BWJGwzxE4K0xIYmcr6iOjsJhEf/5Qc93P
|
||||||
|
IGSHsG/HjWwZ47gbobtv7L+8uKP/0ky+k1cE4nIB1gKYey+SYwvkQTsj24oG9xcL
|
||||||
|
XhgnIl+qDw==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEA52b4byIJpUDyTKo5FiCa5Ekiy7CCd8UoleSomQjh5zZGsIbg
|
||||||
|
z9RqjaTMLF0jqbzh9ix2DQSnY+w32LqPM2sOK1+/atmeCa8m5bvZrRoDxP2T3pQH
|
||||||
|
Tye0C9WI7jqosmMquRFakaY1ODxDRPWF9CRghFF62NcHfnztW2rMiEYtuDRkZGsp
|
||||||
|
JL/B5OAzEgLr4iP8TKMlqSuhaQhi52dEZo0pJ1Ie4up8xxXKeoqfO3WSVDeRpj/n
|
||||||
|
0tYSALhOCdGn0RMav5wfZmxdfZpKUhBrcxFfeiDB5c7xdlnziHrY5lqSQPCHxAQb
|
||||||
|
S1jMaV4adhxDzF56t5RU6/5eWPZ4IvlTRtYmNwIDAQABAoIBAAb0r28XxNZ011O6
|
||||||
|
ojCqFj3afPNGgQV8pbWrw+2luLSsiv9vbn6Q0gsj8wc6XYISrXAq8fl+NFHqndsj
|
||||||
|
8H4JL8nZ/PUHSZrc6vxo4ygy6f4X6UP9iyKz/NOGPbF7jeqe1H/vp5tNNbhVB2ih
|
||||||
|
QL+QAF653El8XTtOIgxnb3KBOYqZ6e0rWvC5XlZrfT4EGqpokW4zQ6ROQUbnWyCk
|
||||||
|
LC4CtQpcLLd7fdGfA2cB2xDdGJ3Er8gAnU/X+tAtcghWanoNARKGU6opyGpwhipe
|
||||||
|
+31CivIUhtASWdbS73ay5QaDQSlgNM1/2hk5Beal7D9bGfKtwT/VGDSpKc4EKP8j
|
||||||
|
ktQSE0ECgYEA/jHMLQyvJ2VuqBdMI5hbaw5jzUAQwaJof5iQNuvFrbtWDeotAf+6
|
||||||
|
HomwoqzZ9+juiil4PHLQJzkArHwMWXbc+3FAznN1foS+YlOmIgJrjKa+EP+sz/X2
|
||||||
|
GxuyH3RD9+TH4EGd4TbeDr0eZOnIbKVybj4ueE+um7jtdLzYW2Y8iCcCgYEA6Qu6
|
||||||
|
x5WOQaPaEOQwEP5AqVBZnZl1ogeEVanlPYl6amPFFnlc41+M61p3ebwRqikaC9Dv
|
||||||
|
hePiOcTTJyt4h7qzgd5rJTjy5bNYDx9F61NGagF0xJLQiMnXM/TsoFABVWetLepG
|
||||||
|
DTzgvCf7wmB9QTgdLct7KyG4suDBJlEAvr70q3ECgYEAxx4pC0z5U4oAMYn2aZeq
|
||||||
|
XOUrxpcdySC4bOMMbQkpk1rBIStEUGGK4OsIw5VVNP5xBSdQ+UESzva3EWYmoloa
|
||||||
|
5pgjpNUKv62qGQnfhJqStt3S2yv8qfbI7xk14a/IokHDVGbyDn5VWgRI79G1322G
|
||||||
|
gtcQvcvlQjSNRbm8XXRrjFcCgYA66x1Awl3h2IQUSyyfzzgX1lmhz59+5HmfksGD
|
||||||
|
SlOpvCmi4fILBihBhHC6VUL+C0ArhppX9mJGiq17tLDXV+t0RQA/u+MlEa+MuzJZ
|
||||||
|
KYee21ljLV8NhkIjP6Pnb/K2XezZs+YcCK0kxNMQtIZWS9KMtmogYHkquEn83vPa
|
||||||
|
Rbrj8QKBgHifm6Z9F4qTz2b2RsYPoMHOdsX0DrZ8xQOH8jioTAy/Xi2hrL5Klp7h
|
||||||
|
zaLifWtOdtckFxIk+6D/zLLn1icC7cc8n4TMwQ1ikY+9IPnkTXVx4b/r/NSbAVxZ
|
||||||
|
J821mkhGdqKJGAzk6uh/Sn4rNGubH+I1x2Xa9hWbARCLsj8tp6TX
|
||||||
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
|
||||||
|
var serverCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDHzCCAgegAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19zZXJ2
|
||||||
|
ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnZvhvIgmlQPJMqjkW
|
||||||
|
IJrkSSLLsIJ3xSiV5KiZCOHnNkawhuDP1GqNpMwsXSOpvOH2LHYNBKdj7DfYuo8z
|
||||||
|
aw4rX79q2Z4Jryblu9mtGgPE/ZPelAdPJ7QL1YjuOqiyYyq5EVqRpjU4PENE9YX0
|
||||||
|
JGCEUXrY1wd+fO1basyIRi24NGRkaykkv8Hk4DMSAuviI/xMoyWpK6FpCGLnZ0Rm
|
||||||
|
jSknUh7i6nzHFcp6ip87dZJUN5GmP+fS1hIAuE4J0afRExq/nB9mbF19mkpSEGtz
|
||||||
|
EV96IMHlzvF2WfOIetjmWpJA8IfEBBtLWMxpXhp2HEPMXnq3lFTr/l5Y9ngi+VNG
|
||||||
|
1iY3AgMBAAGjVTBTMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG
|
||||||
|
CCsGAQUFBwMCBggrBgEFBQcDATAaBgNVHREEEzARhwR/AAABgglsb2NhbGhvc3Qw
|
||||||
|
DQYJKoZIhvcNAQELBQADggEBAAeUHlNJiGfvhi8ts96javP8tO5gPkN7uErIMpzA
|
||||||
|
N1rf5Kdy7/LsxM6Uvwn0ns+p1vxANAjR/c0nfu0eIO1t5fKVDD0s9+ohKA/6phrm
|
||||||
|
xChTyl21mDZlFKjq0sjSwzBcUHPJjzUW9+AMDvS7pOjR5h4nD21LlMIkBzinl5KT
|
||||||
|
uo2Pm/OZqepPdM5XH9DaW0T0tjXKvRFe4FklJSKGD7f+T1whtmyziyA84YjYVa/6
|
||||||
|
gF+gpIOmPruJI9UoFqEncNpLfh5vKu2Vxv+maztFRhb+9gOg+nVBq1pxmMZV0PuM
|
||||||
|
L+tz0avIZEO2+KhgVGF3AF8HSZQHYcaskGFSGc8FxDKcDjM=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC+DCCAeCgAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEUwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla
|
||||||
|
GA8yMjk2MDEwODE1MzMyOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA52b4byIJpUDyTKo5FiCa5Ekiy7CCd8Uo
|
||||||
|
leSomQjh5zZGsIbgz9RqjaTMLF0jqbzh9ix2DQSnY+w32LqPM2sOK1+/atmeCa8m
|
||||||
|
5bvZrRoDxP2T3pQHTye0C9WI7jqosmMquRFakaY1ODxDRPWF9CRghFF62NcHfnzt
|
||||||
|
W2rMiEYtuDRkZGspJL/B5OAzEgLr4iP8TKMlqSuhaQhi52dEZo0pJ1Ie4up8xxXK
|
||||||
|
eoqfO3WSVDeRpj/n0tYSALhOCdGn0RMav5wfZmxdfZpKUhBrcxFfeiDB5c7xdlnz
|
||||||
|
iHrY5lqSQPCHxAQbS1jMaV4adhxDzF56t5RU6/5eWPZ4IvlTRtYmNwIDAQABozkw
|
||||||
|
NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI
|
||||||
|
KwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAGfCa0eCws/7+NYLJwVsdd7C/QHT
|
||||||
|
qbPw6w8oGnlXELMPwC701VFOcadhhengYCY1Kwa/KVu1ucFODDgp1ncvRoMVVWvD
|
||||||
|
/q6V07zu+aV/aW64zU27f+TzxTVXyCgfCSFUELJYBsBFWLw0K57ZDZdN2KJD+zD5
|
||||||
|
BAU0ghmy1DB+WSFMTqQ2iQaNX8oZh5jTZV3JtRNncqEqqIh4Nv7YYYZ02rgE7P2o
|
||||||
|
btVFYLBXHW7VYqnWpWM1pBfZpfGzMpGdR+1feST/88gUZh7ze15Ib4BlyU13v+0l
|
||||||
|
/BjuUsSWiITKWb2fqTiAkrqVbkOrC7Orz8yvgjuih4lEinQV1+KJUtcMmng=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var sha1ServerCertInter = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDITCCAgmgAwIBAgIUaVjtC++/JGFoZRtkpo/j5q1nQ/4wDQYJKoZIhvcNAQEF
|
||||||
|
BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN
|
||||||
|
MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs
|
||||||
|
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq
|
||||||
|
ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6
|
||||||
|
jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1
|
||||||
|
hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn
|
||||||
|
RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ
|
||||||
|
a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5
|
||||||
|
U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw
|
||||||
|
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z
|
||||||
|
dDANBgkqhkiG9w0BAQUFAAOCAQEATpiJFBwcRFIfZ9ffvS1WDzHqNElEnvocv/ul
|
||||||
|
3KVtoX4gmKRoOy344s3oJ5APPHYWUFuZVc3uofjW265r2uOW1Cb4P9yAtNc4htBS
|
||||||
|
+hYsdS3MQlzZCS9rItaT25R6Ieq5TbHGRCof387jzvo1NNhcAQ5akQlQKI87km77
|
||||||
|
VzoEBdAw68Q0ZE+X34Q9eAA44oCcLAgCpGvs6hQuUSInribSR3vtsjuaLjdJ5F1f
|
||||||
|
GCu2QGM4cVLaezmoa1J54ETZggT2xFw2IyWJ2g/kXFpo+HnoyaDrPthud3Pe5xEt
|
||||||
|
JMzX0s3jPSjfeAv34Pr37s0Or18r1bS1hrgxE0SV2vk31fsImg==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var serverCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDITCCAgmgAwIBAgIUfSzzygvth1xlpa9DtyGpHuY2V+swDQYJKoZIhvcNAQEL
|
||||||
|
BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN
|
||||||
|
MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs
|
||||||
|
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq
|
||||||
|
ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6
|
||||||
|
jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1
|
||||||
|
hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn
|
||||||
|
RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ
|
||||||
|
a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5
|
||||||
|
U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw
|
||||||
|
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z
|
||||||
|
dDANBgkqhkiG9w0BAQsFAAOCAQEAwe/JUeIiJ5ugiO4tM0ZtvgHuFC3hK+ZWndRE
|
||||||
|
z4JfVXTW9soxpa/cOU9QdJhZzouIu9yqZasY4zSEerC1e6grBYP95vMbN6xUAown
|
||||||
|
wNzrQzyJ6yP526txiIdOkKf+yVNdz0OWNHMPtwTWIr8kKGK23ABF94aUa0VlkErp
|
||||||
|
Qrd8NQ3guIPI+/upuxirJCFdhE+U3U0pLHpGaGvhkOytfnLYiINwR9norVCDGbQG
|
||||||
|
ITH0tOz8gVWWWwxa9s5CmbqTnasgUMDh1jHa5xOo+riX8H5lwQUaItKU1JM+QMIR
|
||||||
|
6Z+M0Isdw647A6tmX7DqNcmHlBKxPN1GDcVXalwYJUoXwTb9Hw==
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
// Test_checkForHostnameError tests that the upstream message for remote server
|
||||||
|
// certificate's hostname hasn't changed when no SAN extension is present and that
|
||||||
|
// the metrics counter increases properly when such an error is encountered
|
||||||
|
//
|
||||||
|
// Requires GODEBUG=x509ignoreCN=0 to not be set in the environment
|
||||||
|
func TestCheckForHostnameError(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
serverCert []byte
|
||||||
|
counterIncrease bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no SAN",
|
||||||
|
serverCert: serverCertNoSAN,
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with SAN",
|
||||||
|
serverCert: serverCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the test metrics
|
||||||
|
x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkForHostnameError"})
|
||||||
|
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
||||||
|
registry.MustRegister(x509MissingSANCounter)
|
||||||
|
sanChecker := NewSANDeprecatedChecker(x509MissingSANCounter)
|
||||||
|
|
||||||
|
var lastCounterVal int
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tlsServer, serverURL := testServer(t, tt.serverCert)
|
||||||
|
defer tlsServer.Close()
|
||||||
|
|
||||||
|
client := tlsServer.Client()
|
||||||
|
req, err := http.NewRequest(http.MethodGet, serverURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create an http request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.Transport.RoundTrip(req)
|
||||||
|
|
||||||
|
if sanChecker.CheckRoundTripError(err) {
|
||||||
|
sanChecker.IncreaseMetricsCounter(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkForHostnameError")
|
||||||
|
if errorCounterVal == -1 {
|
||||||
|
t.Fatalf("failed to get the error counter from the registry")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
||||||
|
t.Errorf("expected the Test_checkForHostnameError metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
||||||
|
t.Errorf("expected the Test_checkForHostnameError metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCounterVal = errorCounterVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckRespForNoSAN(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
serverCert []byte
|
||||||
|
counterIncrease bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no SAN",
|
||||||
|
serverCert: serverCertNoSAN,
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with SAN",
|
||||||
|
serverCert: serverCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the test metrics
|
||||||
|
x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkRespForNoSAN"})
|
||||||
|
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
||||||
|
registry.MustRegister(x509MissingSANCounter)
|
||||||
|
sanChecker := NewSANDeprecatedChecker(x509MissingSANCounter)
|
||||||
|
|
||||||
|
var lastCounterVal int
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var tlsConnectionState *tls.ConnectionState
|
||||||
|
if tt.serverCert != nil {
|
||||||
|
block, _ := pem.Decode([]byte(tt.serverCert))
|
||||||
|
if block == nil {
|
||||||
|
t.Fatal("failed to parse certificate PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCert, err := x509.ParseCertificate(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse certificate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConnectionState = &tls.ConnectionState{
|
||||||
|
PeerCertificates: []*x509.Certificate{serverCert},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := &http.Response{
|
||||||
|
TLS: tlsConnectionState,
|
||||||
|
}
|
||||||
|
|
||||||
|
if sanChecker.CheckPeerCertificates(resp.TLS.PeerCertificates) {
|
||||||
|
sanChecker.IncreaseMetricsCounter(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkRespForNoSAN")
|
||||||
|
if errorCounterVal == -1 {
|
||||||
|
t.Fatalf("failed to get the error counter from the registry")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
||||||
|
t.Errorf("expected the Test_checkRespForNoSAN metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
||||||
|
t.Errorf("expected the Test_checkRespForNoSAN metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCounterVal = errorCounterVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckForInsecureAlgorithmError(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
serverCert []byte
|
||||||
|
counterIncrease bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "server cert sha1-signed",
|
||||||
|
serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "intermediate CA cert sha1-signed",
|
||||||
|
serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different error - cert untrusted, intermediate not in returned chain",
|
||||||
|
serverCert: serverCertInterSHA1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "properly signed",
|
||||||
|
serverCert: serverCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the test metrics
|
||||||
|
x509SHA1SignatureCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkForInsecureAlgorithmError"})
|
||||||
|
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
||||||
|
registry.MustRegister(x509SHA1SignatureCounter)
|
||||||
|
sha1checker := NewSHA1SignatureDeprecatedChecker(x509SHA1SignatureCounter)
|
||||||
|
|
||||||
|
var lastCounterVal int
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tlsServer, serverURL := testServer(t, tt.serverCert)
|
||||||
|
defer tlsServer.Close()
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodGet, serverURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create an http request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't use tlsServer.Client() as it contains the server certificate
|
||||||
|
// in tls.Config.Certificates. The signatures are, however, only checked
|
||||||
|
// during building a candidate verification certificate chain and
|
||||||
|
// if the content of tls.Config.Certificates matches the certificate
|
||||||
|
// returned by the server, this short-circuits and the signature verification is
|
||||||
|
// never performed.
|
||||||
|
caPool := x509.NewCertPool()
|
||||||
|
require.True(t, caPool.AppendCertsFromPEM(caCert))
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
RootCAs: caPool,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.Transport.RoundTrip(req)
|
||||||
|
|
||||||
|
if sha1checker.CheckRoundTripError(err) {
|
||||||
|
sha1checker.IncreaseMetricsCounter(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkForInsecureAlgorithmError")
|
||||||
|
if errorCounterVal == -1 {
|
||||||
|
t.Fatalf("failed to get the error counter from the registry")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
||||||
|
t.Errorf("expected the Test_checkForInsecureAlgorithmError metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
||||||
|
t.Errorf("expected the Test_checkForInsecureAlgorithmError metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCounterVal = errorCounterVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckRespSHA1SignedCert(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
serverCert []byte
|
||||||
|
counterIncrease bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "server cert sha1-signed",
|
||||||
|
serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "intermediate CA cert sha1-signed",
|
||||||
|
serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "properly signed",
|
||||||
|
serverCert: serverCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the test metrics
|
||||||
|
x509SHA1SignatureCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkRespSHA1SignedCert"})
|
||||||
|
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
||||||
|
registry.MustRegister(x509SHA1SignatureCounter)
|
||||||
|
sha1checker := NewSHA1SignatureDeprecatedChecker(x509SHA1SignatureCounter)
|
||||||
|
|
||||||
|
var lastCounterVal int
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var tlsConnectionState *tls.ConnectionState
|
||||||
|
if tt.serverCert != nil {
|
||||||
|
peerCerts := []*x509.Certificate{}
|
||||||
|
for block, rest := pem.Decode([]byte(tt.serverCert)); block != nil; block, rest = pem.Decode(rest) {
|
||||||
|
cert, err := x509.ParseCertificate(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse certificate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
peerCerts = append(peerCerts, cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConnectionState = &tls.ConnectionState{
|
||||||
|
PeerCertificates: peerCerts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := &http.Response{
|
||||||
|
TLS: tlsConnectionState,
|
||||||
|
}
|
||||||
|
|
||||||
|
if sha1checker.CheckPeerCertificates(resp.TLS.PeerCertificates) {
|
||||||
|
sha1checker.IncreaseMetricsCounter(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkRespSHA1SignedCert")
|
||||||
|
if errorCounterVal == -1 {
|
||||||
|
t.Fatalf("failed to get the error counter from the registry")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
||||||
|
t.Errorf("expected the Test_checkRespSHA1SignedCert metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
||||||
|
t.Errorf("expected the Test_checkRespSHA1SignedCert metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCounterVal = errorCounterVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_x509DeprecatedCertificateMetricsRTWrapper_RoundTrip(t *testing.T) {
|
||||||
|
// register the test metrics
|
||||||
|
testCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "testCounter"})
|
||||||
|
registry := testutil.NewFakeKubeRegistry("0.0.0")
|
||||||
|
registry.MustRegister(testCounter)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
checkers []deprecatedCertificateAttributeChecker
|
||||||
|
resp *http.Response
|
||||||
|
err error
|
||||||
|
counterIncrease bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no error, resp w/ cert, no counter increase",
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{&testNegativeChecker{counterRaiser{testCounter, ""}}},
|
||||||
|
resp: httpResponseWithCert(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no error, resp w/o cert, no counter increase",
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}},
|
||||||
|
resp: httpResponseNoCert(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no error, resp w/ cert, counter increase",
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}},
|
||||||
|
resp: httpResponseWithCert(),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unrelated error, no resp, no counter increase",
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{&testNegativeChecker{counterRaiser{testCounter, ""}}},
|
||||||
|
err: fmt.Errorf("error"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "related error, no resp, counter increase",
|
||||||
|
checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}},
|
||||||
|
err: fmt.Errorf("error"),
|
||||||
|
counterIncrease: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastCounterVal int
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &x509DeprecatedCertificateMetricsRTWrapper{
|
||||||
|
rt: newTestRoundTripper(tt.resp, tt.err),
|
||||||
|
checkers: tt.checkers,
|
||||||
|
}
|
||||||
|
got, err := w.RoundTrip(&http.Request{})
|
||||||
|
if err != tt.err {
|
||||||
|
t.Errorf("x509DeprecatedCertificateMetricsRTWrapper.RoundTrip() should not mutate the error. Got %v, want %v", err, tt.err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.resp) {
|
||||||
|
t.Errorf("x509DeprecatedCertificateMetricsRTWrapper.RoundTrip() = should not mutate the response. Got %v, want %v", got, tt.resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "testCounter")
|
||||||
|
if errorCounterVal == -1 {
|
||||||
|
t.Fatalf("failed to get the error counter from the registry")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.counterIncrease && errorCounterVal != lastCounterVal+1 {
|
||||||
|
t.Errorf("expected the testCounter metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.counterIncrease && errorCounterVal != lastCounterVal {
|
||||||
|
t.Errorf("expected the testCounter metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCounterVal = errorCounterVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testRoundTripper func(req *http.Request) (*http.Response, error)
|
||||||
|
|
||||||
|
func (rt testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return rt(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestRoundTripper(resp *http.Response, err error) testRoundTripper {
|
||||||
|
return func(_ *http.Request) (*http.Response, error) {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testPositiveChecker struct {
|
||||||
|
counterRaiser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testPositiveChecker) CheckRoundTripError(_ error) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testPositiveChecker) CheckPeerCertificates(_ []*x509.Certificate) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type testNegativeChecker struct {
|
||||||
|
counterRaiser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testNegativeChecker) CheckRoundTripError(_ error) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testNegativeChecker) CheckPeerCertificates(_ []*x509.Certificate) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func httpResponseWithCert() *http.Response {
|
||||||
|
return &http.Response{
|
||||||
|
TLS: &tls.ConnectionState{
|
||||||
|
PeerCertificates: []*x509.Certificate{
|
||||||
|
{Issuer: pkix.Name{CommonName: "a name"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func httpResponseNoCert() *http.Response {
|
||||||
|
return &http.Response{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testServer(t *testing.T, serverCert []byte) (*httptest.Server, *url.URL) {
|
||||||
|
rootCAs := x509.NewCertPool()
|
||||||
|
rootCAs.AppendCertsFromPEM(caCert)
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair(serverCert, serverKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to init x509 cert/key pair: %v", err)
|
||||||
|
}
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
RootCAs: rootCAs,
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
w.WriteHeader(200)
|
||||||
|
w.Write([]byte("ok"))
|
||||||
|
}))
|
||||||
|
|
||||||
|
tlsServer.TLS = tlsConfig
|
||||||
|
tlsServer.StartTLS()
|
||||||
|
|
||||||
|
serverURL, err := url.Parse(tlsServer.URL)
|
||||||
|
if err != nil {
|
||||||
|
tlsServer.Close()
|
||||||
|
t.Fatalf("failed to parse the testserver URL: %v", err)
|
||||||
|
}
|
||||||
|
serverURL.Host = net.JoinHostPort("localhost", serverURL.Port())
|
||||||
|
|
||||||
|
return tlsServer, serverURL
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSingleCounterValueFromRegistry(t *testing.T, r metrics.Gatherer, name string) int {
|
||||||
|
mfs, err := r.Gather()
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("failed to gather local registry metrics: %v", err)
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mf := range mfs {
|
||||||
|
if mf.Name != nil && *mf.Name == name {
|
||||||
|
mfMetric := mf.GetMetric()
|
||||||
|
for _, m := range mfMetric {
|
||||||
|
if m.GetCounter() != nil {
|
||||||
|
return int(m.GetCounter().GetValue())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
@ -241,7 +241,10 @@ func (r *proxyHandler) updateAPIService(apiService *apiregistrationv1api.APIServ
|
|||||||
CAData: apiService.Spec.CABundle,
|
CAData: apiService.Spec.CABundle,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
clientConfig.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter))
|
clientConfig.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor(
|
||||||
|
x509MissingSANCounter,
|
||||||
|
x509InsecureSHA1Counter,
|
||||||
|
))
|
||||||
|
|
||||||
newInfo := proxyHandlingInfo{
|
newInfo := proxyHandlingInfo{
|
||||||
name: apiService.Name,
|
name: apiService.Name,
|
||||||
|
@ -34,6 +34,19 @@ var x509MissingSANCounter = metrics.NewCounter(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var x509InsecureSHA1Counter = metrics.NewCounter(
|
||||||
|
&metrics.CounterOpts{
|
||||||
|
Subsystem: "kube_aggregator",
|
||||||
|
Namespace: "apiserver",
|
||||||
|
Name: "x509_insecure_sha1_total",
|
||||||
|
Help: "Counts the number of requests to servers with insecure SHA1 signatures " +
|
||||||
|
"in their serving certificate OR the number of connection failures " +
|
||||||
|
"due to the insecure SHA1 signatures (either/or, based on the runtime environment)",
|
||||||
|
StabilityLevel: metrics.ALPHA,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
legacyregistry.MustRegister(x509MissingSANCounter)
|
legacyregistry.MustRegister(x509MissingSANCounter)
|
||||||
|
legacyregistry.MustRegister(x509InsecureSHA1Counter)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user