mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-22 13:05:36 +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
|
"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:
|
Response:
|
||||||
|
|
||||||
200 OK
|
200 OK
|
||||||
|
@ -1948,6 +1978,29 @@ Check if host name is blocked by SB/PC service:
|
||||||
sha256(sub.host.com)[0..1] -> hashes[2],...
|
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
|
## ipset
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,8 @@
|
||||||
"blocking_ipv6": "Blocking IPv6",
|
"blocking_ipv6": "Blocking IPv6",
|
||||||
"dns_over_https": "DNS-over-HTTPS",
|
"dns_over_https": "DNS-over-HTTPS",
|
||||||
"dns_over_tls": "DNS-over-TLS",
|
"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",
|
"plain_dns": "Plain DNS",
|
||||||
"form_enter_rate_limit": "Enter rate limit",
|
"form_enter_rate_limit": "Enter rate limit",
|
||||||
"rate_limit": "Rate limit",
|
"rate_limit": "Rate limit",
|
||||||
|
@ -415,7 +417,8 @@
|
||||||
"dns_privacy": "DNS Privacy",
|
"dns_privacy": "DNS Privacy",
|
||||||
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> Use <1>{{address}}</1> string.",
|
"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_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_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_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.",
|
"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 React, { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 Tabs from './Tabs';
|
||||||
import Icons from './Icons';
|
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 = [{
|
const dnsPrivacyList = [{
|
||||||
title: 'Android',
|
title: 'Android',
|
||||||
list: [
|
list: [
|
||||||
|
@ -36,6 +69,23 @@ const dnsPrivacyList = [{
|
||||||
{
|
{
|
||||||
title: 'iOS',
|
title: 'iOS',
|
||||||
list: [
|
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',
|
label: 'setup_dns_privacy_ios_1',
|
||||||
components: [
|
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>
|
<strong><Trans>{title}</Trans></strong>
|
||||||
<ul>{list.map(({ label, components }) => <li key={label}>
|
<ul>{list.map(
|
||||||
<Trans
|
({
|
||||||
components={components?.map((props) => {
|
label,
|
||||||
if (React.isValidElement(props)) {
|
components,
|
||||||
return props;
|
renderComponent = renderLi,
|
||||||
}
|
}) => renderComponent({ label, components }),
|
||||||
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>
|
</ul>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
@ -195,8 +224,8 @@ const getTabs = ({
|
||||||
},
|
},
|
||||||
dns_privacy: {
|
dns_privacy: {
|
||||||
title: 'dns_privacy',
|
title: 'dns_privacy',
|
||||||
// eslint-disable-next-line react/display-name
|
getTitle: function Title() {
|
||||||
getTitle: () => <div label="dns_privacy" title={t('dns_privacy')}>
|
return <div label="dns_privacy" title={t('dns_privacy')}>
|
||||||
<div className="tab__text">
|
<div className="tab__text">
|
||||||
{tlsAddress?.length > 0 && (
|
{tlsAddress?.length > 0 && (
|
||||||
<div className="tab__paragraph">
|
<div className="tab__paragraph">
|
||||||
|
@ -251,14 +280,15 @@ const getTabs = ({
|
||||||
{dnsPrivacyList.map(renderDnsPrivacyList)}
|
{dnsPrivacyList.map(renderDnsPrivacyList)}
|
||||||
</>}
|
</>}
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderContent = ({ title, list, getTitle }, t) => <div key={title} label={t(title)}>
|
const renderContent = ({ title, list, getTitle }) => <div key={title} label={i18next.t(title)}>
|
||||||
<div className="tab__title">{t(title)}</div>
|
<div className="tab__title">{i18next.t(title)}</div>
|
||||||
<div className="tab__text">
|
<div className="tab__text">
|
||||||
{typeof getTitle === 'function' && getTitle()}
|
{getTitle?.()}
|
||||||
{list
|
{list
|
||||||
&& <ol>{list.map((item) => <li key={item}>
|
&& <ol>{list.map((item) => <li key={item}>
|
||||||
<Trans>{item}</Trans>
|
<Trans>{item}</Trans>
|
||||||
|
@ -267,9 +297,10 @@ const renderContent = ({ title, list, getTitle }, t) => <div key={title} label={
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
const Guide = ({ dnsAddresses, t }) => {
|
const Guide = ({ dnsAddresses }) => {
|
||||||
const tlsAddress = (dnsAddresses && dnsAddresses.filter((item) => item.includes('tls://'))) || '';
|
const { t } = useTranslation();
|
||||||
const httpsAddress = (dnsAddresses && dnsAddresses.filter((item) => item.includes('https://'))) || '';
|
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 showDnsPrivacyNotice = httpsAddress.length < 1 && tlsAddress.length < 1;
|
||||||
|
|
||||||
const [activeTabLabel, setActiveTabLabel] = useState('Router');
|
const [activeTabLabel, setActiveTabLabel] = useState('Router');
|
||||||
|
@ -281,7 +312,7 @@ const Guide = ({ dnsAddresses, t }) => {
|
||||||
t,
|
t,
|
||||||
});
|
});
|
||||||
|
|
||||||
const activeTab = renderContent(tabs[activeTabLabel], t);
|
const activeTab = renderContent(tabs[activeTabLabel]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -298,12 +329,12 @@ Guide.defaultProps = {
|
||||||
|
|
||||||
Guide.propTypes = {
|
Guide.propTypes = {
|
||||||
dnsAddresses: PropTypes.array,
|
dnsAddresses: PropTypes.array,
|
||||||
t: PropTypes.func.isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
renderDnsPrivacyList.propTypes = {
|
renderDnsPrivacyList.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
list: PropTypes.array.isRequired,
|
list: PropTypes.array.isRequired,
|
||||||
|
renderList: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
renderContent.propTypes = {
|
renderContent.propTypes = {
|
||||||
|
@ -312,4 +343,11 @@ renderContent.propTypes = {
|
||||||
getTitle: PropTypes.func,
|
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/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
|
||||||
github.com/miekg/dns v1.1.31
|
github.com/miekg/dns v1.1.31
|
||||||
github.com/pkg/errors v0.9.1
|
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/sirupsen/logrus v1.6.0 // indirect
|
||||||
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c
|
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.5.1
|
||||||
|
@ -31,4 +32,5 @@ require (
|
||||||
google.golang.org/protobuf v1.25.0 // indirect
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
gopkg.in/yaml.v2 v2.3.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 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
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/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/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 h1:0JVooMPsT7A7HqEYdydp/OfjSOYSjhXV7w1hkKj/NPQ=
|
||||||
github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
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-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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
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)
|
httpRegister(http.MethodGet, "/control/i18n/current_language", handleI18nCurrentLanguage)
|
||||||
http.HandleFunc("/control/version.json", postInstall(optionalAuth(handleGetVersionJSON)))
|
http.HandleFunc("/control/version.json", postInstall(optionalAuth(handleGetVersionJSON)))
|
||||||
httpRegister(http.MethodPost, "/control/update", handleUpdate)
|
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()
|
RegisterAuthHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
69
home/dns.go
69
home/dns.go
|
@ -197,6 +197,44 @@ func generateServerConfig() dnsforward.ServerConfig {
|
||||||
return newconfig
|
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
|
// Get the list of DNS addresses the server is listening on
|
||||||
func getDNSAddresses() []string {
|
func getDNSAddresses() []string {
|
||||||
dnsAddresses := []string{}
|
dnsAddresses := []string{}
|
||||||
|
@ -217,28 +255,15 @@ func getDNSAddresses() []string {
|
||||||
addDNSAddress(&dnsAddresses, config.DNS.BindHost)
|
addDNSAddress(&dnsAddresses, config.DNS.BindHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConf := tlsConfigSettings{}
|
dnsEncryption := getDNSEncryption()
|
||||||
Context.tls.WriteDiskConfig(&tlsConf)
|
if dnsEncryption.https != "" {
|
||||||
if tlsConf.Enabled && len(tlsConf.ServerName) != 0 {
|
dnsAddresses = append(dnsAddresses, dnsEncryption.https)
|
||||||
|
}
|
||||||
if tlsConf.PortHTTPS != 0 {
|
if dnsEncryption.tls != "" {
|
||||||
addr := tlsConf.ServerName
|
dnsAddresses = append(dnsAddresses, dnsEncryption.tls)
|
||||||
if tlsConf.PortHTTPS != 443 {
|
}
|
||||||
addr = fmt.Sprintf("%s:%d", addr, tlsConf.PortHTTPS)
|
if dnsEncryption.quic != "" {
|
||||||
}
|
dnsAddresses = append(dnsAddresses, dnsEncryption.quic)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dnsAddresses
|
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
|
description: AdGuard Home statistics
|
||||||
- name: tls
|
- name: tls
|
||||||
description: AdGuard Home HTTPS/DOH/DOT settings
|
description: AdGuard Home HTTPS/DOH/DOT settings
|
||||||
|
- name: mobileconfig
|
||||||
|
description: Apple .mobileconfig
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/status:
|
/status:
|
||||||
|
@ -915,6 +917,27 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/ProfileInfo"
|
$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:
|
components:
|
||||||
requestBodies:
|
requestBodies:
|
||||||
|
|
Loading…
Reference in a new issue