[ci skip] update tls auto renew script to use technitium
This commit is contained in:
parent
c8642a4e0a
commit
c41eda0fd4
3 changed files with 168 additions and 77 deletions
10
.drone.yml
10
.drone.yml
|
|
@ -29,7 +29,7 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- "apk update && apk add openssh-client git git-crypt"
|
- "apk update && apk add openssh-client git git-crypt"
|
||||||
- "mkdir ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts"
|
- "mkdir ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts"
|
||||||
- 'chmod 400 secrets/deploy_key'
|
- "chmod 400 secrets/deploy_key"
|
||||||
- "git add ."
|
- "git add ."
|
||||||
- "git remote set-url origin git@github.com:ViktorBarzin/infra.git"
|
- "git remote set-url origin git@github.com:ViktorBarzin/infra.git"
|
||||||
- "git commit -m 'Drone CI deploy commit [CI SKIP]' || echo 'No changes'"
|
- "git commit -m 'Drone CI deploy commit [CI SKIP]' || echo 'No changes'"
|
||||||
|
|
@ -41,7 +41,7 @@ steps:
|
||||||
from_secret: slack_webhook
|
from_secret: slack_webhook
|
||||||
channel: general
|
channel: general
|
||||||
when:
|
when:
|
||||||
status: [ success, failure ]
|
status: [success, failure]
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
|
|
@ -55,7 +55,7 @@ trigger:
|
||||||
- push
|
- push
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Build image
|
- name: Build image
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
settings:
|
settings:
|
||||||
username: "viktorbarzin"
|
username: "viktorbarzin"
|
||||||
|
|
@ -98,13 +98,13 @@ steps:
|
||||||
# Install terraform cli
|
# Install terraform cli
|
||||||
- "curl https://releases.hashicorp.com/terraform/0.14.6/terraform_0.14.6_linux_amd64.zip | gzip -d > /usr/local/bin/terraform && chmod 775 /usr/local/bin/terraform"
|
- "curl https://releases.hashicorp.com/terraform/0.14.6/terraform_0.14.6_linux_amd64.zip | gzip -d > /usr/local/bin/terraform && chmod 775 /usr/local/bin/terraform"
|
||||||
- "terraform init"
|
- "terraform init"
|
||||||
- "./modules/kubernetes/setup_tls_secret/renew.sh"
|
- "./modules/kubernetes/setup_tls_secret/renew2.sh"
|
||||||
- name: Commit updated certificates
|
- name: Commit updated certificates
|
||||||
image: alpine
|
image: alpine
|
||||||
commands:
|
commands:
|
||||||
- "apk update && apk add openssh-client git git-crypt"
|
- "apk update && apk add openssh-client git git-crypt"
|
||||||
- "mkdir ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts"
|
- "mkdir ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts"
|
||||||
- 'chmod 400 secrets/deploy_key'
|
- "chmod 400 secrets/deploy_key"
|
||||||
- "git add ."
|
- "git add ."
|
||||||
- "git remote set-url origin git@github.com:ViktorBarzin/infra.git"
|
- "git remote set-url origin git@github.com:ViktorBarzin/infra.git"
|
||||||
- "git commit -m 'Drone CI Update TLS Certificates Commit' || echo 'No changes'"
|
- "git commit -m 'Drone CI Update TLS Certificates Commit' || echo 'No changes'"
|
||||||
|
|
|
||||||
|
|
@ -4,75 +4,118 @@ set timeout -1
|
||||||
set le_dir "/tmp/le/"
|
set le_dir "/tmp/le/"
|
||||||
set config_dir "$le_dir/out/config"
|
set config_dir "$le_dir/out/config"
|
||||||
set pwd [pwd]
|
set pwd [pwd]
|
||||||
|
set technitium_token "REDACTED_TECHNITIUM_TOKEN"
|
||||||
|
|
||||||
spawn certbot certonly --manual --preferred-challenge=dns --email me@viktorbarzin.me --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --manual-public-ip-logging-ok -d *.viktorbarzin.me -d viktorbarzin.me --config-dir $config_dir --work-dir $le_dir/workdir --logs-dir $le_dir/logsdir --no-eff-email
|
# contents for certbot-auth
|
||||||
|
set auth_contents {#!/usr/bin/env sh
|
||||||
|
# Generate API token from DNS web console
|
||||||
|
API_TOKEN="REDACTED_TECHNITIUM_TOKEN"
|
||||||
|
|
||||||
set prompt "$"
|
# Create challenge TXT record
|
||||||
set dns_file "$pwd/modules/kubernetes/bind/extra/viktorbarzin.me"
|
curl "http://technitium-web.technitium.svc.cluster.local:5380/api/zones/records/add?token=$API_TOKEN&domain=_acme-challenge.\$CERTBOT_DOMAIN&type=TXT&ttl=60&text=\$CERTBOT_VALIDATION"
|
||||||
# expect -re "Please deploy a DNS TXT record under the name" {
|
|
||||||
expect -re "Press Enter to Continue" {
|
|
||||||
set challenge [ exec sh -c "echo '$expect_out(buffer)' | tail -n 4 | head -n 1" ]
|
|
||||||
set dns_record "_acme-challenge IN TXT \"$challenge\""
|
|
||||||
puts "\nChallenge: '$challenge'"
|
|
||||||
# send \x03
|
|
||||||
puts "Dns file: '$dns_file'"
|
|
||||||
|
|
||||||
# Check if dns record is not already present
|
# Sleep to make sure the change has time to propagate from primary to secondary name servers
|
||||||
try {
|
sleep 25
|
||||||
set results [exec grep -q $dns_record $dns_file]
|
|
||||||
set status 0
|
|
||||||
} trap CHILDSTATUS {results options} {
|
|
||||||
set status [lindex [dict get $options -errorcode] 2]
|
|
||||||
}
|
|
||||||
if {$status != 0} {
|
|
||||||
exec echo $dns_record | tee -a $dns_file
|
|
||||||
puts "Teed into file"
|
|
||||||
} else {
|
|
||||||
puts "DNS record '$dns_record' already in file"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
spawn /bin/sh
|
||||||
|
send "echo \"$auth_contents\" > /root/certbot-auth.sh \r"
|
||||||
|
send "chmod 700 /root/certbot-auth.sh \r"
|
||||||
|
send "cat /root/certbot-auth.sh \r"
|
||||||
|
send "exit \r"
|
||||||
|
|
||||||
send -- "\r"
|
# Contents for certbot-cleanup
|
||||||
# Do the same for the 2nd dns record
|
set cleanup_contents {#!/usr/bin/env sh
|
||||||
expect -re "\[a-zA-Z0-9_-\]{43}" {
|
exit 0 # DEBUG: TODO: Remove me
|
||||||
set challenge $expect_out(0,string)
|
# Generate API token from DNS web console
|
||||||
# set challenge [ exec sh -c "echo $expect_out(0, buffer) | tail -n 8 | head -n 1" ]
|
API_TOKEN="REDACTED_TECHNITIUM_TOKEN"
|
||||||
set dns_record1 "_acme-challenge IN TXT \"$challenge\""
|
|
||||||
puts "Challenge: '$challenge'"
|
|
||||||
puts "Dns record: '$dns_record1'"
|
|
||||||
puts "Dns file: '$dns_file'"
|
|
||||||
|
|
||||||
# Check if dns record is not already present
|
# Delete challenge TXT record
|
||||||
try {
|
curl "http://technitium-web.technitium.svc.cluster.local:5380/api/zones/records/delete?token=$API_TOKEN&domain=_acme-challenge.\$CERTBOT_DOMAIN&type=TXT&text=\$CERTBOT_VALIDATION"
|
||||||
set results [exec grep -q $dns_record1 $dns_file]
|
|
||||||
set status 0
|
|
||||||
} trap CHILDSTATUS {results options} {
|
|
||||||
set status [lindex [dict get $options -errorcode] 2]
|
|
||||||
}
|
|
||||||
if {$status != 0} {
|
|
||||||
exec echo $dns_record1 | tee -a $dns_file
|
|
||||||
puts "Teed into file"
|
|
||||||
} else {
|
|
||||||
puts "DNS record '$dns_record1' already in file"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
spawn /bin/sh
|
||||||
|
send "echo \"$cleanup_contents\" > /root/certbot-cleanup.sh \r"
|
||||||
|
send "chmod 700 /root/certbot-cleanup.sh \r"
|
||||||
|
send "exit \r"
|
||||||
|
|
||||||
# Force deployment recreation
|
exit 0
|
||||||
exec terraform taint module.kubernetes_cluster.module.bind.module.bind-public-deployment.kubernetes_deployment.bind
|
spawn certbot certonly --manual --preferred-challenges=dns --email me@viktorbarzin.me --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --manual-auth-hook /root/certbot-auth.sh --config-dir $config_dir --work-dir $le_dir/workdir --logs-dir $le_dir/logsdir --no-eff-email --manual-cleanup-hook /root/certbot-cleanup.sh -d viktorbarzin.me -d *.viktorbarzin.me
|
||||||
# Apply changes to configmap and redeploy
|
|
||||||
exec >@stdout 2>@stderr terraform apply -auto-approve -target=module.kubernetes_cluster.module.bind
|
|
||||||
|
|
||||||
# Wait for deployment update
|
############# Old way of auth
|
||||||
# TODO: better to use k8s api. What we want is `kubectl rollout status deployment -l app=bind-public` as a curl
|
|
||||||
# exec bash -c 'while [[ $(kubectl get pods -l app=bind-public -o \'jsonpath={..status.conditions[\?(\@.type=="Ready")].status}\') != "True" ]]; do echo "waiting pod..." && sleep 1; done'
|
|
||||||
exec >@stdout echo 'Waiting for redeployment of bind...'
|
|
||||||
exec sleep 10
|
|
||||||
|
|
||||||
send -- "\r"
|
# spawn certbot certonly --manual --preferred-challenge=dns --email me@viktorbarzin.me --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d *.viktorbarzin.me -d viktorbarzin.me --config-dir $config_dir --work-dir $le_dir/workdir --logs-dir $le_dir/logsdir --no-eff-email
|
||||||
|
|
||||||
# Clean up
|
# set prompt "$"
|
||||||
exec sed -i "s/$dns_record//g" "$dns_file"
|
# set dns_file "$pwd/modules/kubernetes/bind/extra/viktorbarzin.me"
|
||||||
exec sed -i "s/$dns_record1//g" "$dns_file"
|
# # expect -re "Please deploy a DNS TXT record under the name" {
|
||||||
|
# expect -re "Press Enter to Continue" {
|
||||||
|
# set challenge [ exec sh -c "echo '$expect_out(buffer)' | tail -n 4 | head -n 1" ]
|
||||||
|
# set dns_record "_acme-challenge IN TXT \"$challenge\""
|
||||||
|
# puts "\nChallenge: '$challenge'"
|
||||||
|
# # send \x03
|
||||||
|
# puts "Dns file: '$dns_file'"
|
||||||
|
|
||||||
|
# # Check if dns record is not already present
|
||||||
|
# try {
|
||||||
|
# set results [exec grep -q $dns_record $dns_file]
|
||||||
|
# set status 0
|
||||||
|
# } trap CHILDSTATUS {results options} {
|
||||||
|
# set status [lindex [dict get $options -errorcode] 2]
|
||||||
|
# }
|
||||||
|
# if {$status != 0} {
|
||||||
|
# exec echo $dns_record | tee -a $dns_file
|
||||||
|
# puts "Teed into file"
|
||||||
|
# } else {
|
||||||
|
# puts "DNS record '$dns_record' already in file"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# send -- "\r"
|
||||||
|
# # Do the same for the 2nd dns record
|
||||||
|
# expect -re "\[a-zA-Z0-9_-\]{43}" {
|
||||||
|
# set challenge $expect_out(0,string)
|
||||||
|
# # set challenge [ exec sh -c "echo $expect_out(0, buffer) | tail -n 8 | head -n 1" ]
|
||||||
|
# set dns_record1 "_acme-challenge IN TXT \"$challenge\""
|
||||||
|
# puts "Challenge: '$challenge'"
|
||||||
|
# puts "Dns record: '$dns_record1'"
|
||||||
|
# puts "Dns file: '$dns_file'"
|
||||||
|
|
||||||
|
# # Check if dns record is not already present
|
||||||
|
# try {
|
||||||
|
# set results [exec grep -q $dns_record1 $dns_file]
|
||||||
|
# set status 0
|
||||||
|
# } trap CHILDSTATUS {results options} {
|
||||||
|
# set status [lindex [dict get $options -errorcode] 2]
|
||||||
|
# }
|
||||||
|
# if {$status != 0} {
|
||||||
|
# exec echo $dns_record1 | tee -a $dns_file
|
||||||
|
# puts "Teed into file"
|
||||||
|
# } else {
|
||||||
|
# puts "DNS record '$dns_record1' already in file"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# # Force deployment recreation
|
||||||
|
# # exec terraform taint module.kubernetes_cluster.module.bind.module.bind-public-deployment.kubernetes_deployment.bind
|
||||||
|
# exec terraform taint module.kubernetes_cluster.module.technitium.kubernetes_deployment.technitium
|
||||||
|
# # set current_time [clock seconds]
|
||||||
|
# # set formatted_time [clock format $current_time -format "+%Y-%m-%dT%TZ"]
|
||||||
|
# # exec curl -X PATCH https://10.0.20.100:6443/apis/apps/v1/namespaces/technitium/deployments/technitium -H \"Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" -H \"Content-Type:application/strategic-merge-patch+json\" -k -d '{\"spec\": {\"template\": {\"metadata\": { \"annotations\": {\"kubectl.kubernetes.io/restartedAt\": \"'$(date +%Y-%m-%dT%TZ)'\" }}}}}'
|
||||||
|
# # exec curl -X PATCH https://10.0.20.100:6443/apis/apps/v1/namespaces/technitium/deployments/technitium -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -H "Content-Type: application/strategic-merge-patch+json" -k -d "{\"spec\": {\"template\": {\"metadata\": { \"annotations\": {\"kubectl.kubernetes.io/restartedAt\": \"$formatted_time\" }}}}}"
|
||||||
|
# # exec terraform taint module.kubernetes_cluster.module.technitium.module.technitium.kubernetes_deployment.technitium
|
||||||
|
# # Apply changes to configmap and redeploy
|
||||||
|
# exec >@stdout 2>@stderr terraform apply -auto-approve -target=module.kubernetes_cluster.module.technitium
|
||||||
|
|
||||||
|
# # Wait for deployment update
|
||||||
|
# # TODO: better to use k8s api. What we want is `kubectl rollout status deployment -l app=bind-public` as a curl
|
||||||
|
# # exec bash -c 'while [[ $(kubectl get pods -l app=bind-public -o \'jsonpath={..status.conditions[\?(\@.type=="Ready")].status}\') != "True" ]]; do echo "waiting pod..." && sleep 1; done'
|
||||||
|
# exec >@stdout echo 'Waiting for redeployment of technitium...'
|
||||||
|
# exec sleep 10
|
||||||
|
|
||||||
|
# send -- "\r"
|
||||||
|
|
||||||
|
# # Clean up
|
||||||
|
# exec sed -i "s/$dns_record//g" "$dns_file"
|
||||||
|
# exec sed -i "s/$dns_record1//g" "$dns_file"
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
expect ".*Congratulations!"
|
expect ".*Congratulations!"
|
||||||
|
|
|
||||||
48
modules/kubernetes/setup_tls_secret/renew2.sh
Executable file
48
modules/kubernetes/setup_tls_secret/renew2.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
|
||||||
|
export le_dir="/tmp/le/"
|
||||||
|
export config_dir="$le_dir/out/config"
|
||||||
|
export technitium_token="REDACTED_TECHNITIUM_TOKEN"
|
||||||
|
export certbot_auth="$le_dir/certbot_auth.sh"
|
||||||
|
export certbot_cleanup="$le_dir/certbot_cleanup.sh"
|
||||||
|
|
||||||
|
mkdir $le_dir
|
||||||
|
cat << EOF > $certbot_auth
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# Generate API token from DNS web console
|
||||||
|
API_TOKEN="REDACTED_TECHNITIUM_TOKEN"
|
||||||
|
|
||||||
|
# Create challenge TXT record
|
||||||
|
curl "http://technitium-web.technitium.svc.cluster.local:5380/api/zones/records/add?token=\$API_TOKEN&domain=_acme-challenge.\$CERTBOT_DOMAIN&type=TXT&ttl=60&text=\$CERTBOT_VALIDATION"
|
||||||
|
|
||||||
|
# Sleep to make sure the change has time to propagate from primary to secondary name servers
|
||||||
|
sleep 25
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod 700 $certbot_auth
|
||||||
|
cat $certbot_auth
|
||||||
|
|
||||||
|
|
||||||
|
cat << EOF > $certbot_cleanup
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# Generate API token from DNS web console
|
||||||
|
API_TOKEN="REDACTED_TECHNITIUM_TOKEN"
|
||||||
|
|
||||||
|
# Delete challenge TXT record
|
||||||
|
curl "http://technitium-web.technitium.svc.cluster.local:5380/api/zones/records/delete?token=\$API_TOKEN&domain=_acme-challenge.\$CERTBOT_DOMAIN&type=TXT&text=\$CERTBOT_VALIDATION"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod 700 $certbot_cleanup
|
||||||
|
cat $certbot_cleanup
|
||||||
|
|
||||||
|
|
||||||
|
certbot certonly --manual --preferred-challenges=dns --email me@viktorbarzin.me --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --manual-auth-hook $certbot_auth --config-dir $config_dir --work-dir $le_dir/workdir --logs-dir $le_dir/logsdir --no-eff-email --manual-cleanup-hook $certbot_cleanup -d viktorbarzin.me -d *.viktorbarzin.me
|
||||||
|
|
||||||
|
exec cp --remove-destination $config_dir/live/viktorbarzin.me/fullchain.pem ./secrets
|
||||||
|
exec cp --remove-destination $config_dir/live/viktorbarzin.me/privkey.pem ./secrets
|
||||||
|
|
||||||
|
echo "Done renewing cert. Output certificates stored in ./secrets\n"
|
||||||
|
ls ./secrets
|
||||||
Loading…
Add table
Add a link
Reference in a new issue