Skip to content

Commit

Permalink
gateway/certs: added API for custom domains...
Browse files Browse the repository at this point in the history
...and gateway certificates renewal.

* added a new `request-gateway-certificate` admin command to
renew the gateway certificate on-deman.

* added gateway admin APIs for custom domains and gateway
certificates renewal.

Note: requesting renewal for the gateway certificate requires inserting
manually a DNS TXT record to complete the ACME DNS-01 challenge.

Signed-off-by: Iulian Barbu <iulianbarbu2@gmail.com>
  • Loading branch information
iulianbarbu committed Feb 22, 2023
1 parent e8536e8 commit 2d81d54
Show file tree
Hide file tree
Showing 14 changed files with 547 additions and 138 deletions.
129 changes: 129 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ ARG RUSTUP_TOOLCHAIN
FROM rust:${RUSTUP_TOOLCHAIN}-buster as shuttle-build
RUN apt-get update &&\
apt-get install -y curl

# download protoc binary and unzip it in usr/bin
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.9/protoc-21.9-linux-x86_64.zip &&\
unzip -o protoc-21.9-linux-x86_64.zip -d /usr bin/protoc &&\
unzip -o protoc-21.9-linux-x86_64.zip -d /usr/ 'include/*' &&\
rm -f protoc-21.9-linux-x86_64.zip
ARG PROTOC_ARCH
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.9/protoc-21.9-linux-${PROTOC_ARCH}.zip &&\
unzip -o protoc-21.9-linux-${PROTOC_ARCH}.zip -d /usr bin/protoc &&\
unzip -o protoc-21.9-linux-${PROTOC_ARCH}.zip -d /usr/ 'include/*' &&\
rm -f protoc-21.9-linux-${PROTOC_ARCH}.zip

RUN cargo install cargo-chef
WORKDIR /build

Expand Down
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ USE_TLS?=disable
CARGO_PROFILE=debug
endif

ARCH=$(shell uname -m)
PROTOC_ARCH=$(ARCH)
ifeq ($(ARCH), arm64)
PROTOC_ARCH=aarch_64
endif

POSTGRES_EXTRA_PATH?=./extras/postgres
POSTGRES_TAG?=14

Expand All @@ -81,6 +87,7 @@ images: shuttle-provisioner shuttle-deployer shuttle-gateway shuttle-auth postgr

postgres:
docker buildx build \
--build-arg PROTOC_ARCH=$(PROTOC_ARCH) \
--build-arg POSTGRES_TAG=$(POSTGRES_TAG) \
--tag $(CONTAINER_REGISTRY)/postgres:$(POSTGRES_TAG) \
$(BUILDX_FLAGS) \
Expand All @@ -89,6 +96,8 @@ postgres:

panamax:
docker buildx build \
--build-arg PROTOC_ARCH=$(PROTOC_ARCH) \
--platform linux/$(ARCH) \
--build-arg PANAMAX_TAG=$(PANAMAX_TAG) \
--tag $(CONTAINER_REGISTRY)/panamax:$(PANAMAX_TAG) \
$(BUILDX_FLAGS) \
Expand All @@ -112,6 +121,7 @@ down: docker-compose.rendered.yml

shuttle-%: ${SRC} Cargo.lock
docker buildx build \
--build-arg PROTOC_ARCH=$(PROTOC_ARCH) \
--build-arg folder=$(*) \
--build-arg RUSTUP_TOOLCHAIN=$(RUSTUP_TOOLCHAIN) \
--build-arg CARGO_PROFILE=$(CARGO_PROFILE) \
Expand Down
26 changes: 25 additions & 1 deletion admin/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub enum Command {
/// Try to revive projects in the crashed state
Revive,

/// Manage custom domains
/// Manage domains
#[command(subcommand)]
Acme(AcmeCommand),

Expand Down Expand Up @@ -58,6 +58,30 @@ pub enum AcmeCommand {
#[arg(long)]
credentials: PathBuf,
},

/// Renew the certificate for a FQDN
RenewCustomDomainCertificate {
/// Fqdn to renew the certificate for
#[arg(long)]
fqdn: String,

/// Project to renew the certificate for
#[arg(long)]
project: ProjectName,

/// Path to acme credentials file
/// This should have been created with `acme create-account`
#[arg(long)]
credentials: PathBuf,
},

/// Renew certificate for the shuttle gateway
RenewGatewayCertificate {
/// Path to acme credentials file
/// This should have been created with `acme create-account`
#[arg(long)]
credentials: PathBuf,
},
}

#[derive(Subcommand, Debug)]
Expand Down
18 changes: 18 additions & 0 deletions admin/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ impl Client {
self.post(&path, Some(credentials)).await
}

pub async fn acme_renew_custom_domain_certificate(
&self,
fqdn: &str,
project_name: &ProjectName,
credentials: &serde_json::Value,
) -> Result<String> {
let path = format!("/admin/acme/renew/{project_name}/{fqdn}");
self.post(&path, Some(credentials)).await
}

pub async fn acme_renew_gateway_certificate(
&self,
credentials: &serde_json::Value,
) -> Result<String> {
let path = "/admin//acme/gateway/renew".to_string();
self.post(&path, Some(credentials)).await
}

pub async fn get_projects(&self) -> Result<Vec<project::AdminResponse>> {
self.get("/admin/projects").await
}
Expand Down
24 changes: 24 additions & 0 deletions admin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ async fn main() {
.await
.expect("to get a certificate challenge response")
}
Command::Acme(AcmeCommand::RenewCustomDomainCertificate {
fqdn,
project,
credentials,
}) => {
let credentials = fs::read_to_string(credentials).expect("to read credentials file");
let credentials =
serde_json::from_str(&credentials).expect("to parse content of credentials file");

client
.acme_renew_custom_domain_certificate(&fqdn, &project, &credentials)
.await
.expect("to get a certificate challenge response")
}
Command::Acme(AcmeCommand::RenewGatewayCertificate { credentials }) => {
let credentials = fs::read_to_string(credentials).expect("to read credentials file");
let credentials =
serde_json::from_str(&credentials).expect("to parse content of credentials file");

client
.acme_renew_gateway_certificate(&credentials)
.await
.expect("to get a certificate challenge response")
}
Command::ProjectNames => {
let projects = client
.get_projects()
Expand Down
12 changes: 10 additions & 2 deletions common/src/backends/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,18 @@ pub enum Scope {
/// Create an ACME account
AcmeCreate,

/// Create a custom domain,
/// Create a custom domain.
CustomDomainCreate,

/// Admin level scope to internals
/// Renew the certificate of a custom domain.
CustomDomainCertificateRenew,

/// Request renewal of the gateway certificate.
/// Note: this step should be completed manually in terms
/// of DNS-01 challenge completion.
GatewayCertificateRenew,

/// Admin level scope to internals.
Admin,
}

Expand Down
1 change: 1 addition & 0 deletions gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ tracing-opentelemetry = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
ttl_cache = "0.5.1"
uuid = { workspace = true, features = [ "v4" ] }
x509-parser = "0.14.0"

[dependencies.shuttle-common]
workspace = true
Expand Down
Loading

0 comments on commit 2d81d54

Please sign in to comment.