mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-25 06:25:44 +03:00
+ client, home: 2110 Generate .mobileconfig
Close #2110 Squashed commit of the following: commit 3a652a23b21b4eb16dd7b09f149099c93bf7a977 Merge: 5d0d6c5e65acfb75
Author: Andrey Meshkov <am@adguard.com> Date: Wed Oct 7 21:01:54 2020 +0300 Merge branch 'master' into feature/2110 commit 5d0d6c5e8704c80ae526d92966dfee0c469019bb Author: Andrey Meshkov <am@adguard.com> Date: Wed Oct 7 00:28:25 2020 +0300 * (home): minor refactoring commit e1d10252f5b00c94edb9faa85eaefa3d33ac9cbf Merge: f859ef14fb7ca942
Author: Andrey Meshkov <am@adguard.com> Date: Wed Oct 7 00:18:46 2020 +0300 Merge branch 'master' into feature/2110 commit f859ef144c54123d8ff262177148959f7b41a5a4 Author: ArtemBaskal <a.baskal@adguard.com> Date: Tue Oct 6 19:30:18 2020 +0300 Update ServerURL, generate all uniqie uuid commit 3ce7c573229f87579ff150f6519077ced9c5ba23 Merge: e80cf6dea7d2dd7b
Author: ArtemBaskal <a.baskal@adguard.com> Date: Fri Oct 2 18:46:03 2020 +0300 Merge branch 'master' into feature/2110 commit e80cf6ded1c20a4384cb94200134d67b29c0c948 Author: ArtemBaskal <a.baskal@adguard.com> Date: Fri Oct 2 18:33:12 2020 +0300 Describe .mobileconfig in openapi, allow unauthorized access for .mobileconfig commit 9887d1839f8f7e4888fc23bb64cfc43a42b6f58b Author: ArtemBaskal <a.baskal@adguard.com> Date: Fri Oct 2 16:14:45 2020 +0300 Change .mobileconfig generation commit 5298dd706c107f5b02f4278a8773f6af387c36b1 Merge: cd4d1a74128229ad
Author: ArtemBaskal <a.baskal@adguard.com> Date: Fri Oct 2 12:01:16 2020 +0300 Merge branch 'master' into feature/2110 commit cd4d1a748e2471890b31533e4c24272a3d01cbee Author: ArtemBaskal <a.baskal@adguard.com> Date: Thu Oct 1 23:10:14 2020 +0300 Change dot and doh highlight in setup_dns_privacy_4 locale commit 50e310ef3b988f2aad5accea92c6b34ecef28585 Merge: 92e0e28b2f6f65a8
Author: ArtemBaskal <a.baskal@adguard.com> Date: Thu Oct 1 23:05:45 2020 +0300 Merge branch 'master' into feature/2110 commit 92e0e28b757953efbbc211ae43b710b070308573 Author: ArtemBaskal <a.baskal@adguard.com> Date: Mon Sep 28 16:44:25 2020 +0300 Add ServerAddresses property commit c8c4cf88abcb0a76c6024d41d3eafab691ff1e38 Author: ArtemBaskal <a.baskal@adguard.com> Date: Mon Sep 28 13:51:53 2020 +0300 Fix .mobileconfig display on SetupGuide commit 9e4fad3c0ed0bfb980ad1cb030272781c13ebaad Author: ArtemBaskal <a.baskal@adguard.com> Date: Fri Sep 25 19:08:50 2020 +0300 2110 + client, home: Generate .mobileconfig
This commit is contained in:
parent
65acfb75dd
commit
398da7e2d3
9 changed files with 310 additions and 67 deletions
|
@ -830,6 +830,36 @@ Request:
|
|||
"private_key_path":"..." // if set, private_key must be empty
|
||||
}
|
||||
|
||||
Response:
|
||||
|
||||
200 OK
|
||||
|
||||
### API: Validate TLS configuration
|
||||
|
||||
Request:
|
||||
|
||||
POST /control/tls/validate
|
||||
|
||||
{
|
||||
"enabled":true,
|
||||
"port_https":443,
|
||||
"port_dns_over_tls":853,
|
||||
"port_dns_over_quic":784,
|
||||
"allow_unencrypted_doh":false,
|
||||
"certificate_chain":"...",
|
||||
"private_key":"...",
|
||||
"certificate_path":"...",
|
||||
"private_key_path":"...",
|
||||
"valid_cert":true,
|
||||
"valid_chain":false,
|
||||
"not_before":"2019-03-19T08:23:45Z",
|
||||
"not_after":"2029-03-16T08:23:45Z",
|
||||
"dns_names":null,
|
||||
"valid_key":true,
|
||||
"valid_pair":true
|
||||
}
|
||||
|
||||
|
||||
Response:
|
||||
|
||||
200 OK
|
||||
|
@ -1948,6 +1978,29 @@ Check if host name is blocked by SB/PC service:
|
|||
sha256(sub.host.com)[0..1] -> hashes[2],...
|
||||
...
|
||||
|
||||
## API: Get DNS over HTTPS .mobileconfig
|
||||
|
||||
Request:
|
||||
|
||||
GET /apple/doh.mobileconfig
|
||||
|
||||
Response:
|
||||
|
||||
200 OK
|
||||
|
||||
DOH plist file
|
||||
|
||||
## API: Get DNS over TLS .mobileconfig
|
||||
|
||||
Request:
|
||||
|
||||
GET /apple/dot.mobileconfig
|
||||
|
||||
Response:
|
||||
|
||||
200 OK
|
||||
|
||||
DOT plist file
|
||||
|
||||
## ipset
|
||||
|
||||
|
|
|
@ -249,6 +249,8 @@
|
|||
"blocking_ipv6": "Blocking IPv6",
|
||||
"dns_over_https": "DNS-over-HTTPS",
|
||||
"dns_over_tls": "DNS-over-TLS",
|
||||
"download_mobileconfig_doh": "Download .mobileconfig for DNS-over-HTTPS",
|
||||
"download_mobileconfig_dot": "Download .mobileconfig for DNS-over-TLS",
|
||||
"plain_dns": "Plain DNS",
|
||||
"form_enter_rate_limit": "Enter rate limit",
|
||||
"rate_limit": "Rate limit",
|
||||
|
@ -415,7 +417,8 @@
|
|||
"dns_privacy": "DNS Privacy",
|
||||
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> Use <1>{{address}}</1> string.",
|
||||
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> Use <1>{{address}}</1> string.",
|
||||
"setup_dns_privacy_3": "<0>Please note that encrypted DNS protocols are supported only on Android 9. So you need to install additional software for other operating systems.</0><0>Here's a list of software you can use.</0>",
|
||||
"setup_dns_privacy_3": "<0>Here's a list of software you can use.</0>",
|
||||
"setup_dns_privacy_4": "On an iOS 14 or MacOS Big Sur device you can download special '.mobileconfig' file that adds <highlight>DNS-over-HTTPS</highlight> or <highlight>DNS-over-TLS</highlight> servers to the DNS settings.",
|
||||
"setup_dns_privacy_android_1": "Android 9 supports DNS-over-TLS natively. To configure it, go to Settings → Network & internet → Advanced → Private DNS and enter your domain name there.",
|
||||
"setup_dns_privacy_android_2": "<0>AdGuard for Android</0> supports <1>DNS-over-HTTPS</1> and <1>DNS-over-TLS</1>.",
|
||||
"setup_dns_privacy_android_3": "<0>Intra</0> adds <1>DNS-over-HTTPS</1> support to Android.",
|
||||
|
|
|
@ -1,10 +1,43 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import i18next from 'i18next';
|
||||
import Tabs from './Tabs';
|
||||
import Icons from './Icons';
|
||||
|
||||
const MOBILE_CONFIG_LINKS = {
|
||||
DOT: '/apple/dot.mobileconfig',
|
||||
DOH: '/apple/doh.mobileconfig',
|
||||
};
|
||||
|
||||
const renderMobileconfigInfo = ({ label, components }) => <li key={label}>
|
||||
<Trans components={components}>{label}</Trans>
|
||||
<ul>
|
||||
<li>
|
||||
<a href={MOBILE_CONFIG_LINKS.DOT} download>{i18next.t('download_mobileconfig_dot')}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={MOBILE_CONFIG_LINKS.DOH} download>{i18next.t('download_mobileconfig_doh')}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>;
|
||||
|
||||
const renderLi = ({ label, components }) => <li key={label}>
|
||||
<Trans components={components?.map((props) => {
|
||||
if (React.isValidElement(props)) {
|
||||
return props;
|
||||
}
|
||||
const {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
href, target = '_blank', rel = 'noopener noreferrer', key = '0',
|
||||
} = props;
|
||||
|
||||
return <a href={href} target={target} rel={rel} key={key}>link</a>;
|
||||
})}>
|
||||
{label}
|
||||
</Trans>
|
||||
</li>;
|
||||
|
||||
const dnsPrivacyList = [{
|
||||
title: 'Android',
|
||||
list: [
|
||||
|
@ -36,6 +69,23 @@ const dnsPrivacyList = [{
|
|||
{
|
||||
title: 'iOS',
|
||||
list: [
|
||||
{
|
||||
label: 'setup_dns_privacy_ios_2',
|
||||
components: [
|
||||
{
|
||||
key: 0,
|
||||
href: 'https://adguard.com/adguard-ios/overview.html',
|
||||
},
|
||||
<code key="1">text</code>,
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'setup_dns_privacy_4',
|
||||
components: {
|
||||
highlight: <code />,
|
||||
},
|
||||
renderComponent: renderMobileconfigInfo,
|
||||
},
|
||||
{
|
||||
label: 'setup_dns_privacy_ios_1',
|
||||
components: [
|
||||
|
@ -51,16 +101,6 @@ const dnsPrivacyList = [{
|
|||
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'setup_dns_privacy_ios_2',
|
||||
components: [
|
||||
{
|
||||
key: 0,
|
||||
href: 'https://adguard.com/adguard-ios/overview.html',
|
||||
},
|
||||
<code key="1">text</code>,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -116,26 +156,15 @@ const dnsPrivacyList = [{
|
|||
},
|
||||
];
|
||||
|
||||
const renderDnsPrivacyList = ({ title, list }) => <div className="tab__paragraph">
|
||||
const renderDnsPrivacyList = ({ title, list }) => <div className="tab__paragraph" key={title}>
|
||||
<strong><Trans>{title}</Trans></strong>
|
||||
<ul>{list.map(({ label, components }) => <li key={label}>
|
||||
<Trans
|
||||
components={components?.map((props) => {
|
||||
if (React.isValidElement(props)) {
|
||||
return props;
|
||||
}
|
||||
const {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
href, target = '_blank', rel = 'noopener noreferrer', key = '0',
|
||||
} = props;
|
||||
|
||||
return <a
|
||||
href={href} target={target}
|
||||
rel={rel} key={key}>link</a>;
|
||||
})}>
|
||||
{label}
|
||||
</Trans>
|
||||
</li>)}
|
||||
<ul>{list.map(
|
||||
({
|
||||
label,
|
||||
components,
|
||||
renderComponent = renderLi,
|
||||
}) => renderComponent({ label, components }),
|
||||
)}
|
||||
</ul>
|
||||
</div>;
|
||||
|
||||
|
@ -195,8 +224,8 @@ const getTabs = ({
|
|||
},
|
||||
dns_privacy: {
|
||||
title: 'dns_privacy',
|
||||
// eslint-disable-next-line react/display-name
|
||||
getTitle: () => <div label="dns_privacy" title={t('dns_privacy')}>
|
||||
getTitle: function Title() {
|
||||
return <div label="dns_privacy" title={t('dns_privacy')}>
|
||||
<div className="tab__text">
|
||||
{tlsAddress?.length > 0 && (
|
||||
<div className="tab__paragraph">
|
||||
|
@ -251,14 +280,15 @@ const getTabs = ({
|
|||
{dnsPrivacyList.map(renderDnsPrivacyList)}
|
||||
</>}
|
||||
</div>
|
||||
</div>,
|
||||
</div>;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const renderContent = ({ title, list, getTitle }, t) => <div key={title} label={t(title)}>
|
||||
<div className="tab__title">{t(title)}</div>
|
||||
const renderContent = ({ title, list, getTitle }) => <div key={title} label={i18next.t(title)}>
|
||||
<div className="tab__title">{i18next.t(title)}</div>
|
||||
<div className="tab__text">
|
||||
{typeof getTitle === 'function' && getTitle()}
|
||||
{getTitle?.()}
|
||||
{list
|
||||
&& <ol>{list.map((item) => <li key={item}>
|
||||
<Trans>{item}</Trans>
|
||||
|
@ -267,9 +297,10 @@ const renderContent = ({ title, list, getTitle }, t) => <div key={title} label={
|
|||
</div>
|
||||
</div>;
|
||||
|
||||
const Guide = ({ dnsAddresses, t }) => {
|
||||
const tlsAddress = (dnsAddresses && dnsAddresses.filter((item) => item.includes('tls://'))) || '';
|
||||
const httpsAddress = (dnsAddresses && dnsAddresses.filter((item) => item.includes('https://'))) || '';
|
||||
const Guide = ({ dnsAddresses }) => {
|
||||
const { t } = useTranslation();
|
||||
const tlsAddress = dnsAddresses?.filter((item) => item.includes('tls://')) ?? '';
|
||||
const httpsAddress = dnsAddresses?.filter((item) => item.includes('https://')) ?? '';
|
||||
const showDnsPrivacyNotice = httpsAddress.length < 1 && tlsAddress.length < 1;
|
||||
|
||||
const [activeTabLabel, setActiveTabLabel] = useState('Router');
|
||||
|
@ -281,7 +312,7 @@ const Guide = ({ dnsAddresses, t }) => {
|
|||
t,
|
||||
});
|
||||
|
||||
const activeTab = renderContent(tabs[activeTabLabel], t);
|
||||
const activeTab = renderContent(tabs[activeTabLabel]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -298,12 +329,12 @@ Guide.defaultProps = {
|
|||
|
||||
Guide.propTypes = {
|
||||
dnsAddresses: PropTypes.array,
|
||||
t: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
renderDnsPrivacyList.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
list: PropTypes.array.isRequired,
|
||||
renderList: PropTypes.func,
|
||||
};
|
||||
|
||||
renderContent.propTypes = {
|
||||
|
@ -312,4 +343,11 @@ renderContent.propTypes = {
|
|||
getTitle: PropTypes.func,
|
||||
};
|
||||
|
||||
export default withTranslation()(Guide);
|
||||
renderLi.propTypes = {
|
||||
label: PropTypes.string,
|
||||
components: PropTypes.string,
|
||||
};
|
||||
|
||||
renderMobileconfigInfo.propTypes = renderLi.propTypes;
|
||||
|
||||
export default Guide;
|
||||
|
|
2
go.mod
2
go.mod
|
@ -19,6 +19,7 @@ require (
|
|||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
|
||||
github.com/miekg/dns v1.1.31
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c
|
||||
github.com/stretchr/testify v1.5.1
|
||||
|
@ -31,4 +32,5 @@ require (
|
|||
google.golang.org/protobuf v1.25.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -210,6 +210,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v2.20.3+incompatible h1:0JVooMPsT7A7HqEYdydp/OfjSOYSjhXV7w1hkKj/NPQ=
|
||||
github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
|
@ -430,6 +432,8 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5 h1:AQkaJpH+/FmqRjmXZPELom5zIERYZfwTjnHpfoVMQEc=
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
|
|
|
@ -97,8 +97,11 @@ func registerControlHandlers() {
|
|||
httpRegister(http.MethodGet, "/control/i18n/current_language", handleI18nCurrentLanguage)
|
||||
http.HandleFunc("/control/version.json", postInstall(optionalAuth(handleGetVersionJSON)))
|
||||
httpRegister(http.MethodPost, "/control/update", handleUpdate)
|
||||
httpRegister(http.MethodGet, "/control/profile", handleGetProfile)
|
||||
|
||||
httpRegister("GET", "/control/profile", handleGetProfile)
|
||||
// No auth is necessary for DOH/DOT configurations
|
||||
http.HandleFunc("/apple/doh.mobileconfig", postInstall(handleMobileConfigDoh))
|
||||
http.HandleFunc("/apple/dot.mobileconfig", postInstall(handleMobileConfigDot))
|
||||
RegisterAuthHandlers()
|
||||
}
|
||||
|
||||
|
|
65
home/dns.go
65
home/dns.go
|
@ -197,6 +197,44 @@ func generateServerConfig() dnsforward.ServerConfig {
|
|||
return newconfig
|
||||
}
|
||||
|
||||
type DNSEncryption struct {
|
||||
https string
|
||||
tls string
|
||||
quic string
|
||||
}
|
||||
|
||||
func getDNSEncryption() DNSEncryption {
|
||||
dnsEncryption := DNSEncryption{}
|
||||
|
||||
tlsConf := tlsConfigSettings{}
|
||||
|
||||
Context.tls.WriteDiskConfig(&tlsConf)
|
||||
|
||||
if tlsConf.Enabled && len(tlsConf.ServerName) != 0 {
|
||||
|
||||
if tlsConf.PortHTTPS != 0 {
|
||||
addr := tlsConf.ServerName
|
||||
if tlsConf.PortHTTPS != 443 {
|
||||
addr = fmt.Sprintf("%s:%d", addr, tlsConf.PortHTTPS)
|
||||
}
|
||||
addr = fmt.Sprintf("https://%s/dns-query", addr)
|
||||
dnsEncryption.https = addr
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverTLS != 0 {
|
||||
addr := fmt.Sprintf("tls://%s:%d", tlsConf.ServerName, tlsConf.PortDNSOverTLS)
|
||||
dnsEncryption.tls = addr
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverQUIC != 0 {
|
||||
addr := fmt.Sprintf("quic://%s:%d", tlsConf.ServerName, tlsConf.PortDNSOverQUIC)
|
||||
dnsEncryption.quic = addr
|
||||
}
|
||||
}
|
||||
|
||||
return dnsEncryption
|
||||
}
|
||||
|
||||
// Get the list of DNS addresses the server is listening on
|
||||
func getDNSAddresses() []string {
|
||||
dnsAddresses := []string{}
|
||||
|
@ -217,28 +255,15 @@ func getDNSAddresses() []string {
|
|||
addDNSAddress(&dnsAddresses, config.DNS.BindHost)
|
||||
}
|
||||
|
||||
tlsConf := tlsConfigSettings{}
|
||||
Context.tls.WriteDiskConfig(&tlsConf)
|
||||
if tlsConf.Enabled && len(tlsConf.ServerName) != 0 {
|
||||
|
||||
if tlsConf.PortHTTPS != 0 {
|
||||
addr := tlsConf.ServerName
|
||||
if tlsConf.PortHTTPS != 443 {
|
||||
addr = fmt.Sprintf("%s:%d", addr, tlsConf.PortHTTPS)
|
||||
dnsEncryption := getDNSEncryption()
|
||||
if dnsEncryption.https != "" {
|
||||
dnsAddresses = append(dnsAddresses, dnsEncryption.https)
|
||||
}
|
||||
addr = fmt.Sprintf("https://%s/dns-query", addr)
|
||||
dnsAddresses = append(dnsAddresses, addr)
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverTLS != 0 {
|
||||
addr := fmt.Sprintf("tls://%s:%d", tlsConf.ServerName, tlsConf.PortDNSOverTLS)
|
||||
dnsAddresses = append(dnsAddresses, addr)
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverQUIC != 0 {
|
||||
addr := fmt.Sprintf("quic://%s:%d", tlsConf.ServerName, tlsConf.PortDNSOverQUIC)
|
||||
dnsAddresses = append(dnsAddresses, addr)
|
||||
if dnsEncryption.tls != "" {
|
||||
dnsAddresses = append(dnsAddresses, dnsEncryption.tls)
|
||||
}
|
||||
if dnsEncryption.quic != "" {
|
||||
dnsAddresses = append(dnsAddresses, dnsEncryption.quic)
|
||||
}
|
||||
|
||||
return dnsAddresses
|
||||
|
|
92
home/mobileconfig.go
Normal file
92
home/mobileconfig.go
Normal file
|
@ -0,0 +1,92 @@
|
|||
package home
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"howett.net/plist"
|
||||
)
|
||||
|
||||
type DNSSettings struct {
|
||||
DNSProtocol string
|
||||
ServerURL string `plist:",omitempty"`
|
||||
ServerName string `plist:",omitempty"`
|
||||
}
|
||||
|
||||
type PayloadContent = struct {
|
||||
Name string
|
||||
PayloadDescription string
|
||||
PayloadDisplayName string
|
||||
PayloadIdentifier string
|
||||
PayloadType string
|
||||
PayloadUUID string
|
||||
PayloadVersion int
|
||||
DNSSettings DNSSettings
|
||||
}
|
||||
|
||||
type MobileConfig = struct {
|
||||
PayloadContent []PayloadContent
|
||||
PayloadDescription string
|
||||
PayloadDisplayName string
|
||||
PayloadIdentifier string
|
||||
PayloadRemovalDisallowed bool
|
||||
PayloadType string
|
||||
PayloadUUID string
|
||||
PayloadVersion int
|
||||
}
|
||||
|
||||
func genUUIDv4() string {
|
||||
return uuid.NewV4().String()
|
||||
}
|
||||
|
||||
func getMobileConfig(r *http.Request, d DNSSettings) ([]byte, error) {
|
||||
name := fmt.Sprintf("%s DNS over %s", r.Host, d.DNSProtocol)
|
||||
|
||||
data := MobileConfig{
|
||||
PayloadContent: []PayloadContent{{
|
||||
Name: name,
|
||||
PayloadDescription: "Configures device to use AdGuard Home",
|
||||
PayloadDisplayName: name,
|
||||
PayloadIdentifier: fmt.Sprintf("com.apple.dnsSettings.managed.%s", genUUIDv4()),
|
||||
PayloadType: "com.apple.dnsSettings.managed",
|
||||
PayloadUUID: genUUIDv4(),
|
||||
PayloadVersion: 1,
|
||||
DNSSettings: d,
|
||||
}},
|
||||
PayloadDescription: "Adds AdGuard Home to Big Sur and iOS 14 or newer systems",
|
||||
PayloadDisplayName: name,
|
||||
PayloadIdentifier: genUUIDv4(),
|
||||
PayloadRemovalDisallowed: false,
|
||||
PayloadType: "Configuration",
|
||||
PayloadUUID: genUUIDv4(),
|
||||
PayloadVersion: 1,
|
||||
}
|
||||
|
||||
return plist.MarshalIndent(data, plist.XMLFormat, "\t")
|
||||
}
|
||||
|
||||
func handleMobileConfig(w http.ResponseWriter, r *http.Request, d DNSSettings) {
|
||||
mobileconfig, err := getMobileConfig(r, d)
|
||||
|
||||
if err != nil {
|
||||
httpError(w, http.StatusInternalServerError, "plist.MarshalIndent: %s", err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/xml")
|
||||
_, _ = w.Write(mobileconfig)
|
||||
}
|
||||
|
||||
func handleMobileConfigDoh(w http.ResponseWriter, r *http.Request) {
|
||||
handleMobileConfig(w, r, DNSSettings{
|
||||
DNSProtocol: "HTTPS",
|
||||
ServerURL: fmt.Sprintf("https://%s/dns-query", r.Host),
|
||||
})
|
||||
}
|
||||
|
||||
func handleMobileConfigDot(w http.ResponseWriter, r *http.Request) {
|
||||
handleMobileConfig(w, r, DNSSettings{
|
||||
DNSProtocol: "TLS",
|
||||
ServerName: r.Host,
|
||||
})
|
||||
}
|
|
@ -35,6 +35,8 @@ tags:
|
|||
description: AdGuard Home statistics
|
||||
- name: tls
|
||||
description: AdGuard Home HTTPS/DOH/DOT settings
|
||||
- name: mobileconfig
|
||||
description: Apple .mobileconfig
|
||||
|
||||
paths:
|
||||
/status:
|
||||
|
@ -915,6 +917,27 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ProfileInfo"
|
||||
/apple/doh.mobileconfig:
|
||||
get:
|
||||
tags:
|
||||
- mobileconfig
|
||||
- global
|
||||
operationId: mobileConfigDoH
|
||||
summary: Get DNS over HTTPS .mobileconfig
|
||||
responses:
|
||||
"200":
|
||||
description: DNS over HTTPS plist file
|
||||
|
||||
/apple/dot.mobileconfig:
|
||||
get:
|
||||
tags:
|
||||
- mobileconfig
|
||||
- global
|
||||
operationId: mobileConfigDoT
|
||||
summary: Get TLS over TLS .mobileconfig
|
||||
responses:
|
||||
"200":
|
||||
description: DNS over TLS plist file
|
||||
|
||||
components:
|
||||
requestBodies:
|
||||
|
|
Loading…
Reference in a new issue