mobileconfig
This commit is contained in:
@@ -0,0 +1,237 @@
|
|||||||
|
# Mail And Radicale
|
||||||
|
|
||||||
|
This repo currently configures mail for `billenius.com` on `Hermes`.
|
||||||
|
|
||||||
|
## Hosts
|
||||||
|
|
||||||
|
- Mail server: `mail.billenius.com`
|
||||||
|
- Thunderbird autoconfig: `autoconfig.billenius.com`
|
||||||
|
- Outlook-style autodiscover: `autodiscover.billenius.com`
|
||||||
|
- CalDAV/CardDAV via Radicale: `cal.billenius.com`
|
||||||
|
- Apple configuration profile: `https://autoconfig.billenius.com/mobileconfig/?emailaddress=love%40billenius.com`
|
||||||
|
- Webmail via Roundcube: `https://mail.billenius.com`
|
||||||
|
|
||||||
|
## Repo Locations
|
||||||
|
|
||||||
|
- Core mail settings: `modules/nixos/mail-server/mail.nix`
|
||||||
|
- Mail autodiscovery XML: `modules/nixos/mail-server/autodiscover.nix`
|
||||||
|
- Radicale and DAV discovery: `modules/nixos/mail-server/radicale.nix`
|
||||||
|
- Roundcube: `modules/nixos/mail-server/roundcube.nix`
|
||||||
|
|
||||||
|
## What The Repo Configures
|
||||||
|
|
||||||
|
### Mail
|
||||||
|
|
||||||
|
- IMAP over SSL on `mail.billenius.com:993`
|
||||||
|
- SMTP submission with STARTTLS on `mail.billenius.com:587`
|
||||||
|
- Webmail on `https://mail.billenius.com`
|
||||||
|
- ACME certificates for the mail-related nginx hosts
|
||||||
|
|
||||||
|
### Autodiscovery
|
||||||
|
|
||||||
|
- Thunderbird mail config at `https://autoconfig.billenius.com/mail/config-v1.1.xml`
|
||||||
|
- Outlook-style mail config at `https://autodiscover.billenius.com/autodiscover/autodiscover.xml`
|
||||||
|
- Thunderbird XML also advertises:
|
||||||
|
- CardDAV: `https://cal.billenius.com/`
|
||||||
|
- CalDAV: `https://cal.billenius.com/`
|
||||||
|
|
||||||
|
### Radicale
|
||||||
|
|
||||||
|
- Radicale is reverse proxied on `https://cal.billenius.com/`
|
||||||
|
- Authentication uses the same mail accounts and password hashes as the mail server
|
||||||
|
- DAV discovery redirects are served on:
|
||||||
|
- `https://mail.billenius.com/.well-known/caldav`
|
||||||
|
- `https://mail.billenius.com/.well-known/carddav`
|
||||||
|
- `https://cal.billenius.com/.well-known/caldav`
|
||||||
|
- `https://cal.billenius.com/.well-known/carddav`
|
||||||
|
|
||||||
|
This repo does not manage the apex website host for `billenius.com`. If the public website should also expose DAV redirects on `/.well-known/caldav` and `/.well-known/carddav`, that has to be configured on the separate nginx host serving `billenius.com`.
|
||||||
|
|
||||||
|
### Apple Mobileconfig
|
||||||
|
|
||||||
|
- The canonical Apple profile entrypoint is:
|
||||||
|
- `https://autoconfig.billenius.com/mobileconfig/?emailaddress=<url-encoded-email>`
|
||||||
|
- Apple profiles are hosted from `autoconfig.billenius.com`
|
||||||
|
- A small landing page is available at:
|
||||||
|
- `https://autoconfig.billenius.com/mobileconfig/`
|
||||||
|
- Account-specific profiles are always available at:
|
||||||
|
- `https://autoconfig.billenius.com/mobileconfig/<sanitized-email>.mobileconfig`
|
||||||
|
- If there is exactly one configured mail account, the profile is also available at:
|
||||||
|
- `https://autoconfig.billenius.com/mobileconfig/billenius.mobileconfig`
|
||||||
|
|
||||||
|
The profile configures:
|
||||||
|
|
||||||
|
- IMAP on `mail.billenius.com:993`
|
||||||
|
- SMTP submission on `mail.billenius.com:587`
|
||||||
|
- CalDAV on `cal.billenius.com:443`
|
||||||
|
- CardDAV on `cal.billenius.com:443`
|
||||||
|
|
||||||
|
Passwords are not embedded in the profile.
|
||||||
|
|
||||||
|
## DNS
|
||||||
|
|
||||||
|
These records are expected for good client discovery.
|
||||||
|
|
||||||
|
### Host Records
|
||||||
|
|
||||||
|
- `mail.billenius.com`
|
||||||
|
- `cal.billenius.com`
|
||||||
|
- `autoconfig.billenius.com`
|
||||||
|
- `autodiscover.billenius.com`
|
||||||
|
|
||||||
|
`cal.billenius.com`, `autoconfig.billenius.com`, and `autodiscover.billenius.com` can point at the same host as `mail.billenius.com`.
|
||||||
|
|
||||||
|
### Mail SRV
|
||||||
|
|
||||||
|
```dns
|
||||||
|
_imaps._tcp.billenius.com. SRV 0 0 993 mail.billenius.com.
|
||||||
|
_submission._tcp.billenius.com. SRV 0 0 587 mail.billenius.com.
|
||||||
|
```
|
||||||
|
|
||||||
|
### DAV SRV/TXT
|
||||||
|
|
||||||
|
```dns
|
||||||
|
_caldavs._tcp.billenius.com. SRV 0 0 443 cal.billenius.com.
|
||||||
|
_carddavs._tcp.billenius.com. SRV 0 0 443 cal.billenius.com.
|
||||||
|
|
||||||
|
_caldavs._tcp.billenius.com. TXT "path=/"
|
||||||
|
_carddavs._tcp.billenius.com. TXT "path=/"
|
||||||
|
```
|
||||||
|
|
||||||
|
## iOS Setup
|
||||||
|
|
||||||
|
The preferred setup path on Apple devices is to open the hosted profile in Safari:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://autoconfig.billenius.com/mobileconfig/?emailaddress=love%40billenius.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the profile, then enter the password when prompted.
|
||||||
|
|
||||||
|
The manual steps below are the fallback path.
|
||||||
|
|
||||||
|
### Mail
|
||||||
|
|
||||||
|
iOS does not reliably do full self-hosted IMAP setup from the same discovery flow that Thunderbird uses. The hosted `.mobileconfig` profile is the best path for one-step Apple setup.
|
||||||
|
|
||||||
|
1. Open `Settings`
|
||||||
|
2. Go to `Apps` -> `Mail` -> `Mail Accounts` -> `Add Account`
|
||||||
|
3. Choose `Other`
|
||||||
|
4. Choose `Add Mail Account`
|
||||||
|
5. Use:
|
||||||
|
- Email: full mail address, for example `love@billenius.com`
|
||||||
|
- Incoming host: `mail.billenius.com`
|
||||||
|
- Outgoing host: `mail.billenius.com`
|
||||||
|
- Username: full mail address
|
||||||
|
- Password: the mail password
|
||||||
|
6. iOS should use:
|
||||||
|
- IMAP SSL on `993`
|
||||||
|
- SMTP submission on `587`
|
||||||
|
|
||||||
|
### Calendar
|
||||||
|
|
||||||
|
1. Open `Settings`
|
||||||
|
2. Go to `Apps` -> `Calendar` -> `Calendar Accounts` -> `Add Account`
|
||||||
|
3. Choose `Other`
|
||||||
|
4. Choose `Add CalDAV Account`
|
||||||
|
5. Use:
|
||||||
|
- Server: `cal.billenius.com`
|
||||||
|
- Username: full mail address
|
||||||
|
- Password: the mail password
|
||||||
|
|
||||||
|
### Contacts
|
||||||
|
|
||||||
|
1. Open `Settings`
|
||||||
|
2. Go to `Apps` -> `Contacts` -> `Contacts Accounts` -> `Add Account`
|
||||||
|
3. Choose `Other`
|
||||||
|
4. Choose `Add CardDAV Account`
|
||||||
|
5. Use:
|
||||||
|
- Server: `cal.billenius.com`
|
||||||
|
- Username: full mail address
|
||||||
|
- Password: the mail password
|
||||||
|
|
||||||
|
If the goal is a single Apple setup flow that provisions mail, calendars, and contacts together, use the hosted `.mobileconfig` profile on `autoconfig.billenius.com` instead of adding the accounts manually.
|
||||||
|
|
||||||
|
## Thunderbird Setup
|
||||||
|
|
||||||
|
### Mail
|
||||||
|
|
||||||
|
Thunderbird should discover mail automatically from the email address alone.
|
||||||
|
|
||||||
|
1. Open Thunderbird
|
||||||
|
2. Add a new mail account
|
||||||
|
3. Enter the email address and password
|
||||||
|
4. Thunderbird should pick up `mail.billenius.com` from `autoconfig.billenius.com`
|
||||||
|
|
||||||
|
### Contacts
|
||||||
|
|
||||||
|
Thunderbird's mail account wizard does not reliably attach CardDAV address books automatically, even when the XML, SRV/TXT records, and `/.well-known` endpoints exist.
|
||||||
|
|
||||||
|
The reliable path is:
|
||||||
|
|
||||||
|
1. Open `Address Book`
|
||||||
|
2. Choose `New Address Book` -> `Add CardDAV Address Book`
|
||||||
|
3. Use:
|
||||||
|
- Username: full mail address
|
||||||
|
- Location: `https://cal.billenius.com/`
|
||||||
|
4. Authenticate
|
||||||
|
5. Select the discovered address books
|
||||||
|
|
||||||
|
### Calendars
|
||||||
|
|
||||||
|
The reliable path is:
|
||||||
|
|
||||||
|
1. Open `Calendar`
|
||||||
|
2. Choose `New Calendar`
|
||||||
|
3. Choose `On the Network`
|
||||||
|
4. Use:
|
||||||
|
- Username: full mail address
|
||||||
|
- Location: `https://cal.billenius.com/`
|
||||||
|
5. Choose `Find Calendars`
|
||||||
|
6. Subscribe to the discovered calendars
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
### Thunderbird XML
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://autoconfig.billenius.com/mail/config-v1.1.xml
|
||||||
|
curl https://autodiscover.billenius.com/autodiscover/autodiscover.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
### DAV Well-Known
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -I https://mail.billenius.com/.well-known/caldav
|
||||||
|
curl -I https://mail.billenius.com/.well-known/carddav
|
||||||
|
curl -I https://cal.billenius.com/.well-known/caldav
|
||||||
|
curl -I https://cal.billenius.com/.well-known/carddav
|
||||||
|
```
|
||||||
|
|
||||||
|
Each should return a `301` redirect to `https://cal.billenius.com/`.
|
||||||
|
|
||||||
|
### DNS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dig +short SRV _imaps._tcp.billenius.com
|
||||||
|
dig +short SRV _submission._tcp.billenius.com
|
||||||
|
dig +short SRV _caldavs._tcp.billenius.com
|
||||||
|
dig +short SRV _carddavs._tcp.billenius.com
|
||||||
|
dig +short TXT _caldavs._tcp.billenius.com
|
||||||
|
dig +short TXT _carddavs._tcp.billenius.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Current Limitation
|
||||||
|
|
||||||
|
The standards-based discovery in this repo is good enough for:
|
||||||
|
|
||||||
|
- Thunderbird mail autodiscovery
|
||||||
|
- DAV discovery for many clients
|
||||||
|
- manual but short setup flows on iOS and Thunderbird
|
||||||
|
|
||||||
|
It is not enough to guarantee that:
|
||||||
|
|
||||||
|
- Thunderbird's mail wizard will also attach calendars and contacts automatically
|
||||||
|
- iOS will provision mail, contacts, and calendars in one combined login flow
|
||||||
|
|
||||||
|
For that, the next likely improvement is an Apple `mobileconfig` profile and, if needed, client-specific setup documentation.
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./autodiscover.nix
|
./autodiscover.nix
|
||||||
./mail.nix
|
./mail.nix
|
||||||
|
./mobileconfig.nix
|
||||||
./radicale.nix
|
./radicale.nix
|
||||||
./roundcube.nix
|
./roundcube.nix
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.mailserver;
|
||||||
|
hasMailDiscoveryConfig = cfg.enable && cfg.fqdn != null && cfg.domains != [ ];
|
||||||
|
in
|
||||||
|
lib.mkIf hasMailDiscoveryConfig (
|
||||||
|
let
|
||||||
|
domain = builtins.head cfg.domains;
|
||||||
|
mobileconfigHost = "autoconfig.${domain}";
|
||||||
|
radicaleHost = "cal.${domain}";
|
||||||
|
safeAccountName = email: builtins.replaceStrings [ "@" "+" ] [ "_" "-" ] email;
|
||||||
|
|
||||||
|
mkUuid = seed:
|
||||||
|
let
|
||||||
|
hash = builtins.hashString "sha256" seed;
|
||||||
|
in
|
||||||
|
"${lib.substring 0 8 hash}-${lib.substring 8 4 hash}-${lib.substring 12 4 hash}-${lib.substring 16 4 hash}-${lib.substring 20 12 hash}";
|
||||||
|
|
||||||
|
mkMobileconfig = email:
|
||||||
|
let
|
||||||
|
safeName = safeAccountName email;
|
||||||
|
profileUuid = mkUuid "${email}-apple-profile";
|
||||||
|
mailUuid = mkUuid "${email}-apple-mail";
|
||||||
|
caldavUuid = mkUuid "${email}-apple-caldav";
|
||||||
|
carddavUuid = mkUuid "${email}-apple-carddav";
|
||||||
|
in
|
||||||
|
pkgs.writeText "${safeName}.mobileconfig" ''
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>EmailAccountDescription</key>
|
||||||
|
<string>${domain} Mail</string>
|
||||||
|
<key>EmailAccountName</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>EmailAccountType</key>
|
||||||
|
<string>EmailTypeIMAP</string>
|
||||||
|
<key>EmailAddress</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>IncomingMailServerAuthentication</key>
|
||||||
|
<string>EmailAuthPassword</string>
|
||||||
|
<key>IncomingMailServerHostName</key>
|
||||||
|
<string>${cfg.fqdn}</string>
|
||||||
|
<key>IncomingMailServerPortNumber</key>
|
||||||
|
<integer>993</integer>
|
||||||
|
<key>IncomingMailServerUseSSL</key>
|
||||||
|
<true/>
|
||||||
|
<key>IncomingMailServerUsername</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>OutgoingMailServerAuthentication</key>
|
||||||
|
<string>EmailAuthPassword</string>
|
||||||
|
<key>OutgoingMailServerHostName</key>
|
||||||
|
<string>${cfg.fqdn}</string>
|
||||||
|
<key>OutgoingMailServerPortNumber</key>
|
||||||
|
<integer>587</integer>
|
||||||
|
<key>OutgoingMailServerUseSSL</key>
|
||||||
|
<true/>
|
||||||
|
<key>OutgoingMailServerUsername</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>OutgoingPasswordSameAsIncomingPassword</key>
|
||||||
|
<true/>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Configures IMAP and SMTP for ${email}.</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>Mail</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.billenius.mobileconfig.${safeName}.mail</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.mail.managed</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${mailUuid}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CalDAVAccountDescription</key>
|
||||||
|
<string>${domain} Calendar</string>
|
||||||
|
<key>CalDAVHostName</key>
|
||||||
|
<string>${radicaleHost}</string>
|
||||||
|
<key>CalDAVPort</key>
|
||||||
|
<integer>443</integer>
|
||||||
|
<key>CalDAVUseSSL</key>
|
||||||
|
<true/>
|
||||||
|
<key>CalDAVUsername</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Configures CalDAV for ${email}.</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>Calendar</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.billenius.mobileconfig.${safeName}.caldav</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.caldav.account</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${caldavUuid}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CardDAVAccountDescription</key>
|
||||||
|
<string>${domain} Contacts</string>
|
||||||
|
<key>CardDAVHostName</key>
|
||||||
|
<string>${radicaleHost}</string>
|
||||||
|
<key>CardDAVPort</key>
|
||||||
|
<integer>443</integer>
|
||||||
|
<key>CardDAVUseSSL</key>
|
||||||
|
<true/>
|
||||||
|
<key>CardDAVUsername</key>
|
||||||
|
<string>${email}</string>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Configures CardDAV for ${email}.</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>Contacts</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.billenius.mobileconfig.${safeName}.carddav</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.carddav.account</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${carddavUuid}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Configures mail, calendar, and contacts for ${email}.</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>${domain} Mail</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.billenius.mobileconfig.${safeName}</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>${domain}</string>
|
||||||
|
<key>PayloadRemovalDisallowed</key>
|
||||||
|
<false/>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${profileUuid}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
'';
|
||||||
|
|
||||||
|
mobileconfigProfiles = lib.mapAttrs (
|
||||||
|
email: _: {
|
||||||
|
inherit email;
|
||||||
|
safeName = safeAccountName email;
|
||||||
|
profile = mkMobileconfig email;
|
||||||
|
}
|
||||||
|
) cfg.loginAccounts;
|
||||||
|
|
||||||
|
mobileconfigLandingPage = pkgs.writeText "mobileconfig-index.html" ''
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>${domain} Apple Profile</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>${domain} Apple Profile</h1>
|
||||||
|
<p>Open this page in Safari on iPhone, iPad, or macOS and enter your email address to download the configuration profile.</p>
|
||||||
|
<form method="get" action="/mobileconfig/">
|
||||||
|
<label for="emailaddress">Email address</label>
|
||||||
|
<input id="emailaddress" name="emailaddress" type="email" autocomplete="email" required>
|
||||||
|
<button type="submit">Download profile</button>
|
||||||
|
</form>
|
||||||
|
<p>The profile configures IMAP, SMTP, CalDAV, and CardDAV. You will still be asked for your password during installation.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'';
|
||||||
|
|
||||||
|
mobileconfigRedirectConfig =
|
||||||
|
lib.concatStrings (
|
||||||
|
lib.mapAttrsToList (
|
||||||
|
email: profile: ''
|
||||||
|
if ($arg_emailaddress = "${email}") {
|
||||||
|
return 302 /mobileconfig/${profile.safeName}.mobileconfig;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
) mobileconfigProfiles
|
||||||
|
);
|
||||||
|
|
||||||
|
mobileconfigLocations = lib.listToAttrs (
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name = "= /mobileconfig";
|
||||||
|
value.return = "308 /mobileconfig/";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "= /mobileconfig/";
|
||||||
|
value.extraConfig = ''
|
||||||
|
${mobileconfigRedirectConfig}
|
||||||
|
return 302 /mobileconfig/index.html;
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "= /mobileconfig/index.html";
|
||||||
|
value.extraConfig = ''
|
||||||
|
default_type text/html;
|
||||||
|
alias ${mobileconfigLandingPage};
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ lib.mapAttrsToList (
|
||||||
|
_: profile: {
|
||||||
|
name = "= /mobileconfig/${profile.safeName}.mobileconfig";
|
||||||
|
value.extraConfig = ''
|
||||||
|
default_type application/x-apple-aspen-config;
|
||||||
|
add_header Content-Disposition 'attachment; filename="${profile.safeName}.mobileconfig"' always;
|
||||||
|
alias ${profile.profile};
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
) mobileconfigProfiles
|
||||||
|
);
|
||||||
|
|
||||||
|
defaultMobileconfigLocation =
|
||||||
|
let
|
||||||
|
accounts = lib.attrNames mobileconfigProfiles;
|
||||||
|
in
|
||||||
|
if lib.length accounts == 1 then
|
||||||
|
let
|
||||||
|
profile = mobileconfigProfiles.${builtins.head accounts};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"= /mobileconfig/billenius.mobileconfig".extraConfig = ''
|
||||||
|
default_type application/x-apple-aspen-config;
|
||||||
|
add_header Content-Disposition 'attachment; filename="billenius.mobileconfig"' always;
|
||||||
|
alias ${profile.profile};
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.nginx.virtualHosts.${mobileconfigHost}.locations = mobileconfigLocations // defaultMobileconfigLocation;
|
||||||
|
}
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user