IPv4 to IPv6 Proxy API

April 21st, 2023 by

We’ve been offering IPv6-only hosting for eight years now, and have demonstrated that many websites can forego the expense of an IPv4 address pretty easily. You can read more about how we do this on this blog post from 2020. This blog post itself is being served from an IPv6-only server!

A key part of this is our IPv4-to-IPv6 proxy. This listens for incoming traffic on a shared IPv4 address and forwards it to your IPv6-only server. In order to use the proxy, you need to tell it which hostnames to listen for, and which server or servers to forward traffic to. This can be done using our control panel, and as of today, it can also be done via an API.

Having an API for proxy configuration makes it possible to automatically add or remove backend servers, allowing you to spin up additional servers, or take servers out of service for failover or maintenance.

You can also use the API to add and remove hostnames handled by the proxy, and so can be used to automate the provisioning of new services.

Fine-grained access controls

As for our DNS API and Domain API, the Proxy API provides fine-grained access control for API keys. For example, you can create an API key that only has access to a specified domain or hostname, or you can create a read-only API key if you only need to read the current configuration.

Getting started

Our IPv4-to-IPv6 proxy is available to all customers with a Mythic Beasts server, including virtual servers, Raspberry Pi servers, dedicated and colo. You can find more information on the proxy service, and the Proxy API on our support pages.

Domain Management API

October 1st, 2021 by

We’ve just rolled out a new addition to our range of APIs for managing services: the Domain Management API. This new API allows you automate management of your Mythic Beasts domain registrations.

Access to the API is controlled by API keys, which can be managed in our customer control panel. As for our DNS API, the keys provide fine-grained control over access, allow you to grant permissions on individual domains, or all domains on your account, and to restrict a key’s access to specific actions.

API Key Configuration screenshot

Fine-grained access control

The API gives access to information about your domains, such as the expiry date, nameservers, and domain status.

At present, the API only supports a small number of actions, although we intend to expand this in the near future. At present, the following actions are supported:

  • Setting nameservers
  • Setting DS records
  • Locking/unlocking domains (where supported)

The ability to set DS records makes it possible to automate DNSSEC key roll-over, although it’s worth noting that we offer a free managed DNSSEC service which takes care of this for you, so you’ll only need to use this if you particularly want to control your DS records yourself.

The API is currently in public beta, and documentation can be found on our support site. We’d very much welcome feedback on the API, including suggestions for operations that you’d like to see supported. If you have any feedback, please contact us on support@mythic-beasts.com.

More DNS API fun: find an IP across all zones

September 21st, 2020 by

A customer was doing an IP address change on a server and wanted a quick way to find all references to the old IP address across all of their domains.

This seemed like a good job for our DNS API and a few UNIX utilities.

Finding matching records

Our DNS API makes it easy to find records with particular content:

curl -sn https://api.mythic-beasts.com/dns/v2/zones/example1.com/records?data=1.2.3.4

The -n assumes we’ve got a .netrc file with our API credentials. See our DNS API tutorial for more details.

This gives us a block of JSON with any matching records:

{
  "records": [
    {
      "data": "1.2.3.4",
      "host": "www",
      "ttl": 300,
      "type": "A"
    }
  ]
}

jq lets us turn the presence or absence of any matching records into an exit code that we can test with an if statement by piping into the following:

jq -e '.records | length > 0' 

This counts the number of members of the records array, and -e sets the exit code based on the output of the last expression.

Getting a list of zones

We want to check this across all zones, so let’s get a list of zones:

curl -sn https://api.mythic-beasts.com/dns/v2/zones

This gives us some JSON:

{
  "zones": [
    "example1.com",
    "example2.com"
  ]
}

What we really want is a flat list, so we can iterate over it in bash. jq to the rescue again. Simply pipe into:

jq -r '.zones[]'

and we get:

example1.com
example2.com

Putting it all together

Putting this all together with a for loop and an if:

