aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-12-08 11:11:22 +0100
committerAlex Auvolat <alex@adnab.me>2021-12-08 11:11:22 +0100
commit098a6cf2cdb9b0370ab7358b005f731b65e9981c (patch)
tree80e862f2ba2aeb03a33ab8e4fcb05d4a221dd308
parent11c6f0b1c29b10893de9390f5be559de49e78410 (diff)
downloadtricot-098a6cf2cdb9b0370ab7358b005f731b65e9981c.tar.gz
tricot-098a6cf2cdb9b0370ab7358b005f731b65e9981c.zip
Implement glob pattern hostnames
no wildcard certificates: one certificate per matching hostname that actually recieves requests
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/cert_store.rs10
-rw-r--r--src/https.rs2
-rw-r--r--src/proxy_config.rs35
5 files changed, 48 insertions, 7 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e297475..66da4cc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -473,6 +473,12 @@ dependencies = [
]
[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
name = "h2"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1880,6 +1886,7 @@ dependencies = [
"envy",
"futures 0.3.18",
"futures-util",
+ "glob",
"http 0.2.5",
"hyper 0.14.15",
"hyper-reverse-proxy",
diff --git a/Cargo.toml b/Cargo.toml
index 5c6cb2c..bd40fe6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,3 +31,4 @@ hyper-reverse-proxy = "0.4"
unicase = "2"
lazy_static = "1.4"
structopt = "0.3"
+glob = "0.3"
diff --git a/src/cert_store.rs b/src/cert_store.rs
index f1b7d2b..8d45df4 100644
--- a/src/cert_store.rs
+++ b/src/cert_store.rs
@@ -14,7 +14,7 @@ use rustls::sign::CertifiedKey;
use crate::cert::{Cert, CertSer};
use crate::consul::*;
-use crate::proxy_config::ProxyConfig;
+use crate::proxy_config::*;
pub struct CertStore {
consul: Consul,
@@ -39,11 +39,13 @@ impl CertStore {
let proxy_config: Arc<ProxyConfig> = rx_proxy_config.borrow().clone();
for ent in proxy_config.entries.iter() {
- domains.insert(ent.host.clone());
+ if let HostDescription::Hostname(domain) = &ent.host {
+ domains.insert(domain.clone());
+ }
}
- info!("Ensuring we have certs for domains: {:?}", domains);
for dom in domains.iter() {
+ info!("Ensuring we have certs for domains: {:?}", domains);
if let Err(e) = self.get_cert(dom).await {
warn!("Error get_cert {}: {}", dom, e);
}
@@ -58,7 +60,7 @@ impl CertStore {
.borrow()
.entries
.iter()
- .any(|ent| ent.host == domain)
+ .any(|ent| ent.host.matches(domain))
{
bail!("Domain {} should not have a TLS certificate.", domain);
}
diff --git a/src/https.rs b/src/https.rs
index 3621e4f..2d97476 100644
--- a/src/https.rs
+++ b/src/https.rs
@@ -93,7 +93,7 @@ async fn handle(
.entries
.iter()
.filter(|ent| {
- ent.host == host
+ ent.host.matches(host)
&& ent
.path_prefix
.as_ref()
diff --git a/src/proxy_config.rs b/src/proxy_config.rs
index d4fe039..9092b59 100644
--- a/src/proxy_config.rs
+++ b/src/proxy_config.rs
@@ -16,10 +16,33 @@ use crate::consul::*;
// ---- Extract proxy config from Consul catalog ----
#[derive(Debug)]
+pub enum HostDescription {
+ Hostname(String),
+ Pattern(glob::Pattern),
+}
+
+impl HostDescription {
+ fn new(desc: &str) -> Result<Self> {
+ if desc.chars().any(|x| matches!(x, '*' | '?' | '[' | ']')) {
+ Ok(Self::Pattern(glob::Pattern::new(desc)?))
+ } else {
+ Ok(Self::Hostname(desc.to_string()))
+ }
+ }
+
+ pub fn matches(&self, v: &str) -> bool {
+ match self {
+ Self::Pattern(p) => p.matches(v),
+ Self::Hostname(s) => s == v,
+ }
+ }
+}
+
+#[derive(Debug)]
pub struct ProxyEntry {
pub target_addr: SocketAddr,
- pub host: String,
+ pub host: HostDescription,
pub path_prefix: Option<String>,
pub priority: u32,
pub add_headers: Vec<(String, String)>,
@@ -65,9 +88,17 @@ fn parse_tricot_tag(
_ => 100,
};
+ let host = match HostDescription::new(host) {
+ Ok(h) => h,
+ Err(e) => {
+ warn!("Invalid hostname pattern {}: {}", host, e);
+ return None;
+ }
+ };
+
Some(ProxyEntry {
target_addr,
- host: host.to_string(),
+ host,
path_prefix,
priority,
add_headers: add_headers.to_vec(),