Skip to content

Commit

Permalink
Merge pull request #1766 from solliancenet/certbot-docker
Browse files Browse the repository at this point in the history
Utility to run certbot in a container
  • Loading branch information
ciprianjichici authored Sep 25, 2024
2 parents 1fb1321 + 30f89ae commit 6a19c1a
Show file tree
Hide file tree
Showing 10 changed files with 900 additions and 0 deletions.
25 changes: 25 additions & 0 deletions deploy/common/docker/certbot-app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM mcr.microsoft.com/vscode/devcontainers/base:0-bullseye

ARG INSTALL_ZSH="true"
ARG UPGRADE_PACKAGES="true"
ARG USERNAME=certbot
ARG USER_GID=1001
ARG USER_UID=1001

COPY library-scripts/*.sh /tmp/library-scripts/

RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*

RUN bash /tmp/library-scripts/azcli-debian.sh
RUN bash /tmp/library-scripts/install-certbot.sh
RUN bash /tmp/library-scripts/pwsh-debian.sh

RUN rm -rf /tmp/library-scripts

RUN mkdir /app
COPY Function-Library.ps1 /app/Function-Library.ps1
COPY New-LetsEncryptCertificates.ps1 /app/New-LetsEncryptCertificate.ps1

ENTRYPOINT ["pwsh", "/app/New-LetsEncryptCertificate.ps1"]
11 changes: 11 additions & 0 deletions deploy/common/docker/certbot-app/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
default: buildx

buildx: pull prepare
bash ./build.sh
rm -v Function-Library.ps1

prepare:
cp -v ../../scripts/Function-Library.ps1 .

pull:
docker pull mcr.microsoft.com/vscode/devcontainers/base:0-bullseye
128 changes: 128 additions & 0 deletions deploy/common/docker/certbot-app/New-LetsEncryptCertificates.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#! /usr/bin/env pwsh

<#
.SYNOPSIS
This script generates Let's Encrypt certificates for a given base domain and a list of subdomains.
.DESCRIPTION
The script generates Let's Encrypt certificates for a given base domain and a list of subdomains.
It uses Certbot and the dns-azure plugin for DNS authentication.
.PARAMETER baseDomain
The base domain for which the certificates will be generated.
.PARAMETER email
The email address to be used for Let's Encrypt registration and notifications.
.PARAMETER subdomainPrefix
An optional prefix to be added to each subdomain.
.NOTES
- This script requires Certbot and the dns-azure plugin to be installed.
- The script generates certificates for the following subdomains:
- api
- management
- management-api
- vectorization-api
- www
- Certbot DNS Azure documentation: https://docs.certbot-dns-azure.co.uk/en/latest/
- Certbot DNS Azure GitHub repository: https://github.com/terrycain/certbot-dns-azure
.EXAMPLE
Get-LetsEncryptCertificates.ps1 -baseDomain example.com -email [email protected]
#>

param(
[parameter(Mandatory = $true)][string]$baseDomain,
[parameter(Mandatory = $true)][string]$email,
[parameter(Mandatory = $false)][string]$subdomainPrefix = ''
)

Set-PSDebug -Trace 0 # Echo every command (0 to disable, 1 to enable)
Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"

$ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Path
. $ScriptDirectory/Function-Library.ps1

$basenames = @{
"api" = "coreapi"
"management" = "managementui"
"management-api" = "managementapi"
"www" = "chatui"
}

$directories = @{
"config" = "/app/config/certbot/config" | Get-AbsolutePath
"work" = "/app/config/certbot/work" | Get-AbsolutePath
"log" = "/app/config/certbot/log" | Get-AbsolutePath
"certs" = "/app/config/certs" | Get-AbsolutePath
}

foreach ($directory in $directories.GetEnumerator()) {
if (!(Test-Path $directory.Value)) {
New-Item -ItemType Directory -Force -Path $directory.Value
}
}

Invoke-CLICommand "Azure Login" {
az login
}

foreach ($basename in $basenames.GetEnumerator()) {
# Domain Name
if('' -ne $subdomainPrefix) {
$hostname = @($subdomainPrefix, $basename.Name) | Join-String -Separator "-"
} else {
$hostname = $basename.Name
}

$fqdn = @($hostname, $baseDomain) | Join-String -Separator "."

# File Paths
$paths = @{
"pemFullChain" = Join-Path $directories["config"] "live" $fqdn "fullchain.pem"
"pemPrivKey" = Join-Path $directories["config"] "live" $fqdn "privkey.pem"
"pfx" = Join-Path $directories["certs"] $basename.Value "${fqdn}.pfx"
"pfxDir" = Join-Path $directories["certs"] $basename.Value
}

if (!(Test-Path $paths["pfxDir"])) {
New-Item -ItemType Directory -Force -Path $paths["pfxDir"]
}

Invoke-CLICommand "Generate certificate for ${fqdn}" {
certbot certonly `
--agree-tos `
--email $email `
--authenticator dns-azure `
--config-dir $directories["config"] `
--dns-azure-config /app/config/certbot.ini `
--domain $fqdn `
--keep-until-expiring `
--logs-dir $directories["log"] `
--non-interactive `
--preferred-challenges dns `
--quiet `
--work-dir $directories["work"]
}

Invoke-CLICommand "Export certificate for ${fqdn}" {
openssl pkcs12 `
-export `
-inkey $paths["pemPrivKey"] `
-in $paths["pemFullChain"] `
-out $paths["pfx"] `
-passout pass:
}

Invoke-CLICommand "Verify certificate for ${fqdn}" {
openssl pkcs12 `
-info `
-in $paths["pfx"] `
-nokeys `
-passin pass: `
-passout pass:
}
}
41 changes: 41 additions & 0 deletions deploy/common/docker/certbot-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Utility to run certbot in a container

## Synopsis

```bash
make && \
docker run \
-v ./config:/app/config \
-it certbot-app \
-baseDomain <your zone name> \
-email <your email> \
-subdomainPrefix <optional prefix for hostnames>
```

You must replace `<your zone name>` and `<your email>` with the appropriate values. And optionally, you can replace `<optional prefix for hostnames>` with a prefix for the hostnames or leave this parameter off the list.

Example:

```bash
make && \
docker run \
-v ./config:/app/config \
-it certbot-app \
-baseDomain example.com \
-email [email protected] \
-subdomainPrefix test
```

## Before you begin

Create `certbot.ini` in the `config` directory with the following content:

```ini
dns_azure_use_cli_credentials = true

dns_azure_environment = "AzurePublicCloud"

dns_azure_zone1 = <your zone name>:<your zone resource id>
```

You must replace `<your zone name>` and `<your zone resource id>` with the appropriate values.
11 changes: 11 additions & 0 deletions deploy/common/docker/certbot-app/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euox pipefail

REPOSITORY="certbot-app"
CONTEXT="."

SHA=$(git rev-parse --short HEAD)
docker buildx build --rm -t "${REPOSITORY}:${SHA}" "${CONTEXT}"
docker tag "${REPOSITORY}:${SHA}" "${REPOSITORY}:latest"

docker images "${REPOSITORY}"
2 changes: 2 additions & 0 deletions deploy/common/docker/certbot-app/config/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Place certbot.ini file in this folder but do not commit it to the repository
certbot.ini
Loading

0 comments on commit 6a19c1a

Please sign in to comment.