Last active
January 30, 2021 01:41
-
-
Save pirate/0e6d6a23bf5df01b4c6a8451414ade4a to your computer and use it in GitHub Desktop.
Get and set config & secret values in DNS TXT records (via CloudFlare API)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env fish | |
# Script to store and retrieve config/secret key=value pairs in Cloudflare DNS records | |
# Encrypts secrets with a specified passphrase + salt using AES-256-CBC | |
# | |
# Usage: | |
# | |
# $ set_config some_config_key "example config value abc" | |
# $ get_config some_config_key | |
# example config value abc | |
# | |
# $ set_secret some_secret_key "example secret value xyz" "somelongrandompassphrase123" | |
# $ get_secret some_secret_key "somelongrandompassphrase123" | |
# example secret value xyz | |
# https://dash.cloudflare.com/profile/api-tokens | |
set CF_API_KEY "YOUR_CLOUDFLARE_API_BEARER_TOKEN_HERE" | |
set CF_API_ZONE "YOUR_CLOUDFLARE_DNS_ZONE_HERE_abc1234" | |
set CONFIG_DNS_DOMAIN "example.com" | |
set CONFIG_DNS_TTL 120 | |
function aes_encrypt --argument-names=passphrase --description "echo 'plaintext' | aes_encrypt 'passphrase' > cyphertext.txt" | |
openssl enc -aes-256-cbc -md sha512 -base64 -A -pbkdf2 --iter 10000 -pass "pass:$passphrase" -e -in /dev/stdin -out /dev/stdout 2>/dev/null | |
end | |
function aes_decrypt --argument-names=passphrase --description "echo 'cyphertext' | aes_decrypt 'passphrase' > plaintext.txt" | |
openssl enc -aes-256-cbc -md sha512 -base64 -A -pbkdf2 --iter 10000 -pass "pass:$passphrase" -d -in /dev/stdin -out /dev/stdout 2>/dev/null | |
end | |
# Quick check to make sure aes_encrypt, aes_decrypt are working in isolation: | |
# set initial "mary had a little lamb" | |
# echo 'initial:' "$initial" | |
# set cyphertext (echo "$initial" | aes_encrypt "somelongrandompasswordhere") | |
# echo 'cypertext:' "$cyphertext" | |
# set plaintext (echo "$cyphertext" | aes_decrypt "somelongrandompasswordhere") | |
# echo 'plaintext:' "$plaintext" | |
function get_config --argument-names=key --description "lookup the value of a given config [key]" | |
set config_key "$key.$CONFIG_DNS_DOMAIN" | |
# we can get the values via DNS, but it lags, so get it from cloudflare's API for faster results | |
# set config_value (dig +short @1.1.1.1 "$config_key" TXT | xargs | perl -pe 's/ //gm') # too slow | |
curl -X GET -s "https://api.cloudflare.com/client/v4/zones/$CF_API_ZONE/dns_records?name=contains:$config_key&type=TXT" \ | |
-H "Authorization: Bearer $CF_API_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -e -r '.result[0] | .content // ""' | grep --color=never . | |
end | |
function set_config --argument-names=key,value --description "set a given config [key] with a given [value] via in Cloudflare DNS" | |
set config_key "$key.$CONFIG_DNS_DOMAIN" | |
set existing_id ( | |
curl -X GET -s "https://api.cloudflare.com/client/v4/zones/$CF_API_ZONE/dns_records?name=contains:$config_key&type=TXT" \ | |
-H "Authorization: Bearer $CF_API_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[0] | .id' | |
) | |
if [ "$existing_id" != "null" ] | |
curl -X DELETE -s "https://api.cloudflare.com/client/v4/zones/$CF_API_ZONE/dns_records/$existing_id" \ | |
-H "Authorization: Bearer $CF_API_KEY" \ | |
-H "Content-Type: application/json" | jq -r '.success' | grep true > /dev/null | |
end | |
curl -X POST -s "https://api.cloudflare.com/client/v4/zones/$CF_API_ZONE/dns_records" \ | |
-H "Authorization: Bearer $CF_API_KEY" \ | |
-H "Content-Type: application/json" \ | |
--data '{ | |
"type": "TXT", | |
"name": "'"$config_key"'", | |
"content": "'"$value"'", | |
"ttl": '$CONFIG_DNS_TTL' | |
}' | jq -r '.success' | grep true > /dev/null | |
end | |
function get_secret --argument-names=key,passphrase --description "get a given config [key] with a given [default] from Cloudflare DNS" | |
get_config "$key" | aes_decrypt "$passphrase" | |
end | |
function set_secret --argument-names=key,value,passphrase --description "set a given config [key] with a given [value] via in Cloudflare DNS" | |
set_config "$key" (echo "$value | aes_encrypt "$passphrase") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment