mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-10-30 18:50:53 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			254 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <style>
 | |
| #custom-dns-current td.long {
 | |
|   word-break: break-all;
 | |
| }
 | |
| </style>
 | |
| 
 | |
| <h2>Custom DNS</h2>
 | |
| 
 | |
| <p class="text-warning">This is an advanced configuration page.</p>
 | |
| 
 | |
| <p>It is possible to set custom DNS records on domains hosted here.</p>
 | |
| 
 | |
| <h3>Set Custom DNS Records</h3>
 | |
| 
 | |
| <p>You can set additional DNS records, such as if you have a website running on another server, to add DKIM records for external mail providers, or for various confirmation-of-ownership tests.</p>
 | |
| 
 | |
| <form class="form-horizontal" role="form" onsubmit="do_set_custom_dns(); return false;">
 | |
|   <div class="form-group">
 | |
|     <label for="customdnsQname" class="col-sm-1 control-label">Name</label>
 | |
|     <div class="col-sm-10">
 | |
|       <table style="max-width: 400px">
 | |
|       <tr><td>
 | |
|         <input type="text" class="form-control" id="customdnsQname" placeholder="subdomain">
 | |
|       </td><td style="padding: 0 1em; font-weight: bold;">.</td><td>
 | |
|         <select id="customdnsZone" class="form-control"> </select>
 | |
|       </td></tr></table>
 | |
|       <div class="text-info" style="margin-top: .5em">Leave the left field blank to set a record on the chosen domain name, or enter a subdomain.</div>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <label for="customdnsType" class="col-sm-1 control-label">Type</label>
 | |
|     <div class="col-sm-10">
 | |
|       <select id="customdnsType" class="form-control" style="max-width: 400px" onchange="show_customdns_rtype_hint()">
 | |
|         <option value="A" data-hint="Enter an IPv4 address (i.e. a dotted quad, such as 123.456.789.012).">A (IPv4 address)</option>
 | |
|         <option value="AAAA" data-hint="Enter an IPv6 address.">AAAA (IPv6 address)</option>
 | |
|         <option value="CNAME" data-hint="Enter another domain name followed by a period at the end (e.g. mypage.github.io.).">CNAME (DNS forwarding)</option>
 | |
|         <option value="TXT" data-hint="Enter arbitrary text.">TXT (text record)</option>
 | |
|         <option value="MX" data-hint="Enter record in the form of PRIORIY DOMAIN., including trailing period (e.g. 20 mx.example.com.).">MX (mail exchanger)</option>
 | |
|       </select>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <label for="customdnsValue" class="col-sm-1 control-label">Value</label>
 | |
|     <div class="col-sm-10">
 | |
|       <input type="text" class="form-control" id="customdnsValue" placeholder="">
 | |
|       <div id="customdnsTypeHint" class="text-info" style="margin-top: .5em"></div>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="col-sm-offset-1 col-sm-11">
 | |
|       <button type="submit" class="btn btn-primary">Set Record</button>
 | |
|     </div>
 | |
|   </div>
 | |
| </form>
 | |
| 
 | |
| <table id="custom-dns-current" class="table" style="width: auto; display: none">
 | |
|   <thead>
 | |
|     <th>Domain Name</th>
 | |
|     <th>Record Type</th>
 | |
|     <th>Value</th>
 | |
|     <th></th>
 | |
|   </thead>
 | |
|   <tbody>
 | |
|     <tr><td colspan="4">Loading...</td></tr>
 | |
|   </tbody>
 | |
| </table>
 | |
| 
 | |
| <h3>Using a Secondary Nameserver</h3>
 | |
| 
 | |
| <p>If your TLD requires you to have two separate nameservers, you can either set up a secondary (aka “slave”) nameserver or, alternatively, set up <a href="#" onclick="return show_panel('external_dns')">external DNS</a> and ignore the DNS server on this box. If you choose to use a seconday/slave nameserver, you must find a seconday/slave nameserver service provider. Your domain name registrar or virtual cloud provider may provide this service for you. Once you set up the seconday/slave nameserver service, enter the hostname of <em>their</em> secondary nameserver:</p>
 | |
| 
 | |
| <form class="form-horizontal" role="form" onsubmit="do_set_secondary_dns(); return false;">
 | |
|   <div class="form-group">
 | |
|     <label for="secondarydnsHostname" class="col-sm-1 control-label">Hostname</label>
 | |
|     <div class="col-sm-10">
 | |
|       <input type="text" class="form-control" id="secondarydnsHostname" placeholder="ns1.cloudprovider.com">
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="col-sm-offset-1 col-sm-11">
 | |
|       <button type="submit" class="btn btn-primary">Update</button>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div id="secondarydns-clear-instructions" class="form-group" style="display: none">
 | |
|     <div class="col-sm-offset-1 col-sm-11">
 | |
|       <p class="small">Clear the input field above and click Update to use this machine itself as secondary DNS, which is the default/normal setup.</p>
 | |
