mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-05 23:56:50 +08:00
PowerDNS's pipe backend's configuration is included
- also include instructions to run tests
This commit is contained in:
22
README.md
22
README.md
@@ -1,10 +1,24 @@
|
||||
# sslip.io [](https://ci.nono.io/?groups=sslip.io)
|
||||
# sslip.io
|
||||
|
||||
[](https://ci.nono.io/?groups=sslip.io)
|
||||
|
||||
*sslip.io* is a domain that maps specially-crafted DNS A records to IP addresses
|
||||
(e.g. "127-0-0-1.sslip.io" maps to 127.0.0.1). It is similar to, and inspired
|
||||
by, [xip.io](http://xip.io/).
|
||||
(e.g. "127-0-0-1.sslip.io" maps to 127.0.0.1). It is similar to, inspired by,
|
||||
and uses much of the code of [xip.io](http://xip.io/).
|
||||
|
||||
Refer to the website ([sslip.io](https://sslip.io)) for more information.
|
||||
|
||||
- `document_root/` contains the HTML content of the sslip.io website
|
||||
- `ci/` contains the Concourse CI pipeline and task
|
||||
- `ci/` contains the [Concourse](https://concourse.ci/) continuous integration
|
||||
(CI) pipeline and task.
|
||||
- `spec/` contains the RSpec files for test driven development (TDD).
|
||||
To run the tests:
|
||||
```bash
|
||||
DOMAIN=sslip.io rspec spec/
|
||||
```
|
||||
- `conf/sslip.io+nono.io.yml` contains the
|
||||
[PowerDNS](https://www.powerdns.com/)'s [pipe
|
||||
backend](https://doc.powerdns.com/md/authoritative/backend-pipe/)'s
|
||||
configuration in YAML format for use with [BOSH](https://bosh.io). The
|
||||
`pdns_pipe` key is the pipe backend script, and `pdns_pipe_conf` is its
|
||||
configuration file.
|
||||
|
261
conf/sslip.io+nono.io.yml
Normal file
261
conf/sslip.io+nono.io.yml
Normal file
@@ -0,0 +1,261 @@
|
||||
pdns_named_conf: |
|
||||
zone "nono.com" {
|
||||
type slave;
|
||||
file "/var/vcap/jobs/pdns/etc/nono.com";
|
||||
masters { 78.46.204.247; };
|
||||
};
|
||||
zone "nono.io" {
|
||||
type slave;
|
||||
file "/var/vcap/jobs/pdns/etc/nono.io";
|
||||
masters { 78.46.204.247; };
|
||||
};
|
||||
pdns_conf: |
|
||||
launch=bind:first,pipe:second
|
||||
slave=yes
|
||||
bind-first-config=/var/vcap/jobs/pdns/etc/named.conf
|
||||
pipe-second-command=/var/vcap/jobs/pdns/bin/pipe /var/vcap/jobs/pdns/etc/pipe.conf
|
||||
pdns_pipe: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
shopt -s nocasematch
|
||||
|
||||
#
|
||||
# Configuration
|
||||
#
|
||||
XIP_DOMAIN="xip.test"
|
||||
XIP_ROOT_ADDRESSES=( "127.0.0.1" )
|
||||
XIP_NS_ADDRESSES=( "127.0.0.1" )
|
||||
XIP_MX_RECORDS=( )
|
||||
XIP_TIMESTAMP="0"
|
||||
XIP_TTL=300
|
||||
|
||||
if [ -a "$1" ]; then
|
||||
source "$1"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Protocol helpers
|
||||
#
|
||||
read_cmd() {
|
||||
local IFS=$'\t'
|
||||
local i=0
|
||||
local arg
|
||||
|
||||
read -ra CMD
|
||||
for arg; do
|
||||
eval "$arg=\"\${CMD[$i]}\""
|
||||
let i=i+1
|
||||
done
|
||||
}
|
||||
|
||||
send_cmd() {
|
||||
local IFS=$'\t'
|
||||
printf "%s\n" "$*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
send_cmd "FAIL"
|
||||
log "Exiting"
|
||||
exit 1
|
||||
}
|
||||
|
||||
read_helo() {
|
||||
read_cmd HELO VERSION
|
||||
[ "$HELO" = "HELO" ] && [ "$VERSION" = "1" ]
|
||||
}
|
||||
|
||||
read_query() {
|
||||
read_cmd TYPE QNAME QCLASS QTYPE ID IP
|
||||
}
|
||||
|
||||
send_answer() {
|
||||
local type="$1"
|
||||
shift
|
||||
send_cmd "DATA" "$QNAME" "$QCLASS" "$type" "$XIP_TTL" "$ID" "$@"
|
||||
}
|
||||
|
||||
log() {
|
||||
printf "[xip-pdns:$$] %s\n" "$@" >&2
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# xip.io domain helpers
|
||||
#
|
||||
XIP_DOMAIN_PATTERN="(^|\.)${XIP_DOMAIN//./\.}\$"
|
||||
NS_SUBDOMAIN_PATTERN="^ns-([0-9]+)\$"
|
||||
IP_SUBDOMAIN_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_SUBDOMAIN_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]?))\$"
|
||||
BASE36_SUBDOMAIN_PATTERN="(^|\.)([a-z0-9]{1,7})\$"
|
||||
|
||||
qtype_is() {
|
||||
[ "$QTYPE" = "$1" ] || [ "$QTYPE" = "ANY" ]
|
||||
}
|
||||
|
||||
qname_matches_domain() {
|
||||
[[ "$QNAME" =~ $XIP_DOMAIN_PATTERN ]]
|
||||
}
|
||||
|
||||
qname_is_root_domain() {
|
||||
[ "$QNAME" = "$XIP_DOMAIN" ]
|
||||
}
|
||||
|
||||
extract_subdomain_from_qname() {
|
||||
SUBDOMAIN="${QNAME:0:${#QNAME}-${#XIP_DOMAIN}}"
|
||||
SUBDOMAIN="${SUBDOMAIN%.}"
|
||||
}
|
||||
|
||||
subdomain_is_ns() {
|
||||
[[ "$SUBDOMAIN" =~ $NS_SUBDOMAIN_PATTERN ]]
|
||||
}
|
||||
|
||||
subdomain_is_ip() {
|
||||
[[ "$SUBDOMAIN" =~ $IP_SUBDOMAIN_PATTERN ]]
|
||||
}
|
||||
|
||||
subdomain_is_dashed_ip() {
|
||||
[[ "$SUBDOMAIN" =~ $DASHED_IP_SUBDOMAIN_PATTERN ]]
|
||||
}
|
||||
|
||||
subdomain_is_base36() {
|
||||
[[ "$SUBDOMAIN" =~ $BASE36_SUBDOMAIN_PATTERN ]]
|
||||
}
|
||||
|
||||
resolve_ns_subdomain() {
|
||||
local index="${SUBDOMAIN:3}"
|
||||
echo "${XIP_NS_ADDRESSES[$index-1]}"
|
||||
}
|
||||
|
||||
resolve_ip_subdomain() {
|
||||
[[ "$SUBDOMAIN" =~ $IP_SUBDOMAIN_PATTERN ]] || true
|
||||
echo "${BASH_REMATCH[2]}"
|
||||
}
|
||||
|
||||
resolve_dashed_ip_subdomain() {
|
||||
[[ "$SUBDOMAIN" =~ $DASHED_IP_SUBDOMAIN_PATTERN ]] || true
|
||||
echo "${BASH_REMATCH[2]//-/.}"
|
||||
}
|
||||
|
||||
resolve_base36_subdomain() {
|
||||
[[ "$SUBDOMAIN" =~ $BASE36_SUBDOMAIN_PATTERN ]] || true
|
||||
local ip=$(( 36#${BASH_REMATCH[2]} ))
|
||||
printf "%d.%d.%d.%d" $(( ip&0xFF )) $(( (ip>>8)&0xFF )) $(( (ip>>16)&0xFF )) $(( (ip>>24)&0xFF ))
|
||||
}
|
||||
|
||||
answer_soa_query() {
|
||||
send_answer "SOA" "admin.$XIP_DOMAIN ns-1.$XIP_DOMAIN $XIP_TIMESTAMP $XIP_TTL $XIP_TTL $XIP_TTL $XIP_TTL"
|
||||
}
|
||||
|
||||
answer_ns_query() {
|
||||
local i=1
|
||||
local ns_address
|
||||
for ns in "${XIP_NS[@]}"; do
|
||||
send_answer "NS" "$ns"
|
||||
done
|
||||
}
|
||||
|
||||
answer_root_a_query() {
|
||||
local address
|
||||
for address in "${XIP_ROOT_ADDRESSES[@]}"; do
|
||||
send_answer "A" "$address"
|
||||
done
|
||||
}
|
||||
|
||||
answer_mx_query() {
|
||||
set -- "${XIP_MX_RECORDS[@]}"
|
||||
while [ $# -gt 1 ]; do
|
||||
send_answer "MX" "$1 $2"
|
||||
shift 2
|
||||
done
|
||||
}
|
||||
|
||||
answer_subdomain_a_query_for() {
|
||||
local type="$1"
|
||||
local address="$(resolve_${type}_subdomain)"
|
||||
if [ -n "$address" ]; then
|
||||
send_answer "A" "$address"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# PowerDNS pipe backend implementation
|
||||
#
|
||||
trap fail err
|
||||
read_helo
|
||||
send_cmd "OK" "xip.io PowerDNS pipe backend (protocol version 1)"
|
||||
|
||||
while read_query; do
|
||||
log "Query: type=$TYPE qname=$QNAME qclass=$QCLASS qtype=$QTYPE id=$ID ip=$IP"
|
||||
|
||||
if qname_matches_domain; then
|
||||
if qname_is_root_domain; then
|
||||
if qtype_is "SOA"; then
|
||||
answer_soa_query
|
||||
fi
|
||||
|
||||
if qtype_is "NS"; then
|
||||
answer_ns_query
|
||||
fi
|
||||
|
||||
if qtype_is "A"; then
|
||||
answer_root_a_query
|
||||
fi
|
||||
|
||||
if qtype_is "MX"; then
|
||||
answer_mx_query
|
||||
fi
|
||||
|
||||
elif qtype_is "A"; then
|
||||
extract_subdomain_from_qname
|
||||
|
||||
if subdomain_is_ns; then
|
||||
answer_subdomain_a_query_for ns
|
||||
|
||||
elif subdomain_is_dashed_ip; then
|
||||
answer_subdomain_a_query_for dashed_ip
|
||||
|
||||
elif subdomain_is_ip; then
|
||||
answer_subdomain_a_query_for ip
|
||||
|
||||
elif subdomain_is_base36; then
|
||||
answer_subdomain_a_query_for base36
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
send_cmd "END"
|
||||
done
|
||||
pdns_pipe_conf: |
|
||||
# Increment this timestamp when the contents of the file change.
|
||||
XIP_TIMESTAMP="2016090200"
|
||||
|
||||
# The top-level domain for which the name server is authoritative.
|
||||
# CHANGEME: change "sslip.io" to your domain
|
||||
XIP_DOMAIN="sslip.io"
|
||||
|
||||
# The public IP addresses (e.g. for the web site) of the top-level domain.
|
||||
# `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" )
|
||||
|
||||
# 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.
|
||||
# Each entry maps to a 1-based subdomain of the format `ns-1`, `ns-2`, etc.
|
||||
# `A` queries for these subdomains map to the corresponding addresses here.
|
||||
# CHANGEME: change this to match your NS records; one of these IP addresses
|
||||
# should match the jobs(xip).networks.static_ips listed above
|
||||
XIP_NS_ADDRESSES=( "52.0.56.137" "78.47.249.19" )
|
||||
XIP_NS=( "ns-aws.nono.io" "ns-gce.nono.io" "ns-he.nono.io" )
|
||||
|
||||
# These are the MX records for your domain. IF YOU'RE NOT SURE,
|
||||
# don't set it at at all (comment it out)--it defaults to no
|
||||
# MX records.
|
||||
XIP_MX_RECORDS=(
|
||||
"10" "mx.zoho.com"
|
||||
"20" "mx2.zoho.com"
|
||||
)
|
||||
|
||||
# How long responses should be cached, in seconds.
|
||||
XIP_TTL=300
|
Reference in New Issue
Block a user