mirror of https://github.com/linkerd/linkerd2.git
Proxy: Get identity of pod & controller from configuration. (#1221)
Instead of attempting to construct identities itself, have the proxy accept fully-formed identities from whatever configures it. This allows us to centralize the formatting of the identity strings in the Go code that is shared between the `conduit inject`, `conduit install`, and CA components. One wrinkle: The pod namespace isn't necessarily available at `conduit inject` time, so the proxy must implement a simple variable substitution mechanism to insert the pod namespace into its identity. This has the side-effect of enabling TLS to the controller since the controller's identity is now available. Signed-off-by: Brian Smith <brian@briansmith.org>
This commit is contained in:
parent
cca8e7077d
commit
afbc88ac44
|
@ -187,10 +187,12 @@ pub const ENV_OUTBOUND_PORTS_DISABLE_PROTOCOL_DETECTION: &str = "CONDUIT_PROXY_O
|
|||
pub const ENV_TLS_TRUST_ANCHORS: &str = "CONDUIT_PROXY_TLS_TRUST_ANCHORS";
|
||||
pub const ENV_TLS_CERT: &str = "CONDUIT_PROXY_TLS_CERT";
|
||||
pub const ENV_TLS_PRIVATE_KEY: &str = "CONDUIT_PROXY_TLS_PRIVATE_KEY";
|
||||
pub const ENV_TLS_POD_IDENTITY: &str = "CONDUIT_PROXY_TLS_POD_IDENTITY";
|
||||
pub const ENV_TLS_CONTROLLER_IDENTITY: &str = "CONDUIT_PROXY_TLS_CONTROLLER_IDENTITY";
|
||||
|
||||
pub const ENV_CONTROLLER_NAMESPACE: &str = "CONDUIT_PROXY_CONTROLLER_NAMESPACE";
|
||||
pub const ENV_POD_NAME: &str = "CONDUIT_PROXY_POD_NAME";
|
||||
pub const ENV_POD_NAMESPACE: &str = "CONDUIT_PROXY_POD_NAMESPACE";
|
||||
pub const VAR_POD_NAMESPACE: &str = "$CONDUIT_PROXY_POD_NAMESPACE";
|
||||
|
||||
pub const ENV_CONTROL_URL: &str = "CONDUIT_PROXY_CONTROL_URL";
|
||||
const ENV_RESOLV_CONF: &str = "CONDUIT_RESOLV_CONF";
|
||||
|
@ -271,13 +273,14 @@ impl<'a> TryFrom<&'a Strings> for Config {
|
|||
let tls_trust_anchors = parse(strings, ENV_TLS_TRUST_ANCHORS, parse_path);
|
||||
let tls_end_entity_cert = parse(strings, ENV_TLS_CERT, parse_path);
|
||||
let tls_private_key = parse(strings, ENV_TLS_PRIVATE_KEY, parse_path);
|
||||
let tls_pod_identity_template = strings.get(ENV_TLS_POD_IDENTITY);
|
||||
let tls_controller_identity = strings.get(ENV_TLS_CONTROLLER_IDENTITY);
|
||||
let bind_timeout = parse(strings, ENV_BIND_TIMEOUT, parse_duration);
|
||||
let resolv_conf_path = strings.get(ENV_RESOLV_CONF);
|
||||
let event_buffer_capacity = parse(strings, ENV_EVENT_BUFFER_CAPACITY, parse_number);
|
||||
let metrics_retain_idle = parse(strings, ENV_METRICS_RETAIN_IDLE, parse_duration);
|
||||
let dns_min_ttl = parse(strings, ENV_DNS_MIN_TTL, parse_duration);
|
||||
let dns_max_ttl = parse(strings, ENV_DNS_MAX_TTL, parse_duration);
|
||||
let pod_name = strings.get(ENV_POD_NAME);
|
||||
let pod_namespace = strings.get(ENV_POD_NAMESPACE).and_then(|maybe_value| {
|
||||
// There cannot be a default pod namespace, and the pod namespace is required.
|
||||
maybe_value.ok_or_else(|| {
|
||||
|
@ -299,23 +302,35 @@ impl<'a> TryFrom<&'a Strings> for Config {
|
|||
let tls_settings = match (tls_trust_anchors?,
|
||||
tls_end_entity_cert?,
|
||||
tls_private_key?,
|
||||
pod_name?.as_ref())
|
||||
tls_pod_identity_template?.as_ref(),
|
||||
tls_controller_identity?)
|
||||
{
|
||||
(Some(trust_anchors),
|
||||
Some(end_entity_cert),
|
||||
Some(private_key),
|
||||
Some(pod_name)) => {
|
||||
let service_identity = tls::Identity::try_from_pod_name(&namespaces, pod_name)
|
||||
Some(tls_pod_identity_template),
|
||||
controller_identity) => {
|
||||
let pod_identity =
|
||||
tls_pod_identity_template.replace(VAR_POD_NAMESPACE, &namespaces.pod);
|
||||
let pod_identity = tls::Identity::from_sni_hostname(pod_identity.as_bytes())
|
||||
.map_err(|_| Error::InvalidEnvVar)?; // Already logged.
|
||||
let controller_identity = if let Some(controller_identity) = &controller_identity {
|
||||
let identity = tls::Identity::from_sni_hostname(controller_identity.as_bytes())
|
||||
.map_err(|_| Error::InvalidEnvVar)?; // Already logged.
|
||||
Conditional::Some(identity)
|
||||
} else {
|
||||
Conditional::None(tls::ReasonForNoIdentity::NotConfigured)
|
||||
};
|
||||
Ok(Conditional::Some(tls::CommonSettings {
|
||||
trust_anchors,
|
||||
end_entity_cert,
|
||||
private_key,
|
||||
service_identity,
|
||||
pod_identity,
|
||||
controller_identity,
|
||||
}))
|
||||
},
|
||||
(None, None, None, _) => Ok(Conditional::None(tls::ReasonForNoTls::Disabled)),
|
||||
(trust_anchors, end_entity_cert, private_key, pod_name) => {
|
||||
(None, None, None, _, _) => Ok(Conditional::None(tls::ReasonForNoTls::Disabled)),
|
||||
(trust_anchors, end_entity_cert, private_key, pod_identity, _) => {
|
||||
if trust_anchors.is_none() {
|
||||
error!("{} is not set; it is required when {} and {} are set.",
|
||||
ENV_TLS_TRUST_ANCHORS, ENV_TLS_CERT, ENV_TLS_PRIVATE_KEY);
|
||||
|
@ -328,9 +343,9 @@ impl<'a> TryFrom<&'a Strings> for Config {
|
|||
error!("{} is not set; it is required when {} are set.",
|
||||
ENV_TLS_PRIVATE_KEY, ENV_TLS_TRUST_ANCHORS);
|
||||
}
|
||||
if pod_name.is_none() {
|
||||
if pod_identity.is_none() {
|
||||
error!("{} is not set; it is required when {} are set.",
|
||||
ENV_POD_NAME, ENV_TLS_CERT);
|
||||
ENV_TLS_POD_IDENTITY, ENV_TLS_CERT);
|
||||
}
|
||||
Err(Error::InvalidEnvVar)
|
||||
},
|
||||
|
|
|
@ -232,8 +232,14 @@ where
|
|||
&taps,
|
||||
);
|
||||
|
||||
let controller_tls =
|
||||
Conditional::None(tls::ReasonForNoIdentity::NotImplementedForController.into()); // TODO
|
||||
let controller_tls = config.tls_settings.as_ref().and_then(|settings| {
|
||||
settings.controller_identity.as_ref().map(|controller_identity| {
|
||||
tls::ConnectionConfig {
|
||||
identity: controller_identity.clone(),
|
||||
config: tls_client_config.clone(),
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let (dns_resolver, dns_bg) = dns::Resolver::from_system_config_and_env(&config)
|
||||
.unwrap_or_else(|e| {
|
||||
|
@ -267,7 +273,7 @@ where
|
|||
);
|
||||
let tls_settings = config.tls_settings.as_ref().map(|settings| {
|
||||
tls::ConnectionConfig {
|
||||
identity: settings.service_identity.clone(),
|
||||
identity: settings.pod_identity.clone(),
|
||||
config: tls_server_config
|
||||
}
|
||||
});
|
||||
|
|
|
@ -43,9 +43,12 @@ pub struct CommonSettings {
|
|||
/// The private key in DER-encoded PKCS#8 form.
|
||||
pub private_key: PathBuf,
|
||||
|
||||
/// The identity we use to identify the service being proxied (as opposed
|
||||
/// to the psuedo-service exposed on the proxy's control port).
|
||||
pub service_identity: Identity,
|
||||
/// The identity of the pod being proxied (as opposed to the psuedo-service
|
||||
/// exposed on the proxy's control port).
|
||||
pub pod_identity: Identity,
|
||||
|
||||
/// The identity of the controller, if given.
|
||||
pub controller_identity: Conditional<Identity, ReasonForNoIdentity>,
|
||||
}
|
||||
|
||||
/// Validated configuration common between TLS clients and TLS servers.
|
||||
|
@ -116,9 +119,8 @@ pub enum ReasonForNoIdentity {
|
|||
/// of telling us that we shouldn't do TLS for this endpoint.
|
||||
NotProvidedByServiceDiscovery,
|
||||
|
||||
/// We haven't implemented the mechanism to construct a TLS identity for
|
||||
/// the controller yet.
|
||||
NotImplementedForController,
|
||||
/// The proxy wasn't configured with the identity.
|
||||
NotConfigured,
|
||||
|
||||
/// We haven't implemented the mechanism to construct a TLs identity for
|
||||
/// the tap psuedo-service yet.
|
||||
|
@ -236,15 +238,20 @@ impl CommonConfig {
|
|||
rustls::ClientConfig::new().get_verifier().verify_server_cert(
|
||||
&root_cert_store,
|
||||
&cert_chain,
|
||||
settings.service_identity.as_dns_name_ref(),
|
||||
settings.pod_identity.as_dns_name_ref(),
|
||||
&[]) // No OCSP
|
||||
.map(|_| ())
|
||||
.map_err(Error::EndEntityCertIsNotValid)?;
|
||||
.map_err(|err| {
|
||||
error!("validating certificate failed for {:?}: {}", settings.pod_identity, err);
|
||||
Error::EndEntityCertIsNotValid(err)
|
||||
})?;
|
||||
|
||||
// `CertResolver::new` is responsible for verifying that the
|
||||
// private key is the right one for the certificate.
|
||||
let cert_resolver = CertResolver::new(certificate_was_validated, cert_chain, private_key)?;
|
||||
|
||||
info!("loaded TLS configuration.");
|
||||
|
||||
Ok(Self {
|
||||
root_cert_store,
|
||||
cert_resolver: Arc::new(cert_resolver),
|
||||
|
@ -414,22 +421,18 @@ pub(super) const SIGNATURE_ALG_RUSTLS_ALGORITHM: rustls::internal::msgs::enums::
|
|||
mod test_util {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use config::Namespaces;
|
||||
use tls::{CommonSettings, Identity};
|
||||
use conditional::Conditional;
|
||||
use tls::{CommonSettings, Identity, ReasonForNoIdentity};
|
||||
|
||||
pub struct Strings {
|
||||
pub pod_name: &'static str,
|
||||
pub pod_ns: &'static str,
|
||||
pub controller_ns: &'static str,
|
||||
pub identity: &'static str,
|
||||
pub trust_anchors: &'static str,
|
||||
pub end_entity_cert: &'static str,
|
||||
pub private_key: &'static str,
|
||||
}
|
||||
|
||||
pub static FOO_NS1: Strings = Strings {
|
||||
pod_name: "foo",
|
||||
pod_ns: "ns1",
|
||||
controller_ns: "conduit",
|
||||
identity: "foo.deployment.ns1.conduit-managed.conduit.svc.cluster.local",
|
||||
trust_anchors: "ca1.pem",
|
||||
end_entity_cert: "foo-ns1-ca1.crt",
|
||||
private_key: "foo-ns1-ca1.p8",
|
||||
|
@ -438,16 +441,12 @@ mod test_util {
|
|||
impl Strings {
|
||||
pub fn to_settings(&self) -> CommonSettings {
|
||||
let dir = PathBuf::from("src/transport/tls/testdata");
|
||||
let namespaces = Namespaces {
|
||||
pod: self.pod_ns.into(),
|
||||
tls_controller: Some(self.controller_ns.into()),
|
||||
};
|
||||
let service_identity = Identity::try_from_pod_name(&namespaces, self.pod_name).unwrap();
|
||||
CommonSettings {
|
||||
pod_identity: Identity::from_sni_hostname(self.identity.as_bytes()).unwrap(),
|
||||
controller_identity: Conditional::None(ReasonForNoIdentity::NotConfigured),
|
||||
trust_anchors: dir.join(self.trust_anchors),
|
||||
end_entity_cert: dir.join(self.end_entity_cert),
|
||||
private_key: dir.join(self.private_key),
|
||||
service_identity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,12 +468,8 @@ mod tests {
|
|||
#[test]
|
||||
fn recognize_ca_did_not_issue_cert() {
|
||||
let settings = Strings {
|
||||
pod_name: "foo",
|
||||
pod_ns: "ns1",
|
||||
controller_ns: "conduit",
|
||||
trust_anchors: "ca2.pem", // Mismatch
|
||||
end_entity_cert: "foo-ns1-ca1.crt",
|
||||
private_key: "foo-ns1-ca1.p8",
|
||||
trust_anchors: "ca2.pem",
|
||||
..FOO_NS1
|
||||
}.to_settings();
|
||||
match CommonConfig::load_from_disk(&settings) {
|
||||
Err(Error::EndEntityCertIsNotValid(_)) => (),
|
||||
|
@ -485,12 +480,9 @@ mod tests {
|
|||
#[test]
|
||||
fn recognize_cert_is_not_valid_for_identity() {
|
||||
let settings = Strings {
|
||||
pod_name: "foo", // Mismatch
|
||||
pod_ns: "ns1",
|
||||
controller_ns: "conduit",
|
||||
trust_anchors: "ca1.pem",
|
||||
end_entity_cert: "bar-ns1-ca1.crt",
|
||||
private_key: "bar-ns1-ca1.p8",
|
||||
..FOO_NS1
|
||||
}.to_settings();
|
||||
match CommonConfig::load_from_disk(&settings) {
|
||||
Err(Error::EndEntityCertIsNotValid(_)) => (),
|
||||
|
@ -503,12 +495,8 @@ mod tests {
|
|||
#[should_panic]
|
||||
fn recognize_private_key_is_not_valid_for_cert() {
|
||||
let settings = Strings {
|
||||
pod_name: "foo",
|
||||
pod_ns: "ns1",
|
||||
controller_ns: "conduit",
|
||||
trust_anchors: "ca1.pem",
|
||||
end_entity_cert: "foo-ns1-ca1.crt",
|
||||
private_key: "bar-ns1-ca1.p8", // Mismatch
|
||||
private_key: "bar-ns1-ca1.p8",
|
||||
..FOO_NS1
|
||||
}.to_settings();
|
||||
match CommonConfig::load_from_disk(&settings) {
|
||||
Err(_) => (), // // TODO: Err(Error::InvalidPrivateKey) > (),
|
||||
|
|
|
@ -2,7 +2,6 @@ use conduit_proxy_controller_grpc;
|
|||
use convert::TryFrom;
|
||||
use super::{DnsName, InvalidDnsName, webpki};
|
||||
use std::sync::Arc;
|
||||
use config::Namespaces;
|
||||
|
||||
/// An endpoint's identity.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -36,46 +35,6 @@ impl Identity {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn try_from_pod_name(namespaces: &Namespaces, pod_name: &str) -> Result<Self, ()> {
|
||||
// Verifies that the string doesn't contain '.' so that it is safe to
|
||||
// join it using '.' to try to form a DNS name. The rest of the DNS
|
||||
// name rules will be enforced by `DnsName::try_from`.
|
||||
fn check_single_label(value: &str, name: &str) -> Result<(), ()> {
|
||||
if !value.contains('.') {
|
||||
Ok(())
|
||||
} else {
|
||||
error!("Invalid {}: {:?}", name, value);
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
let controller_ns = if let Some(controller_ns) = &namespaces.tls_controller {
|
||||
controller_ns
|
||||
} else {
|
||||
error!("controller namespace not provided");
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// Log any/any per-component errors before returning.
|
||||
let controller_ns_check = check_single_label(controller_ns, "controller namespace");
|
||||
let pod_ns_check = check_single_label(&namespaces.pod, "pod namespace");
|
||||
let pod_name_check = check_single_label(pod_name, "pod name");
|
||||
if controller_ns_check.is_err() || pod_ns_check.is_err() || pod_name_check.is_err() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// We reserve all names under a fake "managed-pods" service in
|
||||
// our namespace for identifying pods by name.
|
||||
let name = format!(
|
||||
"{pod}.{pod_ns}.conduit-managed-pods.{controller_ns}.svc.cluster.local",
|
||||
pod = pod_name,
|
||||
pod_ns = &namespaces.pod,
|
||||
controller_ns = controller_ns,
|
||||
);
|
||||
|
||||
Self::from_sni_hostname(name.as_bytes())
|
||||
}
|
||||
|
||||
pub fn from_sni_hostname(hostname: &[u8]) -> Result<Self, ()> {
|
||||
if hostname.last() == Some(&b'.') {
|
||||
return Err(()); // SNI hostnames are implicitly absolute.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: bar-deployment-tls-conduit-io
|
||||
data:
|
||||
certificate.crt: MIIB3TCCAYSgAwIBAgIUaXeuhu5/UwzmY82o6rnU5twTrtkwCgYIKoZIzj0EAwIwDzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0xOTA2MjcyMjM2MDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR2p2ps8aVtO818gwn5pk0lpOZtiSl0oynxYfxh05pe6XwdqQwQ6VKldZYyMAtOUZIMhrCWe9nJdn4sAaFZ7oFUo4HMMIHJMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUC7/6s+uRYILC6w1poW0w1j5OqDgwHwYDVR0jBBgwFoAUuBnxjXYU5QeUryEYIqJhbOGeHfcwSgYDVR0RAQH/BEAwPoI8YmFyLmRlcGxveW1lbnQubnMxLmNvbmR1aXQtbWFuYWdlZC5jb25kdWl0LnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0cAMEQCID0TUqbOV0hjWGUNDsI/g+GMoThog3TKRYy5CYCapbibAiAqfBKV8y34H9R74020sXH6HqCTFHY2y00c1ujOlLgS5g==
|
||||
private-key.p8: MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqdyV6IkoQeHj2421U7yXrW7DLkfyNwM8Y2UI5W4gHnuhRANCAAR2p2ps8aVtO818gwn5pk0lpOZtiSl0oynxYfxh05pe6XwdqQwQ6VKldZYyMAtOUZIMhrCWe9nJdn4sAaFZ7oFU
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIJ560iowWQ1mggSFMTg7m9S4drgBytWBrj2UX29s8sCsoAoGCCqGSM49
|
||||
AwEHoUQDQgAE5tRYXAFU8W3HRo4qJIKLtaONaENzDX3ttJebH6ZKEXUg2xDPMBTm
|
||||
7GO5EltrJBpGEwP+RL16SQxF82CxjbJ/6g==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -1,10 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYjCCAQigAwIBAgIUeNut9wWIX23pQjr5vp9CVjT5ckYwCgYIKoZIzj0EAwIw
|
||||
DzENMAsGA1UECxMETm9uZTAeFw0xODA2MTgyMDQ3MDBaFw0yMzA2MTcyMDQ3MDBa
|
||||
MA8xDTALBgNVBAsTBE5vbmUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATpX00P
|
||||
uIzqsJOyfF8j5KQxZwl7z8gwFRUOKS5pGYToLZRHknDCAM6+8atts+rlOCbRx3Ip
|
||||
BOE6/zl8mmgwDtHho0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
||||
/zAdBgNVHQ4EFgQUd6BIvpxr8rUL9quQelM8GiTv2h0wCgYIKoZIzj0EAwIDSAAw
|
||||
RQIhANh+WhsYerczLUi5fsZNOFVA+gTaYLaPfjkZ+xduaFnDAiBor7lB9XUt/1Xn
|
||||
J+2gLEkKlZnmoDx7EWOlnfK5/zkVMg==
|
||||
MIIBYjCCAQigAwIBAgIUXSnUsmTPZRbrF0r35e1o30XFwgowCgYIKoZIzj0EAwIw
|
||||
DzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0yMzA2MjYyMjM2MDBa
|
||||
MA8xDTALBgNVBAsTBE5vbmUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATm1Fhc
|
||||
AVTxbcdGjiokgou1o41oQ3MNfe20l5sfpkoRdSDbEM8wFObsY7kSW2skGkYTA/5E
|
||||
vXpJDEXzYLGNsn/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
||||
/zAdBgNVHQ4EFgQUuBnxjXYU5QeUryEYIqJhbOGeHfcwCgYIKoZIzj0EAwIDSAAw
|
||||
RQIhAKOH9hNtY0L29O8L5KBwwMT1g8m1v3dyW9eG31+4++rIAiBCZeDG/sdfU6ye
|
||||
Nz2RnIf0V7K8r5LE1ti7dHj9s5ipNg==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIMhxYa0qVqt+HIidzIxXirLr175Ipp+GvhmgXaUAsOf0oAoGCCqGSM49
|
||||
AwEHoUQDQgAEeEscd3LbZFKRU0063H1RRs+rNhroW8VBsJhBarY3pB4N/2+qsy5B
|
||||
vawmypQHGNBcSYXHJHWwUif8EAUAM6mfDg==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -1,10 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYTCCAQigAwIBAgIUeFHfUb7rtx5XqLkZCvGtBWl9dBwwCgYIKoZIzj0EAwIw
|
||||
DzENMAsGA1UECxMETm9uZTAeFw0xODA2MTgyMDQ3MDBaFw0yMzA2MTcyMDQ3MDBa
|
||||
MA8xDTALBgNVBAsTBE5vbmUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASeliXf
|
||||
Pezb5p/uCv2vHKyTcGY4fIJ/3EZNmImCoKsR2KBjNhOZY5hJNC0XIXscPFwuUKpe
|
||||
IkYBxLaz1N72VmnGo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
||||
/zAdBgNVHQ4EFgQUY9VEJcxsPngQJsJ0VC7ZDhjbWAgwCgYIKoZIzj0EAwIDRwAw
|
||||
RAIgS9lRS+ZSM5xCRx3V57zutoPrxaLqZjO3T7WxbgZXesQCIDpLonnDBl9lApMV
|
||||
X6SzSOuotZ6t2dz2bHSxw2KYLPK/
|
||||
MIIBYzCCAQigAwIBAgIUWmaYSTCFRog23pUsGVKlyDe75zUwCgYIKoZIzj0EAwIw
|
||||
DzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0yMzA2MjYyMjM2MDBa
|
||||
MA8xDTALBgNVBAsTBE5vbmUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR4Sxx3
|
||||
cttkUpFTTTrcfVFGz6s2GuhbxUGwmEFqtjekHg3/b6qzLkG9rCbKlAcY0FxJhcck
|
||||
dbBSJ/wQBQAzqZ8Oo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
||||
/zAdBgNVHQ4EFgQUwx+SFFiw81zahT/m0Q1/jvq1qXcwCgYIKoZIzj0EAwIDSQAw
|
||||
RgIhAO+LfUIi59+EJH8hY5fNwbFEwIqYNr0qTXtvmQA6uRMFAiEAuf9w3/g0SMo9
|
||||
ur3iPVbDOUjffCmUGRM3JU/mDpBAhZM=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: controller-deployment-tls-conduit-io
|
||||
data:
|
||||
certificate.crt: MIIB6TCCAY+gAwIBAgIUEps+dEyQhZ+odRrZ0SX440IIwJ0wCgYIKoZIzj0EAwIwDzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0xOTA2MjcyMjM2MDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARFgz6NL4cDmBQMs4jO947nwwSAjaR3NdbkA1nxWMZPCLZt4rew8trVtI2OzIsWMRBsYgE2TEZucbeSvMuvaYv4o4HXMIHUMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUStC4LpdbAY72Qcx+JMIZqDD6R0AwHwYDVR0jBBgwFoAUuBnxjXYU5QeUryEYIqJhbOGeHfcwVQYDVR0RAQH/BEswSYJHY29udHJvbGxlci5kZXBsb3ltZW50LmNvbmR1aXQuY29uZHVpdC1tYW5hZ2VkLmNvbmR1aXQuc3ZjLmNsdXN0ZXIubG9jYWwwCgYIKoZIzj0EAwIDSAAwRQIhAKymvovtMYPh+p1uHK4pibxv0tv3c1KiAsm155eMo+qVAiA8tLHg6LFa0KK0XnJsxg4s11RdP3GTHiE9JzHxE3S3NQ==
|
||||
private-key.p8: MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgT80odmjeMwYOXl5iXxmjG/ma5r4xPyCU1WPqQoDPiiChRANCAARFgz6NL4cDmBQMs4jO947nwwSAjaR3NdbkA1nxWMZPCLZt4rew8trVtI2OzIsWMRBsYgE2TEZucbeSvMuvaYv4
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: foo-deployment-tls-conduit-io
|
||||
data:
|
||||
certificate.crt: MIIB3jCCAYSgAwIBAgIUNWa2zxC5m7FEHkAUOGlLulewvIowCgYIKoZIzj0EAwIwDzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0xOTA2MjcyMjM2MDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASLybbtZElvkwIwqhAhEVvY/d7YXLiLQfHwr1zU9R6mu26VExfaUW/qYF1T8CzcvFTF+8sep5UHf0ZnFkZ6A0Qko4HMMIHJMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUSNwmOK6mgGGQ+drh2Wj5hzNlVgowHwYDVR0jBBgwFoAUuBnxjXYU5QeUryEYIqJhbOGeHfcwSgYDVR0RAQH/BEAwPoI8Zm9vLmRlcGxveW1lbnQubnMxLmNvbmR1aXQtbWFuYWdlZC5jb25kdWl0LnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIHhRnB+b/bAcCN4CDZ9JtpwxFGuu0Myi38XyDxCrtcxSAiEAudVtg4RAa0CMX+UEbCc+iEBdSNd6GzkLRuDr2SjhRcQ=
|
||||
private-key.p8: MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgJJN+QcHnTmCJswrXMnitL6HFy4XBB3KDjKgM8QwdhzGhRANCAASLybbtZElvkwIwqhAhEVvY/d7YXLiLQfHwr1zU9R6mu26VExfaUW/qYF1T8CzcvFTF+8sep5UHf0ZnFkZ6A0Qk
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: foo-deployment-tls-conduit-io
|
||||
data:
|
||||
certificate.crt: MIIB3jCCAYSgAwIBAgIUM+macpyHjf4dHSgqS4EDecbJZrswCgYIKoZIzj0EAwIwDzENMAsGA1UECxMETm9uZTAeFw0xODA2MjcyMjM2MDBaFw0xOTA2MjcyMjM2MDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASgHX7nCVBeUzcm6PNWDnXLDxNW7ybJYd1H3G+sRK0O5Aw/69Isx9ukYSQqNsP8Ou0TQaWAklP1OhmpoKXqbiUno4HMMIHJMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUoWY9k5H0zRWDemH+/st8zyKVqH0wHwYDVR0jBBgwFoAUwx+SFFiw81zahT/m0Q1/jvq1qXcwSgYDVR0RAQH/BEAwPoI8Zm9vLmRlcGxveW1lbnQubnMxLmNvbmR1aXQtbWFuYWdlZC5jb25kdWl0LnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIDzIH6l5DrE/SXXI3aKoc6JNLC3zV/WY6Zm/OIGvM6emAiEAj/hDuI7BBdyqhVv0JqL1toas/4x8HoNXs9s8VfPJucY=
|
||||
private-key.p8: MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgeBhuCVyWrqNnXNDDTSIaDX8saHX4I6Q7D41tJ1NZEhOhRANCAASgHX7nCVBeUzcm6PNWDnXLDxNW7ybJYd1H3G+sRK0O5Aw/69Isx9ukYSQqNsP8Ou0TQaWAklP1OhmpoKXqbiUn
|
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,9 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Requires:
|
||||
# go get -u github.com/cloudflare/cfssl/cmd/cfssl
|
||||
# go get -u github.com/cloudflare/cfssl/cmd/cfssljson
|
||||
#
|
||||
set -euox pipefail
|
||||
|
||||
ca() {
|
||||
|
@ -7,12 +12,19 @@ ca() {
|
|||
echo '{"names":[{"CN": "${name}","OU":"None"}]}' \
|
||||
| cfssl genkey -initca - \
|
||||
| cfssljson -bare ${name}
|
||||
|
||||
rm ${name}.csr
|
||||
}
|
||||
|
||||
ee() {
|
||||
ca_name=$1
|
||||
ee_name=$2
|
||||
hostname=$3
|
||||
ee_deployment=$2
|
||||
ee_namespace=$3
|
||||
controller_namespace=$4
|
||||
|
||||
ee_name=${ee_deployment}-${ee_namespace}
|
||||
hostname=${ee_deployment}.deployment.${ee_namespace}.conduit-managed.${controller_namespace}.svc.cluster.local
|
||||
|
||||
echo '{}' \
|
||||
| cfssl gencert -ca ${ca_name}.pem -ca-key ${ca_name}-key.pem -hostname=${hostname} - \
|
||||
| cfssljson -bare ${ee_name}
|
||||
|
@ -22,14 +34,30 @@ ee() {
|
|||
openssl x509 -inform pem -outform der \
|
||||
-in ${ee_name}.pem \
|
||||
-out ${ee_name}-${ca_name}.crt
|
||||
rm ${ee_name}.pem
|
||||
rm \
|
||||
${ee_name}.pem \
|
||||
${ee_name}-key.pem \
|
||||
${ee_name}.csr
|
||||
|
||||
crt=`base64 -w0 ${ee_name}-${ca_name}.crt`
|
||||
p8=`base64 -w0 ${ee_name}-${ca_name}.p8`
|
||||
|
||||
secret="${ee_name}-${ca_name}-secret.yml"
|
||||
echo "apiVersion: v1" > ${secret}
|
||||
echo "kind: Secret" >> ${secret}
|
||||
echo "metadata:" >> ${secret}
|
||||
echo " name: ${ee_deployment}-deployment-tls-conduit-io" >> ${secret}
|
||||
echo "data:" >> ${secret}
|
||||
echo " certificate.crt: ${crt}" >> "${ee_name}-${ca_name}-secret.yml"
|
||||
echo " private-key.p8: ${p8}" >> "${ee_name}-${ca_name}-secret.yml"
|
||||
}
|
||||
|
||||
ca "Cluster-local CA 1" ca1
|
||||
ca "Cluster-local CA 1" ca2 # Same name, different key pair.
|
||||
ee ca1 foo-ns1 foo.ns1.conduit-managed-pods.conduit.svc.cluster.local
|
||||
ee ca2 foo-ns1 foo.ns1.conduit-managed-pods.conduit.svc.cluster.local # Same, but different CA
|
||||
ee ca1 bar-ns1 bar.ns1.conduit-managed-pods.conduit.svc.cluster.local # Different service.
|
||||
|
||||
rm *-key.pem *.csr
|
||||
# The controller itself.
|
||||
ee ca1 controller conduit conduit
|
||||
|
||||
ee ca1 foo ns1 conduit
|
||||
ee ca2 foo ns1 conduit # Same, but different CA
|
||||
ee ca1 bar ns1 conduit # Different service.
|
||||
|
|
Loading…
Reference in New Issue