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:
Brian Smith 2018-06-27 17:17:34 -10:00 committed by GitHub
parent cca8e7077d
commit afbc88ac44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 149 additions and 115 deletions

View File

@ -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)
},

View File

@ -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
}
});

View File

@ -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) > (),

View File

@ -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.

View File

@ -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.

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJ560iowWQ1mggSFMTg7m9S4drgBytWBrj2UX29s8sCsoAoGCCqGSM49
AwEHoUQDQgAE5tRYXAFU8W3HRo4qJIKLtaONaENzDX3ttJebH6ZKEXUg2xDPMBTm
7GO5EltrJBpGEwP+RL16SQxF82CxjbJ/6g==
-----END EC PRIVATE KEY-----

View File

@ -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-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMhxYa0qVqt+HIidzIxXirLr175Ipp+GvhmgXaUAsOf0oAoGCCqGSM49
AwEHoUQDQgAEeEscd3LbZFKRU0063H1RRs+rNhroW8VBsJhBarY3pB4N/2+qsy5B
vawmypQHGNBcSYXHJHWwUif8EAUAM6mfDg==
-----END EC PRIVATE KEY-----

View File

@ -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-----

View File

@ -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.

View File

@ -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.

View File

@ -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.

42
proxy/src/transport/tls/testdata/gen-certs.sh vendored Normal file → Executable file
View File

@ -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.