|     </div>
 | |
|   </div>
 | |
| </form>
 | |
| 
 | |
| 
 | |
| <h3>Custom DNS API</h3>
 | |
| 
 | |
| <p>Use your box’s DNS API to set custom DNS records on domains hosted here. For instance, you can create your own dynamic DNS service.</p>
 | |
| 
 | |
| <p>Usage:</p>
 | |
| 
 | |
| <pre>curl -X <b>VERB</b> [-d "<b>value</b>"] --user {email}:{password} https://{{hostname}}/admin/dns/custom[/<b>qname</b>[/<b>rtype</b>]]</pre>
 | |
| 
 | |
| <p>(Brackets denote an optional argument.)</p>
 | |
| 
 | |
| <h4>Verbs</h4>
 | |
| 
 | |
| <table class="table">
 | |
| <thead><th>Verb</th> <th>Usage</th></thead>
 | |
| <tr><td>GET</td> <td>Returns matching custom DNS records as a JSON array of objects. Each object has the keys <code>qname</code>, <code>rtype</code>, and <code>value</code>. The optional <code>qname</code> and <code>rtype</code> parameters in the request URL filter the records returned in the response. The request body (<code>-d "..."</code>) must be omitted.</td></tr>
 | |
| <tr><td>PUT</td> <td>Sets a custom DNS record replacing any existing records with the same <code>qname</code> and <code>rtype</code>. Use PUT (instead of POST) when you only have one value for a <code>qname</code> and <code>rtype</code>, such as typical <code>A</code> records (without round-robin).</td></tr>
 | |
| <tr><td>POST</td> <td>Adds a new custom DNS record. Use POST when you have multiple <code>TXT</code> records or round-robin <code>A</code> records. (PUT would delete previously added records.)</td></tr>
 | |
| <tr><td>DELETE</td> <td>Deletes custom DNS records. If the request body (<code>-d "..."</code>) is empty or omitted, deletes all records matching the <code>qname</code> and <code>rtype</code>. If the request body is present, deletes only the record matching the <code>qname</code>, <code>rtype</code> and value.</td></tr>
 | |
| </table>
 | |
| 
 | |
| <h4>Parameters</h4>
 | |
| 
 | |
| <table class="table">
 | |
| <thead><th>Parameter</th> <th>Value</th></thead>
 | |
| <tr><td>email</td> <td>The email address of any administrative user here.</td></tr>
 | |
| <tr><td>password</td> <td>That user’s password.</td></tr>
 | |
| <tr><td>qname</td> <td>The fully qualified domain name for the record you are trying to set. It must be one of the domain names or a subdomain of one of the domain names hosted on this box. (Add mail users or aliases to add new domains.)</td></tr>
 | |
| <tr><td>rtype</td> <td>The resource type. Defaults to <code>A</code> if omitted. Possible values: <code>A</code> (an IPv4 address), <code>AAAA</code> (an IPv6 address), <code>TXT</code> (a text string), <code>CNAME</code> (an alias, which is a fully qualified domain name — don’t forget the final period), <code>MX</code>, or <code>SRV</code>.</td></tr>
 | |
| <tr><td>value</td> <td>For PUT, POST, and DELETE, the record’s value. If the <code>rtype</code> is <code>A</code> or <code>AAAA</code> and <code>value</code> is empty or omitted, the IPv4 or IPv6 address of the remote host is used (be sure to use the <code>-4</code> or <code>-6</code> options to curl). This is handy for dynamic DNS!</td></tr>
 | |
| </table>
 | |
| 
 | |
| <p>Strict <a href="http://tools.ietf.org/html/rfc4408">SPF</a> and <a href="https://datatracker.ietf.org/doc/draft-kucherawy-dmarc-base/?include_text=1">DMARC</a> records will be added to all custom domains unless you override them.</p>
 | |
| 
 | |
| <h4>Examples:</h4>
 | |
| 
 | |
| <p>Try these examples. For simplicity the examples omit the <code>--user me@mydomain.com:yourpassword</code> command line argument which you must fill in with your email address and password.</p>
 | |
| 
 | |
| <pre># sets laptop.mydomain.com to point to the IP address of the machine you are executing curl on
 | |
| curl -X PUT https://{{hostname}}/admin/dns/custom/laptop.mydomain.com
 | |
| 
 | |
| # deletes that record and all A records for that domain name
 | |
| curl -X DELETE https://{{hostname}}/admin/dns/custom/laptop.mydomain.com
 | |
| 
 | |
| # sets a CNAME alias
 | |
| curl -X PUT -d "bar.mydomain.com." https://{{hostname}}/admin/dns/custom/foo.mydomain.com/cname
 | |
| 
 | |
| # deletes that CNAME and all CNAME records for that domain name
 | |
| curl -X DELETE https://{{hostname}}/admin/dns/custom/foo.mydomain.com/cname
 | |
| 
 | |
| # adds a TXT record using POST to preserve any previous TXT records
 | |
