From 4d7cfb9bf7d3241a42b51d165edc028f21b30856 Mon Sep 17 00:00:00 2001 From: Brian Cunnie Date: Sat, 9 Dec 2017 14:51:25 -0800 Subject: [PATCH] sslip.io returns AAAA (IPv6) records MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api.system.2a01-4f8-c17-b8f--2.sslip.io ➡ 2a01:4f8:c17:b8f::2 - `dashed` domains only (e.g. only "fe80-2a01-4f8-c17--de0e" not "fe80.2a01.4f8.c17..de0e"; DNS doesn't allow two dots next to each other. - mirrored from https://github.com/cunnie/bin/blob/master/pdns_pipe.sh which has colocated tests. --- conf/sslip.io+nono.io.yml | 46 ++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/conf/sslip.io+nono.io.yml b/conf/sslip.io+nono.io.yml index ea56bfe..322941e 100644 --- a/conf/sslip.io+nono.io.yml +++ b/conf/sslip.io+nono.io.yml @@ -43,6 +43,7 @@ pdns_pipe: | # `A` queries for the top-level domain will return this list of addresses. # CHANGEME: change this to your domain's webserver's address XIP_ROOT_ADDRESSES=( "52.0.56.137" ) + XIP_ROOT_ADDRESSES_AAAA=( "2a01:4f8:c17:b8f::2" ) # The public IP addresses on which this xip-pdns server will run. # `NS` queries for the top-level domain will return this list of addresses. @@ -115,11 +116,12 @@ pdns_pipe: | # # xip.io domain helpers # - # note we insert "x{0}" to separate the double parentheses "((" to - # avoid BOSH interpolation getting confused and thinking it needs to insert - # a variable. - IP_PATTERN="(^|\.)(x{0}(x{0}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))($|\.)" - DASHED_IP_PATTERN="(^|-|\.)(x{0}(x{0}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)-){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))($|-|\.)" + IP_PATTERN="(^|\.)(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))($|\.)" + DASHED_IP_PATTERN="(^|-|\.)(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)-){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))($|-|\.)" + # https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses + # We don't use "dotted" IPv6 because DNS doesn't allow two dots next to each other + # e.g. "::1" -> "1..sslip.io" isn't allowed (dig error: `is not a legal name (empty label)`) + DASHED_IPV6_PATTERN="(^|\.)(([0-9a-fA-F]{1,4}-){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-))(\.|$)" qtype_is() { [ "$QTYPE" = "$1" ] || [ "$QTYPE" = "ANY" ] @@ -137,6 +139,10 @@ pdns_pipe: | [[ "$QNAME" =~ $DASHED_IP_PATTERN ]] } + subdomain_is_dashed_ipv6() { + [[ "$QNAME" =~ $DASHED_IPV6_PATTERN ]] + } + resolve_ns_subdomain() { local index="${SUBDOMAIN:3}" echo "${XIP_NS_ADDRESSES[$index-1]}" @@ -152,6 +158,11 @@ pdns_pipe: | echo "${BASH_REMATCH[2]//-/.}" } + resolve_dashed_ipv6_subdomain() { + [[ "$QNAME" =~ $DASHED_IPV6_PATTERN ]] || true + echo "${BASH_REMATCH[2]//-/:}" + } + answer_soa_query() { send_answer "SOA" "$XIP_SOA" } @@ -171,6 +182,13 @@ pdns_pipe: | done } + answer_root_aaaa_query() { + local address + for address in "${XIP_ROOT_ADDRESSES_AAAA[@]}"; do + send_answer "AAAA" "$address" + done + } + answer_mx_query() { set -- "${XIP_MX_RECORDS[@]}" while [ $# -gt 1 ]; do @@ -187,6 +205,14 @@ pdns_pipe: | fi } + answer_subdomain_aaaa_query_for() { + local type="$1" + local address="$(resolve_${type}_subdomain)" + if [ -n "$address" ]; then + send_answer "AAAA" "$address" + fi + } + # # PowerDNS pipe backend implementation @@ -219,5 +245,15 @@ pdns_pipe: | fi fi + if qtype_is "AAAA"; then + if [ $QNAME == $XIP_DOMAIN ]; then + answer_root_aaaa_query + else + if subdomain_is_dashed_ipv6; then + answer_subdomain_aaaa_query_for dashed_ipv6 + fi + fi + fi + send_cmd "END" done