Documentation
Welcome to LuaDNS!
LuaDNS is a DNS hosting platform which allows easy DNS management (domains and records) and deployment through Git (optional).
Getting Started
In order to use this service you'll need a LuaDNS account, sign up for a free account here:
Git Integration
Git integration is a convenient way to manage your DNS settings, it allows you to keep all your zones and records in a git repository. This brings all the benefits of a version control system: change history, rollback, commit hooks, shared access between team members and a powerful Lua scripting that helps generate records and simplify configuration.
After each git push
, our build system will pull the DNS settings from the
your git repository. Your configuration files are analyzed, validated and then
DNS zones and records are distributed to our name servers. At the end, you will
receive an email notification with the build status.
Account Setup
To configure the git integration go to the configuration wizard.
If you want to set up your account manually, you need to follow these steps:
- Set the repository URL in your the settings page.
- Configure your repository to grant read-only access when accessed with your build key, this is optional if your git repository accessible via HTTP(s).
- Configure your repository to issue a HTTP POST request on each push to
https://api.luadns.com/notifications/YOUR_API_KEY/push
,
you'll find your API key on API Keys page.
Example Repository
See example repository and ready to use templates.
Troubleshooting
Use curl
to trigger a manual rebuild of your zones:
$ curl -X POST https://api.luadns.com/notifications/YOUR_API_KEY/push
DNSSEC
You can improve domain security by enabling DNSSEC, this allows you to digitally sign your DNS records.
To start using DNSSEC you must enable it from the zone settings page. When DNSSEC is enabled, a pair of DNSKEY will be generated automatically: KSK (Key Signing Key) and ZSK (Zone Signing Key). The zone is signed and distributed to our name servers to be served right away.
The KSK is used to sign DNSKEY records and ZSK is used to sign other records. Using two keys together allows us to roll a new ZSK without updating the DS record in the parent zone.
Before enabling DNSSEC check that your registrar supports DS records with algorithm 13 (ECDSA Curve P-256 with SHA-256).
Some registries supports automated DNSSEC provisioning via CDS/CDNSKEY record signaling (RFC 7344). We support CDS & CDNSKEY records, they are generated automatically when DNSSEC is enabled.
Lua Zone File Format
Users have the option to store their configurations in a standard Bind format or to use more powerful Lua format.
Resource Records
LuaDNS supports most common Resource Records:
AAAA, ALIAS, A, CNAME, DS, FORWARD, HTTPS, MX, NS, PTR, REDIRECT, SOA, SPF, SRV, SSHFP, TLSA, TXT
A Record
A Record Syntax:
-- @name = relative name
-- @ip = IPv4 address
-- @ttl = TTL (default: user default TTL)
a(name, ip, ttl)
Example:
a("mail", "1.2.3.4")
AAAA Record
AAAA Record Syntax:
-- @name = relative name
-- @ip = IPv6 address
-- @ttl = TTL (default: user default TTL)
aaaa(name, ip, ttl)
Example:
aaaa("mail", "2001:4860:4860::8888")
ALIAS Record
ALIAS Record Syntax:
-- @name = relative name
-- @target = target host (fqdn)
-- @ttl = TTL (default: user default TTL)
alias(name, target, ttl)
This record is suited to solve the DNS restriction with CNAME on apex (root, naked) domains.
The system creates A and AAAA records for name
with the
IP addresses found while resolving target
. The target is polled
periodically and the A and AAAA records are updated when changes
are detected.
Example:
alias(_a, "myapp.herokuapp.com")
CAA Record
CAA Record Syntax:
-- @name = relative name
-- @value = value
-- @tag = tag (issue, issuewild, iodef, default: issue)
-- @flag = flag (default: 0)
-- @ttl = TTL (default: user default TTL)
caa(name, value, tag, flag, ttl)
Example:
caa("", "letsencrypt.org", "issue")
caa("", "mailto:user@example.com", "iodef")
CNAME Record
CNAME Record Syntax:
-- @name = relative name
-- @alias = alias (fqdn)
-- @ttl = TTL (default: user default TTL)
cname(name, alias, ttl)
Example:
cname("www", "example.com")
DS Record
DS Record Syntax:
-- @name = relative name
-- @keytag = key tag
-- @digest = digest (hexadecimal characters)
-- @algorithm = algorithm (default: 13)
-- @digest_type = digest type (default: 2)
-- @ttl = TTL (default: user default TTL)
ds(name, keytag, digest, algorithm, digest_type, ttl)
Example:
-- Add a DS record for `us` subdomain using default values for
-- algorithm (13 = ECDSAP256SHA256) and digest type (2 = SHA256).
ds("us", 22021, "D657C7EE6B88F0F4163B69BE8B4DCBEAEC32DA3C3E8AA5B62F6E630D97A7DDEF")
FORWARD Record
The FORWARD pseudo record configures LuaDNS mail servers to accept and forward emails to an external email provider.
FORWARD Record Syntax:
-- @from = mailbox name (without domain)
-- @to = recipient (email address)
-- @ttl = cache TTL (default: user default TTL)
forward(from, to, ttl)
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
-- Forward mailbox `joe@example.com` to `bob@mailinator.com`.
forward("bob", "bob@mailinator.com")
-- Catch-all forward.
-- Forward all unmatched mailboxes to alice@mailinator.com.
forward("*", "alice@mailinator.com")
HTTPS Record
HTTPS Record Syntax:
-- @name = relative name
-- @target = target (fqdn)
-- @svc_prio = priority (default: 0)
-- @svc_params = params table (default: {})
-- @ttl = TTL (default: user default TTL)
https(name, target, svc_prio, svc_params, ttl)
The svc_prio
parameter specifies
- when == 0 - alias mode
- when != 0 - service mode
The svc_params
is a list of key=value pairs. Supported keys:
- alpn
- ech
- ipv4hint
- ipv6hint
- mandatory
- no-default-alpn
- port
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
-- Create an alias for apex/root domain.
https(_a, "lb.cdn-example.net")
-- Create a failover config (lower prio numbers have higher priority).
https("www", "svc1.example.net", 10, {alpn="http/1.1,h2"})
https("www", "svc2.example.net", 20, {alpn="http/1.1,h2"})
-- Configure Encrypted Client Hello (ECH).
https("app", "svc3.example.net", 1, {alpn="http/1.1,h2", ech="base64_public_key"})
MX Record
MX Record Syntax:
-- @name = relative name
-- @exchanger = mail exchanger(fqdn)
-- @prio = priority (default: 0)
-- @ttl = TTL (default: user default TTL)
mx(name, exchanger, prio, ttl)
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
mx(_a, "aspmx.l.google.com", 10)
NS Record
NS Record Syntax:
-- @name = relative name
-- @server = name server (fqdn)
-- @ttl = TTL (default: user default TTL)
ns(name, server, ttl)
Name servers are automatically added for each zone found in the repository, you don't have to specify them.
Example:
-- File: example.com.lua
-- delegate uk.example.com to uk-ns1.example.com, uk-ns2.example.com name servers
ns("uk", "uk-ns1.example.com")
ns("uk", "uk-ns2.example.com")
PTR Record
PTR Record Syntax:
-- @name = relative name
-- @host = host name (fqdn)
-- @ttl = TTL (default: user default TTL)
ptr(name, host, ttl)
Example:
-- File: 1.168.192.in-addr.arpa.lua
ptr("1", "server.example.com")
-- File: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.lua
ptr("1", "localhost.example.com")
REDIRECT Record
The REDIRECT pseudo record configures the DNS servers and HTTP redirection service to allow easy HTTP redirections.
REDIRECT Record Syntax:
-- @name = relative name
-- @target = target url
-- @mode = redirect mode (0=relative, 1=exact, 2=frame, default: 0)
-- @ttl = cache TTL (default: user default TTL)
redirect(name, target, mode, ttl)
The mode
parameter specifies how the name
is going
to be redirected to target
:
- 0 - relative mode, server appends the path and query
string to
target
and issues a301
redirect - 1 - exact mode, server issues a
301
redirect totarget
URL - 2 - frame mode, server returns a HTML page which
loads the the
target
URL in a frame
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
-- Default mode (301 redirect)
-- Redirect http://example.com/* to http://www.example.com/*
-- http://example.com/foo => http://www.example.com/foo
-- http://example.com/foo?param=bar => http://www.example.com/foo?param=bar
redirect(_a, "http://www.example.com/")
-- Exact mode (301 redirect)
-- Redirect http://app.example.com/* to https://secure.example.com/home
-- http://app.example.com/foo => https://secure.example.com/home
-- http://app.example.com/foo?param=bar => https://secure.example.com/home
redirect("app", "https://secure.example.com/home", 1)
-- Frame mode
-- Returns a page which loads http://www.example.net/webmail in a frame
-- http://webmail.example.com/ => http://www.example.net/webmail
redirect("webmail", "http://www.example.net/webmail", 2)
SOA Record
SOA record it's created by automatically by the system, you don't have to specify one.
SPF Record
SPF Record Syntax:
-- @name = relative name
-- @text = text
-- @ttl = TTL (default: user default TTL)
spf(name, text, ttl)
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
spf(_a, "v=spf1 a mx include:_spf.google.com ~all")
SRV Record
SRV Record Syntax:
-- @name = relative name
-- @target = host name(fqdn)
-- @port = port number
-- @prio = prio (default: 0)
-- @weight = weight (default: 0)
-- @ttl = TTL (default: user default TTL)
srv(name, target, port, prio, weight, ttl)
Example:
-- File: example.com
srv("_sip._tcp", "sipserver.example.com", 5060)
SSHFP Record
SSHFP Record Syntax:
-- @name = relative name
-- @algorithm = algorithm number (1=RSA, 2=DSA, 3=ECDSA, 4=Ed25519)
-- @fp_value = fingerprint (presented in hex)
-- @fp_type = fingerprint type (1=SHA-1, 2=SHA-256, default: 1)
-- @ttl = TTL (default: user default TTL)
sshfp(name, algorithm, fp_value, fp_type, ttl)
Example:
-- File: example.com
-- Run ssh-keygen tool to print the SSHFP fingerprint resource record:
-- $ ssh-keygen -f /etc/ssh/ssh_host_rsa_key.pub -r myserver
-- myserver IN SSHFP 1 1 34b1436fa3d5cf235563efe42a9223ae1c6b486e
-- $ ssh-keygen -f /etc/ssh/ssh_host_dsa_key.pub -r myserver
-- myserver IN SSHFP 2 1 0392244baae593a996b354f473b350c4c2afe9f3
sshfp("myserver", 1, "34b1436fa3d5cf235563efe42a9223ae1c6b486e")
sshfp("myserver", 2, "0392244baae593a996b354f473b350c4c2afe9f3")
TLSA Record
TLSA Record Syntax:
-- @name = relative name
-- @usage = usage (0 - PKIX-TA, 1 - PKIX-EE, 2 - DANE-TA, 3 - DANE-EE)
-- @certificate = certificate association data (hex)
-- @selector = selector (0 - Cert, 1 - SPKI, default: 1)
-- @matching_type = matching type (1=SHA-256, 2=SHA-512, default: 1)
-- @ttl = TTL (default: user default TTL)
tlsa(name, usage, certificate, selector, matching_type, ttl)
Example:
-- File: example.com
tlsa("_25._tcp.mail", 3, "0c72ac70b745ac19998811b131d662c9ac69dbdbe7cb23e5b514b56664c5d3d6")
TXT Record
TXT Record Syntax:
-- @name = relative name
-- @text = text
-- @ttl = TTL (default: user default TTL)
txt(name, text, ttl)
Example:
-- File: example.com.lua
-- _a variable is set by the system to zone name
-- _a = "example.com"
txt(_a, "google-site-verification=vEj1ZcGtXeM_UEjnCqQEhxPSqkS9IQ4PBFuh48FP8o4")
Wildcard Record
Wildcard records are supported, example usage:
-- File: example.com.lua
-- Variable _a is replaced with zone name by LuaDNS
-- _a = "example.com"
-- *.example.com resolves to 1.2.3.4
a("*", "1.2.3.4")
-- Email for *.uk.example.com is handled by mx-eu.example.com
a("*.uk", concat("mx-eu", _a))
User default TTL
In a Resource Records definition user default TTL (default: 3600 seconds) is used when TTL is not specified, you can change your default TTL from the account settings page.
System Functions
concat
The concat
function concatenates two names using dot, used usually to
construct host names for the content part of the record.
Syntax:
-- @name = label
-- @domain = domain
concat(name, domain)
Example:
-- File: example.com.lua
-- Variable _a is replaced with zone name by LuaDNS
-- _a = "example.com"
-- Add a MX exchanger mail.example.com.
mx("", concat("mail", _a))
-- This is equivalent with the above example.
mx("", "mail." .. _a)
slave
The slave
functions is a helper to add a local or third party secondary name
server to current zone. To add multiple servers invoke the slave
function
multiple times.
You have to configure your secondary slave servers to use axfr.luadns.net or IP 108.61.179.251 as primary name server.
Syntax:
-- @name = relative name or hostname
-- @ip = IPv4 address
-- @ttl = TTL (default: user default TTL)
slave(name, ip, ttl)
The IP address is used to configure access for AXFR transfers and to send NOTIFY messages.
Example:
-- File: example.com.lua
-- Local secondary (relative name)
-- It inserts a NS record and an A record:
-- example.com. IN NS ns1.example.com.
-- example.com. IN A 1.1.1.1
slave("ns1", "1.1.1.1")
-- Third party secondary server (hostname)
-- It inserts only a NS record:
-- example.com. IN NS ns1.third-party-ns.com.
slave("ns1.third-party-ns.com", "2.2.2.2")
ignore
The ignore
function instructs the build system to ignore the records managed
outside of git (API, DynDNS).
Syntax:
-- @name = ignore name (relative name)
-- @text = ignore types (default: A,AAAA)
ignore(name, types)
Example:
-- File: example.com.lua
-- Ignore A, AAAA and TXT records with name 'example.com'.
ignore("", "A,AAAA,TXT")
-- Ignore A and AAAA records with name 'myserver.example.com'.
ignore("myserver")
-- Ignore TXT and SPF records with name `test*.example.com`.
ignore("test%", "TXT,SPF")
System Variables
- _a - variable is set by compiler to zone name (extracted from file name).
Example:_a = "example.com"
for configuration file example.com.lua.
Comments
Comments are simple Lua comments:
A comment starts with a double hyphen (--) anywhere outside a string. If the text immediately after -- is not an opening long bracket, the comment is a short comment, which runs until the end of the line. Otherwise, it is a long comment, which runs until the corresponding closing long bracket. Long comments are frequently used to disable code temporarily.
Templates
Templates are simulated through Lua functions. Global functions/templates
should be grouped in templates.lua
file in your repository. Functions defined
here are available to each zone.
Example (templates.lua
):
function google_app(domain)
-- Configure Google Apps mail exchangers
mx(domain, "aspmx.l.google.com", 5)
mx(domain, "alt1.aspmx.l.google.com", 10)
mx(domain, "alt2.aspmx.l.google.com", 10)
mx(domain, "aspmx2.googlemail.com", 20)
mx(domain, "aspmx3.googlemail.com", 20)
-- Additional Google Apps records
cname(concat("calendar", domain), "ghs.google.com")
cname(concat("docs", domain), "ghs.google.com")
cname(concat("mail", domain), "ghs.google.com")
cname(concat("sites", domain), "ghs.google.com")
-- Configure SPF
txt(domain, "v=spf1 a mx include:_spf.google.com ~all")
end
Domain aliases
When dealing with multiple domains sharing the same configuration to avoid cluttering the repository with zone files, LuaDNS allows domain aliases to be specified in .clones files:
Example:
$ ls -al example.com.*
-rw-r--r-- 1 vitalie vitalie 25 2012-04-18 00:31 example.com.clones
-rw-r--r-- 1 vitalie vitalie 266 2012-03-01 12:46 example.com.lua
$ cat example.com.clones
example.org
example.info
The system will generate the same set of records for example.org, example.info mirroring records from example.com.
Zone transfers (AXFR)
LuaDNS can be configured to function together with external slave servers. To configure a slave server use slave function. Example:
-- File: example.com.lua
-- Zone: example.com
-- Add two slave servers (ns1.example.com, ns2.example.com)
-- required A and NS records are created automatically
slave("ns1", "1.1.1.1")
slave("ns2", "1.1.1.2")
-- Add two external slave servers
-- required NS records are created automatically
slave("ns1.third-party-ns.com", "2.2.2.1")
slave("ns1.third-party-ns.com", "2.2.2.2")
-- Please, configure your ACLs on slave servers
-- to use axfr.luadns.net or IP 108.61.179.251.
Examples
Basic Example
-- File: example.com.lua
-- Variable _a is replaced with zone name by LuaDNS
-- _a = "example.com"
-- A Records
a(_a, "1.2.3.4")
-- CNAME Records
cname("www", _a)
-- MX Records
mx(_a, _a)
Advanced Example
-- File: example.com.lua
-- Zone: example.com
-- Variable _a is replaced with zone name by LuaDNS
-- _a = "example.com"
-- A records
a(_a, "1.2.3.4")
-- CNAME records
cname("www", _a)
cname("ftp", _a)
-- Templates
google_app(_a)
-- Add 2 slave servers (ns1.example.com, ns2.example.com)
-- required A and NS records are created automatically
slave("ns1", "1.1.1.1")
slave("ns2", "1.1.1.2")
Bind Zone File Format
LuaDNS has native support for Bind zone files, add Bind files
to your git repository (use .bind extension) and push modifications
with git (git push origin master
).
Your configuration files will be parsed, validated and deployed to our name servers, shortly you'll receive from us an email with status of the deployment.
Examples:
- Git repository: https://github.com/luadns/dns
- Bind zone file: https://github.com/luadns/dns/blob/master/example.org.bind
Information on Bind zone file format is available here: https://www.zytrax.com/books/dns/ch8
Supported directives
- $TTL
- $ORIGIN
Supported Records
- A
- AAAA
- CNAME
- MX
- NS
- PTR
- SOA
- SPF
- SRV
- SSHFP
- TXT
Vanity Name Servers
There are many situations when you need to use your vanity name servers with your domains, example:
- ns1.yourcompany.com
- ns2.yourcompany.com
To configure your account to use vanity name servers follow this steps:
- Create ns1-2.yourcompany.com name servers (A & AAAA records) in yourcompany.com zone
- Add glue records (A & AAAA) for ns1-2.yourcompany.com servers at your registrar
- Add ns1-2.yourcompany.com to Vanity Servers in the settings page
Create Vanity Name Servers
Edit yourcompany.com zone and create A & AAAA records for each name server pointing to our IP addresses:
# A records
ns1.yourcompany.com -> 185.142.218.1
ns2.yourcompany.com -> 185.142.218.2
# AAAA records
ns1.yourcompany.com -> 2001:67c:25a0::1
ns2.yourcompany.com -> 2001:67c:25a0::2
If you have more than 4 name servers you can reuse one of the IPv4 & IPv6 addresses.
Add Glue Records for Vanity Name Servers
If you intend to use your vanity name servers ns1-2.yourcompany.com for yourcompany.com domain, you'll have to add glue records (same A & AAAA records) for each vanity name server at your registrar.
Use Your Vanity Servers
To use your vanity name servers instead of defaults, edit your account and add your name servers (one name server per line) in the "Vanity Servers" textarea.
Example:
ns1.yourcompany.com
ns2.yourcompany.com
Next time when you'll create/update a zone via web GUI or git, your name servers will be injected automatically instead of the default ones (ns1-4.luadns.net).
Dynamic DNS Update
We support dyndns2
protocol, check the Dynamic DNS Update page for more details.