In this article, you will learn:
WEDOS DNS
WEDOS DNS can function either as primary or secondary:
- Primary DNS means that DNS records are stored and delivered directly via WEDOS DNS servers. To use DNS in primary mode, you need to add the domain, as well as copy or import its DNS records. Once the records are migrated, you don’t have to maintain them with the previous provider and use WEDOS instead.
- Secondary DNS are stored on another provider’s authoritative DNS server, and WEDOS DNS only references them. This configuration is harder to set up (see the ZONE – Whitelabel article for more information) and requires you to maintain a custom DNS server.
While secondary DNS allows your applications to communicate with your original DNS solution and rely on WEDOS solely for distribution, maintaining your own DNS infrastructure may be too cost-ineffective, if you’re using WEDOS anyway. To learn how to migrate your existing records to WEDOS as primary DNS, either use the DNS AXFR import interface, or WAPI, as described below.
Migrate DNS via WAPI
To automate DNS migration for a large number of domains or records, we suggest using a variant of the WAPI script provided below.
If this is your first time encountering WAPI, go through the WAPI Manual first.
Keep in mind, that there is a limit of 1000 WAPI requests per hour. Take into account 1 request to add a domain to WAPI, plus 1 per request.
The provided WAPI script uses PHP to:
- read data from a simple .zone (BIND format) file,
- extract the DNS records, and
- use WAPI to create the domain and populate it with those records.
Read from .zone File
This section covers reading data from a single example .zone (BIND) file. The script works for files following these criteria:
- Record name area for main domain is blank (no
@
ordomain.tld.
), subdomains are referenced by name (such aswww
). - The SOA record is inline, e.g.
@ IN SOA ns1.example-dns.tld.
, and at the top.ns2.example-dns.tld
. - Each DNS record must appear on a single line.
- Directives such as
$ORIGIN
or$INCLUDE
are not supported. - Comments (text after
;
) are allowed, the script will ignore them.
Here is a sample file for reference:
$TTL 3600
@ IN SOA ns1.example-dns.tld. ns2.example-dns.tld. (
1234567890 ; Serial (YYYYMMDDnn)
7200 ; Refresh
1800 ; Retry
1209600 ; Expire
3600 ; Minimum TTL
)
IN NS ns1.example-dns.tld.
IN NS ns2.example-dns.tld.
IN A 46.28.105.2
IN MX 10 mail.wds-test.org.
www IN CNAME wds-test.eu.
Extract DNS Records
To handle this file and extract DNS record information, you can use (and modify as needed) the following script:
$filename = 'domain.zone'; // Load a .zone file
if (!file_exists($filename)) {
die("Error: File $filename not found.<br>");
}
$rawLines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$dnsRecords = [];
$inSOABlock = false;
foreach ($rawLines as $line) {
$trimmed = trim($line);
// Skip $TTL
if (stripos($trimmed, '$TTL') === 0) {
continue;
}
// Handle start of SOA block
if (preg_match('/\bSOA\b/i', $trimmed)) {
$inSOABlock = true;
continue;
}
// Skip lines inside SOA block
if ($inSOABlock) {
// Remove comments before checking for closing parenthesis
$noComment = explode(';', $trimmed)[0];
if (strpos($noComment, ')') !== false) {
$inSOABlock = false;
}
continue;
}
// Skip NS records
if (preg_match('/(^|\s)IN\s+NS\s/i', $trimmed)) {
continue;
}
// Skip empty lines
if (empty($trimmed)) {
continue;
}
// Parse each line into structured data
$record = [];
if (preg_match('/^(?:(\S+)\s+)?IN\s+(A|AAAA|MX|CNAME|TXT)\s+(.*)$/i', $trimmed, $matches)) {
$record['name'] = isset($matches[1]) ? $matches[1] : "";
$record['type'] = $matches[2];
$record['rdata'] = $matches[3];
$dnsRecords[] = $record;
}
}
This script:
- Loads a single
.zone
file. - Skips the
TTL
,SOA
andNS
records, as well as empty lines. - Stores each record of type
A
,AAAA
,MX
,CNAME
orTXT
in the$dnsRecords
array.
You may want to modify it to:
- Load multiple files or read from other file types.
- Work for different record name conventions.
- Store other record types in the array.
Add Domain and Records to DNS
Finally, automate adding the domain and records to DNS. Before you do, make sure you have WAPI configured according to the WAPI Manual.
Also, replace $wapiLogin = 'login@domain.tld'
and $wapiPassword = 'WAPI_password'
with your specific values.
$domain = 'domain.tld'; // Domain name
// Set CEST timezone for timestamp verification
date_default_timezone_set('Europe/Prague');
// WEDOS WAPI credentials and settings
$wapiUrl = 'https://api.wedos.com/wapi/json';
$wapiLogin = 'login@domain.tld';
$wapiPassword = 'WAPI_password';
// Function to make WAPI requests
function wapiRequest($command, $data) {
global $wapiUrl, $wapiLogin, $wapiPassword;
// Construct the authorization string
$dateHour = date('H', time());
$auth = sha1($wapiLogin.sha1($wapiPassword).$dateHour);
// Construct the request payload
$payload = array(
'request' => array(
'user' => $wapiLogin,
'auth' => $auth,
'command' => $command,
'data' => $data,
'clTRID' => 'dns' . date('YmdHis')
)
);
echo json_encode($payload);
// Initialize cURL session
$ch = curl_init($wapiUrl);
// Set cURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('request' => json_encode($payload))));
// Execute cURL session
$response = curl_exec($ch);
// Close cURL session
curl_close($ch);
return json_decode($response, true);
}
$response = wapiRequest('dns-domain-add', 'array('name' => $domain)'); // Create domain in DNS
foreach ($dnsRecords as $record) {
$response = wapiRequest('dns-row-add', array(
'domain' => $domain,
'name' => $record['name'],
'ttl' => 300,
'type' => $record['type'],
'rdata' => $record['rdata']
)); // Populate domain with DNS records
}
This script:
- Creates a universal
wapiRequest
function to send requests to WAPI. - Adds the domain to WEDOS DNS and then adds the records.
You may want to add:
- Custom logic based on response
code
. For more information, check the article WAPI – WEDOS DNS.
FAQ
Can I import primary DNS via AXFR?
The interface for AXFR imports is currently in development. It will also support BIND format text and file inputs.