| curl -X POST -d "some text here" https://{{hostname}}/admin/dns/custom/foo.mydomain.com/txt
 | |
| 
 | |
| # deletes that one TXT record while preserving other TXT records
 | |
| curl -X DELETE -d "some text here" https://{{hostname}}/admin/dns/custom/foo.mydomain.com/txt
 | |
| </pre>
 | |
| 
 | |
| <script>
 | |
| function show_custom_dns() {
 | |
|   api(
 | |
|     "/dns/secondary-nameserver",
 | |
|     "GET",
 | |
|     { },
 | |
|     function(data) {
 | |
|       $('#secondarydnsHostname').val(data.hostname ? data.hostname : '');
 | |
|       $('#secondarydns-clear-instructions').toggle(data.hostname != null);
 | |
|     });
 | |
| 
 | |
|   api(
 | |
|     "/dns/zones",
 | |
|     "GET",
 | |
|     { },
 | |
|     function(data) {
 | |
|       $('#customdnsZone').text('');
 | |
|       for (var i = 0; i < data.length; i++) {
 | |
|         $('#customdnsZone').append($('<option/>').text(data[i]));
 | |
|       }
 | |
|     });
 | |
| 
 | |
|   show_current_custom_dns();
 | |
|   show_customdns_rtype_hint();
 | |
| }
 | |
| 
 | |
| function show_current_custom_dns() {
 | |
|   api(
 | |
|     "/dns/custom",
 | |
|     "GET",
 | |
|     { },
 | |
|     function(data) {
 | |
|       if (data.length > 0)
 | |
|         $('#custom-dns-current').fadeIn();
 | |
|       else
 | |
|         $('#custom-dns-current').fadeOut();
 | |
| 
 | |
|       $('#custom-dns-current').find("tbody").text('');
 | |
|       for (var i = 0; i < data.length; i++) {
 | |
|         var tr = $("<tr/>");
 | |
|         $('#custom-dns-current').find("tbody").append(tr);
 | |
|         tr.attr('data-qname', data[i].qname);
 | |
|         tr.attr('data-rtype', data[i].rtype);
 | |
|         tr.attr('data-value', data[i].value);
 | |
|         tr.append($('<td class="long"/>').text(data[i].qname));
 | |
|         tr.append($('<td/>').text(data[i].rtype));
 | |
|         tr.append($('<td class="long"/>').text(data[i].value));
 | |
|         tr.append($('<td>[<a href="#" onclick="return delete_custom_dns_record(this)">delete</a>]</td>'));
 | |
|       }
 | |
|     });
 | |
| }
 | |
| 
 | |
| function delete_custom_dns_record(elem) {
 | |
|   var qname = $(elem).parents('tr').attr('data-qname');
 | |
|   var rtype = $(elem).parents('tr').attr('data-rtype');
 | |
|   var value = $(elem).parents('tr').attr('data-value');
 | |
|   do_set_custom_dns(qname, rtype, value, "DELETE");
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| function do_set_secondary_dns() {
 | |
|  api(
 | |
|     "/dns/secondary-nameserver",
 | |
|     "POST",
 | |
|     {
 | |
|       hostname: $('#secondarydnsHostname').val()
 | |
|     },
 | |
|     function(data) {
 | |
|       if (data == "") return; // nothing updated
 | |
|       show_modal_error("Secondary DNS", $("<pre/>").text(data));
 | |
|       $('#secondarydns-clear-instructions').slideDown();
 | |
|     },
 | |
|     function(err) {
 | |
|       show_modal_error("Secondary DNS", $("<pre/>").text(err));
 | |
|     });
 | |
| }
 | |
| 
 | |
| function do_set_custom_dns(qname, rtype, value, method) {
 | |
|   if (!qname) {
 | |
|     if ($('#customdnsQname').val() != '')
 | |
|       qname = $('#customdnsQname').val() + '.' + $('#customdnsZone').val();
 | |
|     else
 | |
|       qname = $('#customdnsZone').val();
 | |
|     rtype = $('#customdnsType').val();
 | |
|     value = $('#customdnsValue').val();
 | |
|     method = 'POST';
 | |
|   }
 | |
| 
 | |
|   api(
 | |
|     "/dns/custom/" + qname + "/" + rtype,
 | |
|     method,
 | |
|     value,
 | |
|     function(data) {
 | |
|       if (data == "") return; // nothing updated
 | |
|       show_modal_error("Custom DNS", $("<pre/>").text(data));
 | |
|       show_current_custom_dns();
 | |
|     },
 | |
|     function(err) {
 | |
|       show_modal_error("Custom DNS (Error)", $("<pre/>").text(err));
 | |
|     });
 | |
| }
 | |
| 
 | |
| function show_customdns_rtype_hint() {
 | |
|   $('#customdnsTypeHint').text($("#customdnsType").find('option:selected').attr('data-hint'));
 | |
| }
 | |
| </script>
 |