Skip to content

Commit

Permalink
NEW FEATURE: M365_BUILDER() (Microsoft 365 builder) (#2365)
Browse files Browse the repository at this point in the history
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
  • Loading branch information
juliusrickert and tlimoncelli committed May 17, 2023
1 parent 835ea88 commit 08cdba4
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 0 deletions.
49 changes: 49 additions & 0 deletions commands/types/dnscontrol.d.ts
Expand Up @@ -2408,6 +2408,55 @@ declare function LOC_BUILDER_DMS_STR(opts: { label?: string; str: string; alt?:
*/
declare function LOC_BUILDER_STR(opts: { label?: string; str: string; alt?: number; ttl?: Duration }): RecordModifier;

/**
* DNSControl offers a `M365_BUILDER` which can be used to simply set up Microsoft 365 for a domain in an opinionated way.
*
* It defaults to a setup without support for legacy Skype for Business applications.
* It doesn't set up SPF or DMARC. See [`SPF_BUILDER`](/language-reference/record-modifiers/dmarc_builder) and [`DMARC_BUILDER`](/language-reference/record-modifiers/spf_builder).
*
* ## Example
*
* ### Simple example
*
* ```javascript
* M365_BUILDER({
* initialDomain: 'example.onmicrosoft.com',
* });
* ```
*
* This sets up `MX` records, Autodiscover, and DKIM.
*
* ### Advanced example
*
* ```javascript
* M365_BUILDER({
* label: 'test',
* mx: false,
* autodiscover: false,
* dkim: false,
* mdm: true,
* domainGUID: 'test-example-com', // Can be automatically derived in this case, if example.com is the context.
* initialDomain: 'example.onmicrosoft.com',
* });
* ```
*
* This sets up Mobile Device Management only.
*
* ### Parameters
*
* * `label` The label of the Microsoft 365 domain, useful if it is a subdomain (default: `'@'`)
* * `mx` Set an `MX` record? (default: `true`)
* * `autodiscover` Set Autodiscover `CNAME` record? (default: `true`)
* * `dkim` Set DKIM `CNAME` records? (default: `true`)
* * `skypeForBusiness` Set Skype for Business/Microsoft Teams records? (default: `false`)
* * `mdm` Set Mobile Device Management records? (default: `false`)
* * `domainGUID` The GUID of _this_ Microsoft 365 domain (default: `<label>.<context>` with `.` replaced by `-`, no default if domain contains dashes)
* * `initialDomain` The initial domain of your Microsoft 365 tenant/account, ends in `onmicrosoft.com`
*
* @see https://docs.dnscontrol.org/language-reference/record-modifiers/m365_builder
*/
declare function M365_BUILDER(opts: { label?: string; mx?: boolean; autodiscover?: boolean; dkim?: boolean; skypeForBusiness?: boolean; mdm?: boolean; domainGUID?: string; initialDomain?: string }): RecordModifier;

/**
* R53_ZONE lets you specify the AWS Zone ID for an entire domain (D()) or a specific R53_ALIAS() record.
*
Expand Down
70 changes: 70 additions & 0 deletions documentation/functions/record/M365_BUILDER.md
@@ -0,0 +1,70 @@
---
name: M365_BUILDER
parameters:
- label
- mx
- autodiscover
- dkim
- skypeForBusiness
- mdm
- domainGUID
- initialDomain
parameters_object: true
parameter_types:
label: string?
mx: boolean?
autodiscover: boolean?
dkim: boolean?
skypeForBusiness: boolean?
mdm: boolean?
domainGUID: string?
initialDomain: string?
---

DNSControl offers a `M365_BUILDER` which can be used to simply set up Microsoft 365 for a domain in an opinionated way.

It defaults to a setup without support for legacy Skype for Business applications.
It doesn't set up SPF or DMARC. See [`SPF_BUILDER`](/language-reference/record-modifiers/dmarc_builder) and [`DMARC_BUILDER`](/language-reference/record-modifiers/spf_builder).

## Example

### Simple example

{% code title="dnsconfig.js" %}
```javascript
M365_BUILDER({
initialDomain: 'example.onmicrosoft.com',
});
```
{% endcode %}

This sets up `MX` records, Autodiscover, and DKIM.

### Advanced example

{% code title="dnsconfig.js" %}
```javascript
M365_BUILDER({
label: 'test',
mx: false,
autodiscover: false,
dkim: false,
mdm: true,
domainGUID: 'test-example-com', // Can be automatically derived in this case, if example.com is the context.
initialDomain: 'example.onmicrosoft.com',
});
```
{% endcode %}

This sets up Mobile Device Management only.

### Parameters

* `label` The label of the Microsoft 365 domain, useful if it is a subdomain (default: `'@'`)
* `mx` Set an `MX` record? (default: `true`)
* `autodiscover` Set Autodiscover `CNAME` record? (default: `true`)
* `dkim` Set DKIM `CNAME` records? (default: `true`)
* `skypeForBusiness` Set Skype for Business/Microsoft Teams records? (default: `false`)
* `mdm` Set Mobile Device Management records? (default: `false`)
* `domainGUID` The GUID of _this_ Microsoft 365 domain (default: `<label>.<context>` with `.` replaced by `-`, no default if domain contains dashes)
* `initialDomain` The initial domain of your Microsoft 365 tenant/account, ends in `onmicrosoft.com`
128 changes: 128 additions & 0 deletions pkg/js/helpers.js
Expand Up @@ -1633,6 +1633,134 @@ function DMARC_BUILDER(value) {
return TXT(label, record.join('; '));
}

// Documentation of the records: https://learn.microsoft.com/en-us/microsoft-365/enterprise/external-domain-name-system-records?view=o365-worldwide
function M365_BUILDER(name, value) {
// value is optional
if (!value) {
value = {};
}

if (value.mx !== false) {
value.mx = true;
}
if (value.autodiscover !== false) {
value.autodiscover = true;
}
if (value.dkim !== false) {
value.dkim = true;
}

if (!value.label) {
value.label = '@';
}

if (!value.domainGUID) {
// Does not work with dashes in domain name.
// Microsoft uses its own, (probably) deterministic algorithm to transform these domains.
// Unfortunately, underlying algorithm is not known to us.
if (name.indexOf('-') !== -1) {
throw (
'M365_BUILDER requires domainGUID for domains with dashes: ' +
name
);
}

value.domainGUID = name.replace('.', '-');
}

if (value.dkim && !value.initialDomain) {
throw (
"M365_BUILDER requires your M365 account's initial domain to set up DKIM (default: enabled): " +
name
);
}

r = [];

// MX (default: true)
if (value.mx) {
r.push(
MX(
value.label,
0,
value.domainGUID + '.mail.protection.outlook.com.'
)
);
}

// Autodiscover (default: true)
if (value.autodiscover) {
if ((value.label = '@')) {
r.push(CNAME('autodiscover', 'autodiscover.outlook.com.'));
} else {
r.push(
CNAME(
'autodiscover.' + value.label,
'autodiscover.outlook.com.'
)
);
}
}

// DKIM (default: true)
if (value.dkim) {
r.push(
CNAME(
'selector1._domainkey',
'selector1-' +
value.domainGUID +
'._domainkey.' +
value.initialDomain +
'.'
)
);
r.push(
CNAME(
'selector2._domainkey',
'selector2-' +
value.domainGUID +
'._domainkey.' +
value.initialDomain +
'.'
)
);
}

// Skype for Business (default: false)
if (value.skypeForBusiness) {
r.push(CNAME('lyncdiscover', 'webdir.online.lync.com.'));
r.push(CNAME('sip', 'sipdir.online.lync.com.'));
r.push(SRV('_sip._tls', 100, 1, 443, 'sipdir.online.lync.com.'));
r.push(
SRV(
'_sipfederationtls._tcp',
100,
1,
5061,
'sipfed.online.lync.com.'
)
);
}

// Mobile Device Management (default: false)
if (value.mdm) {
r.push(
CNAME(
'enterpriseregistration',
'enterpriseregistration.windows.net.'
)
);
r.push(
CNAME(
'enterpriseenrollment',
'enterpriseenrollment.manage.microsoft.com.'
)
);
}

return r;
}

// This is a no-op. Long TXT records are handled natively now.
function DKIM(arr) {
return arr;
Expand Down

0 comments on commit 08cdba4

Please sign in to comment.