Open haykharut opened 1 year ago
For reference:
Here is my script that makes the cert + key:
import datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
def generate_cert(org, dns_names, common_name):
# Init CA config
ca = (
x509.CertificateBuilder(
issuer_name=x509.Name(
[x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, org)]
),
subject_name=x509.Name(
[x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, org)]
),
serial_number=2022,
not_valid_before=datetime.datetime.utcnow(),
not_valid_after=datetime.datetime.utcnow() + datetime.timedelta(days=365),
public_key=rsa.generate_private_key(
public_exponent=65537, key_size=4096
).public_key(),
)
.add_extension(
x509.BasicConstraints(ca=True, path_length=None),
critical=True,
)
.add_extension(
x509.KeyUsage(
digital_signature=True,
content_commitment=False,
key_encipherment=False,
data_encipherment=False,
key_agreement=False,
key_cert_sign=True,
crl_sign=False,
encipher_only=False,
decipher_only=False,
),
critical=True,
)
.add_extension(
x509.ExtendedKeyUsage(
[
x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH,
x509.oid.ExtendedKeyUsageOID.SERVER_AUTH,
]
),
critical=False,
)
)
# Sign CA and generate public key in PEM format
ca_pem = ca.sign(
private_key=rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
),
algorithm=hashes.SHA256(),
).public_bytes(encoding=serialization.Encoding.PEM)
# generate new private key
new_private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
)
# New certificate config
new_cert = x509.CertificateBuilder(
serial_number=2022,
issuer_name=x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, common_name),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, org),
]
),
subject_name=x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, common_name),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, org),
]
),
not_valid_before=datetime.datetime.utcnow(),
not_valid_after=datetime.datetime.utcnow() + datetime.timedelta(days=365),
public_key=new_private_key.public_key(),
)
new_cert = new_cert.add_extension(
x509.SubjectAlternativeName([x509.DNSName(dns_name) for dns_name in dns_names]),
critical=False,
)
new_cert = new_cert.add_extension(
x509.KeyUsage(
digital_signature=True,
key_encipherment=False,
content_commitment=False,
key_agreement=False,
data_encipherment=False,
key_cert_sign=True,
crl_sign=False,
encipher_only=False,
decipher_only=False,
),
critical=True,
)
# sign the new certificate and encode to PEM
new_cert_pem = new_cert.sign(
private_key=new_private_key,
algorithm=hashes.SHA256(),
backend=default_backend(),
).public_bytes(serialization.Encoding.PEM)
# new private key PEM encoded
new_private_key_pem = new_private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
return ca_pem, new_cert_pem, new_private_key_pem
And here is where my webhook config
def create_or_update_mutating_webhook_configuration(
ca_pem, webhook_service, webhook_namespace
):
# Initialize the kube client
clientset = client.ApiClient(config.load_incluster_config())
# Create or update the mutatingwebhookconfiguration
apiclient = AdmissionregistrationV1Api(api_client=clientset)
mutating_webhook_config = client.V1MutatingWebhookConfiguration(
metadata=client.V1ObjectMeta(name=webhook_config_name),
webhooks=[
client.V1MutatingWebhook(
name="mywebhook",
admission_review_versions=["v1", "v1beta1"],
side_effects="None",
client_config=client.AdmissionregistrationV1WebhookClientConfig(
ca_bundle=ca_pem, # self-generated CA for the webhook
service=client.AdmissionregistrationV1ServiceReference(
name=webhook_service,
namespace=webhook_namespace,
path="/mutate",
),
),
rules=[
client.V1RuleWithOperations(
operations=["CREATE", "UPDATE"],
api_groups=[""],
api_versions=["v1"],
resources=["pods"],
),
],
failure_policy="Fail",
)
],
)
Hi!
I have been trying to replicate your code in Python and have reached a point where I managed to :
1) create the certificates and a private key 2) create the webhookconfiguration in the cluster
The problem I have is that the certificate is not recognized:
failed to call webhook: Post "...svc:443/mutate?timeout=10s": x509: certificate signed by unknown authority
Looking at your code, I cannot find how the self-signed certificate is made recognizable to kubernetes. I can see that :
There are 2 CA configs in the script and 2 certificates made. The first is passed to the webhook configuration and the second is used in the webserver together with the private key. I do not quite understand why this is enough for kubernetes to recognize the certificate signer. Isn't there supposed to be a Certificate Signing Request made?