IP=1.2.3.4
for zone in $(curl -sn https://api.mythic-beasts.com/dns/v2/zones | jq -r '.zones[]') ; do
  if curl -sn "https://api.mythic-beasts.com/dns/v2/zones/$zone/records?data=$IP" |\
      jq -e '.records | length > 0' >/dev/null ; then 
    echo "$IP found in $zone"
  fi
done

Gives:

1.2.3.4 found in example1.com

More than one way to do it

Another approach would be to use the zone file output format and check if the output is empty or not:

curl -sn -H 'Accept: text/dns' \
  "https://api.mythic-beasts.com/dns/v2/zones/$zone/records?data=$IP"

This give us matching records, one per line:

www         300 A 1.2.3.4

We can then test if we’ve got any matches using ifne (if-not-empty, part of the moreutils package in most distributions):

curl -sn -H 'Accept: text/dns' \
  "https://api.mythic-beasts.com/dns/v2/zones/$zone/records?data=$IP" \
  | ifne echo $IP found in $zone

Access to our DNS API is included with all domains registered with us. API credentials can be limited to individual zones or even records, can be either read/write or read-only.

ANAME records

Of course, it’s generally desirable to avoid including an IP address in lots of different DNS records in the first place. It’s preferable to assign the IP to a single hostname, and then point other records at that. Our DNS service supports ANAME records which allow the use of hostnames rather than IP addresses in places where CNAMEs cannot be used.

Automating DNS challenges

May 5th, 2020 by

We recently announced our new DNS API which we’ve just moved out of beta and into production. 

One of the goals of the new API was better support for automating DNS-based challenges, such as those used by Let’s Encrypt to authenticate certificate requests. 

DNS-based challenges are needed to obtain wildcard certificates from Let’s Encrypt, and can be a convenient way to get certificates for hostnames that don’t a have publicly accessible web server, but can be tricky to implement due to delays in updating DNS records, and automatic requires having credentials capable of DNS records for your domain stored on your server.

The new API has a number of features to address these issues.

Restricted credentials

The DNS API allows you to create API credentials that are restricted to editing specific records within your domain.  Credentials can be restricted by hostname, record type, or both.

For example, you can create credentials that can only edit the _acme-challenge TXT record needed for Let’s Encrypt challenges. Access to the DNS API is potentially very sensitive, so it makes sense to limit access as much as possible.

Restricted API key

Record verification

Updates made via the API do not become live immediately. There is a delay of up to a minute before they hit our master nameserver, and a potential further delay of a few seconds before the record propagates to our authoritative nameservers. When responding to a DNS-based challenge, you will typically want to ensure that the record is actually live before proceeding with verification.

Our DNS API provides a “verify” feature, that checks that records are live on all authoritative nameservers. For example, a GET request to the following URL would check that the nameservers have the latest update to the record:

https://api.mythic-beasts.com/dns/v2/zones/example.com/records/_acme-challenge/TXT?verify

This will return a 200 response if the nameservers are up-to-date, and 409 if they are not. This can be used to script a check after updating a record:

#!/bin/sh

ZONE=example.com
RECORD=_acme-challenge
TYPE=TXT

for i in $(seq 1 12); do
    RES=$(curl -n https://api.mythic-beasts.com/dns/v2/zones/$ZONE/records/$RECORD/$TYPE?verify -qs -w '%{http_code}' -o /dev/null)
    case $RES in
        200)    echo Records updated
                exit 0
                ;;
        409)    echo "Not yet updated ($i/12)"
                ;;
        *)      echo "Unexpected error: $RES"
                exit 1
                ;;
    esac
    sleep 10
done
echo Timed out
exit 2

Obtaining certificates the easy way

Our preferred Let’s Encrypt client is the excellent dehydrated, and we maintain a hook script for supporting DNS-based challenges in dehydrated. We haven’t yet updated the hook script to support our new API, but will be doing so soon and will post details here when it’s ready.

New DNS API

April 6th, 2020 by

We’ve just launched our new DNS API, which provides a much cleaner and more powerful API for automatic management of DNS records.

Key features of the new API include:

  • Configurable auth credentials – restrict access to individual records, or record types.  Ideal for Let’s Encrypt or other DNS-based challenges.
  • Choice of JSON or zone file format for input and output.
  • Atomic multi-record updates – update arbitrary sets of records in a single transaction.
  • Form parameters for record creation – record creation can be trivially scripted using curl.
  • Broad record type support – CAA, SSHFP, TLSA, SRV and many more.

For a walk through of the features of the new API, please see our DNS API tutorial , or for more details see the reference documentation.

To get started with the API, use the API keys section of the control panel to create some credentials.

Configurable API permits

Restricted API credentials for Let’s Encrypt challenges

The new API is currently in public beta, meaning that we reserve the right to make last minute breaking changes to the API, although we expect any such changes to be minor, and we would very much like to hear any feedback you may have.