-
Notifications
You must be signed in to change notification settings - Fork 383
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #850 from xyide/route53-bash
Route53 bash
- Loading branch information
Showing
4 changed files
with
272 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Using Route53 BASH scripts for LetsEncrypt domain validation. | ||
|
||
## Quick guide to setting up getssl for domain validation of Route53 DNS domains. | ||
|
||
There a few prerequisites to using getssl with Route53 DNS: | ||
|
||
1. You will need to set up an IAM user with the necessary permissions to modify resource records in the hosted zone. | ||
|
||
- route53:ListHostedZones | ||
- route53:ChangeResourceRecordSets | ||
|
||
1. You will need the AWS CLI Client installed on your machine. | ||
|
||
1. You will need to configure the client for the IAM user that has permission to modify the resource records. | ||
|
||
With those in hand, the installation procedure is: | ||
|
||
1. Open your config file (the global file in ~/.getssl/getssl.cfg | ||
or the per-account file in ~/.getssl/example.net/getssl.cfg) | ||
|
||
1. Set the following options: | ||
|
||
- VALIDATE_VIA_DNS="true" | ||
- DNS_ADD_COMMAND="/usr/share/getssl/dns_scripts/dns_add_route53" | ||
- DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_del_route53" | ||
|
||
The AWS CLI profile to use (will use _default_ if not specified) | ||
|
||
- export AWS*CLI_PROFILE="\_profile name*" | ||
|
||
1. Set any other options that you wish (per the standard | ||
directions.) Use the test CA to make sure that | ||
everything is setup correctly. | ||
|
||
That's it. getssl example.net will now validate with DNS. | ||
|
||
There are additional options, which are documented in `dns_route53 -h` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
|
||
# Add token to Route53 dns using dns_route53 bash version | ||
|
||
fulldomain="$1" | ||
token="$2" | ||
|
||
[ -z "$ROUTE53_SCRIPT" ] && ROUTE53_SCRIPT="/usr/share/getssl/dns_scripts/dns_route53" | ||
[[ "$ROUTE53_SCRIPT" =~ ^~ ]] && \ | ||
eval 'ROUTE53_SCRIPT=`readlink -nf ' $ROUTE53_SCRIPT '`' | ||
|
||
if [ ! -x "$ROUTE53_SCRIPT" ]; then | ||
echo "$ROUTE53_SCRIPT: not found. Please install, softlink or set ROUTE53_SCRIPT to its full path" | ||
echo "See ROUTE53-README.txt for complete instructions." | ||
exit 3 | ||
fi | ||
|
||
$ROUTE53_SCRIPT -q add "${fulldomain}." "${token}" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
|
||
# Delete token from Route53 dns using dns_route53 bash version | ||
|
||
fulldomain="$1" | ||
token="$2" | ||
|
||
[ -z "$ROUTE53_SCRIPT" ] && ROUTE53_SCRIPT="/usr/share/getssl/dns_scripts/dns_route53" | ||
[[ "$ROUTE53_SCRIPT" =~ ^~ ]] && \ | ||
eval 'ROUTE53_SCRIPT=`readlink -nf ' $ROUTE53_SCRIPT '`' | ||
|
||
if [ ! -x "$ROUTE53_SCRIPT" ]; then | ||
echo "$ROUTE53_SCRIPT: not found. Please install, softlink or set ROUTE53_SCRIPT to its full path" | ||
echo "See ROUTE53-README.txt for complete instructions." | ||
exit 3 | ||
fi | ||
|
||
$ROUTE53_SCRIPT -q del "${fulldomain}." "${token}" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
#!/usr/bin/env bash | ||
VERSION="1.0" | ||
PROG="$(basename "$0")" | ||
|
||
QUIET=n | ||
|
||
while getopts 'dhp:t:z:i:qv' opt; do | ||
case $opt in | ||
d) DEBUG="Y" ;; | ||
p) AWS_CLI_PROFILE="$OPTARG" ;; | ||
q) QUIET= ;; | ||
v) echo "dns_route53 version $VERSION"; exit 0 ;; | ||
z) ROUTE53_HOSTED_ZONE_NAME="$OPTARG" ;; | ||
i) ROUTE53_HOSTED_ZONE_ID="$OPTARG" ;; | ||
*) | ||
cat <<EOF | ||
Usage | ||
$PROG [-dt -q] add name data [ttl] | ||
$PROG [-dt -h -p "aws-profile-name" -q] del name data | ||
Add or delete TXT records from Route53 Hosted Zone | ||
You must have the AWS CLI installed and a profile configured for this script to work. | ||
The IAM user that the profile uses requires the following action permissions in AWS: | ||
- route53:ListHostedZones - Not necessary if zone ID is available to this script | ||
- route53:ChangeResourceRecordSets | ||
With getssl, this script is called from the dns_add_route53 and | ||
dns_del_route53 wrapper scripts. | ||
Arguments: | ||
add - add the specified record to the domain | ||
del - remove the specified record from the domain | ||
name is the fully qualified record name to create the challenge for e.g. www.example.org. Note that trailing '.' is necessary. Also note that _acme-challenge. will automatically be prepended by this script | ||
data is the record data, e.g. "myverificationtoken" | ||
ttl is optional and will default to 120 if not specified | ||
If it is necessary to turn on debugging externally, define | ||
ROUTE53_DEBUG="y" (any non-null string will do). | ||
For minimal trace output (to override -q), define ROUTE53_TRACE="y". | ||
Options | ||
-d Provide debugging output - all requests and responses | ||
-h This help. | ||
-i: The hosted zone ID | ||
-p: The AWS CLI profile to use. Will use default if not specified | ||
-q: Quiet - omit normal success messages | ||
-z: The hosted zone name. Will be used to determine the zone ID if ID was not provided | ||
All output, except for this help text, is to stderr. | ||
Environment variables | ||
ROUTE53_SCRIPT location of this script | ||
ROUTE53_HOSTED_ZONE_NAME The name of the hosted zone name. If not specified, then the name will be determined from the record name provided to this script | ||
ROUTE53_HOSTED_ZONE_ID The id of the hosted zone to be used instead of trying to automatically determine the ID | ||
AWS_CLI_PROFILE the aws cli profile to use if not using default | ||
BUGS | ||
Report any issues to https://github.com/xyide/getssl/issues | ||
EOF | ||
exit 0 | ||
;; | ||
esac | ||
done | ||
shift $((OPTIND-1)) | ||
|
||
if [ -z "$AWS_CLI_PROFILE" ]; then | ||
echo "AWS_CLI_PROFILE not defined. Using default" >&2 | ||
AWS_CLI_PROFILE=default | ||
fi | ||
|
||
op="$1" | ||
if ! [[ "$op" =~ ^(add|del)$ ]]; then | ||
echo "Operation must be \"add\" or \"del\"" >&2 | ||
exit 3 | ||
fi | ||
name="$2" | ||
if [ -z "$name" ]; then | ||
echo "'name' parameter is required, see -h" >&2 | ||
exit 3 | ||
fi | ||
data="$3" | ||
if [ -z "$data" ]; then | ||
echo "'data' parameter is required, see -h" >&2 | ||
exit 3 | ||
fi | ||
|
||
if [ "$op" = 'del' ]; then | ||
ttl=120 | ||
elif [ -z "$5" ]; then | ||
ttl="120" | ||
elif ! [[ "$5" =~ ^[0-9]+$ ]]; then | ||
echo "TTL $5 is not numeric" >&2 | ||
exit 3 | ||
elif [ "$5" -lt 120 ]; then | ||
[ -n "$VERB" ] && \ | ||
echo "$5 is too small. Using TTL of 120 instead" >&2 | ||
ttl="120" | ||
else | ||
ttl="$5" | ||
fi | ||
|
||
# end processing parameters | ||
|
||
[ -n "$DEBUG" ] && \ | ||
echo "$PROG: $op $name \"$data\" $ttl" >&2 | ||
|
||
# Determine what actual hosted zone to use. | ||
|
||
HOSTED_ZONE_NAME=$ROUTE53_HOSTED_ZONE_NAME | ||
HOSTED_ZONE_ID=$ROUTE53_HOSTED_ZONE_ID | ||
RR_NAME="_acme-challenge.${name}" | ||
RR_VALUE="${data}" | ||
|
||
# Function to parse through the segments in the supplied name | ||
# to determine the zone and its id | ||
function determine_hosted_zone_name_and_id() { | ||
TMP_NAME=$name | ||
TMP_RR_NAME= | ||
while [[ "$TMP_NAME" =~ ^([^.]+)\.([^.]+.*) ]]; do | ||
if [ -n "${TMP_RR_NAME}" ]; then | ||
TMP_RR_NAME="${TMP_RR_NAME}."; | ||
fi | ||
TMP_RR_NAME="${TMP_RR_NAME}${BASH_REMATCH[1]}" | ||
testdomain="${BASH_REMATCH[2]}" | ||
[ -n "$DEBUG" ] && echo "Testing hosted zone ${testdomain}" | ||
TMP_NAME=$testdomain | ||
if [[ ! "$TMP_NAME" =~ [^.]+\.[^.]+ ]]; then | ||
[ -n "$DEBUG" ] && echo "No segments left" | ||
exit 1 | ||
fi | ||
|
||
TMP_ZONE_ID=$(aws --profile=${AWS_CLI_PROFILE} route53 list-hosted-zones --query "HostedZones[?Name=='${testdomain}'].Id | [0]" | sed -e 's/^"//' -e 's/"$//') | ||
|
||
|
||
if [ "${TMP_ZONE_ID}" != "null" ]; then | ||
[ -n "$DEBUG" ] && echo "Found hosted zone ${testdomain}" | ||
HOSTED_ZONE_NAME=${testdomain} | ||
HOSTED_ZONE_ID=$TMP_ZONE_ID | ||
break | ||
fi | ||
done | ||
} | ||
|
||
# If zone ID is specified, then use it to determine the hosted zone name | ||
if [ -n "${HOSTED_ZONE_ID}" ]; then | ||
HOSTED_ZONE_NAME=$(aws --profile=${AWS_CLI_PROFILE} route53 list-hosted-zones --query "HostedZones[?Id=='${ZONE_ID}'].Name | [0]" | sed -e 's/^"//' -e 's/"$//') | ||
# If zone name is specified, then use it to get the zone id | ||
elif [ -n "${HOSTED_ZONE_NAME}" ]; then | ||
HOSTED_ZONE_ID=$(aws --profile=${AWS_CLI_PROFILE} route53 list-hosted-zones --query "HostedZones[?Name=='${HOSTED_ZONE_NAME}'].Id | [0]" | sed -e 's/^"//' -e 's/"$//') | ||
else | ||
determine_hosted_zone_name_and_id | ||
fi | ||
|
||
|
||
if [ -z "${HOSTED_ZONE_ID}" ]; then | ||
echo "Hosted zone id not specified or determined" >&2 | ||
exit 3 | ||
fi | ||
|
||
if [ "$op" = "add" ]; then | ||
ACTION="UPSERT" | ||
elif [ "$op" = "del" ]; then | ||
ACTION="DELETE" | ||
else | ||
echo "Unsupported Operation: $op" >&2 | ||
fi | ||
|
||
CHANGE_BATCH=' | ||
{ | ||
"Comment": "GetSSL LetsEncrypt DNS Challenge", | ||
"Changes": [{ | ||
"Action" : "'"$ACTION"'", | ||
"ResourceRecordSet" : { | ||
"Name" : "'"$RR_NAME"'", | ||
"Type" : "TXT", | ||
"TTL" : '${ttl}', | ||
"ResourceRecords" : [{ | ||
"Value" : "\"'$RR_VALUE'\"" | ||
}] | ||
} | ||
}] | ||
} | ||
' | ||
|
||
|
||
[ -n "$DEBUG" ] && echo "${CHANGE_BATCH}" >&2 | ||
|
||
aws \ | ||
--profile=${AWS_CLI_PROFILE} \ | ||
route53 \ | ||
change-resource-record-sets \ | ||
--hosted-zone-id=${HOSTED_ZONE_ID} \ | ||
--change-batch "${CHANGE_BATCH}" | ||
exit $? |