rework to allow multiple dns profiles in one config

This commit is contained in:
fyr77 2021-03-03 19:02:39 +01:00
parent d6a9ed4106
commit 81579961d7
7 changed files with 475 additions and 222 deletions

36
finalize.html Normal file
View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DNS Profile Creator</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/w3.css">
<link rel="stylesheet" href="css/dark-mode.css">
<script src="js/FileSaver.min.js"></script>
<script src="js/uuidv4.min.js"></script>
<script src="js/finalize.js"></script>
</head>
<body class="w3-container">
<h1>Secure DNS profile creator</h1>
<h2>For iOS 14 or later and macOS Big Sur or later</h2>
<div class="w3-bar w3-border bar-color">
<a href="/" class="w3-bar-item w3-button w3-mobile">About</a>
<a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a>
<a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a>
<a href="/finalize.html" class="w3-bar-item w3-button w3-mobile w3-green">Finalize profile</a>
<a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a>
<a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a>
</div>
<br>
<div id="dynamicList"></div>
<br>
<div class="w3-bar">
<button class="w3-button w3-bar-item w3-mobile w3-green" style="width:80%" onclick="saveDynamicDataToFile()">Download Profile</button>
<button class="w3-button w3-bar-item w3-mobile w3-dark-gray" style="width:20%" onclick="confirmDel()">Delete All</button>
</div>
</body>
</html>

View file

@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -7,48 +8,71 @@
<link rel="stylesheet" href="css/w3.css"> <link rel="stylesheet" href="css/w3.css">
<link rel="stylesheet" href="css/dark-mode.css"> <link rel="stylesheet" href="css/dark-mode.css">
</head> </head>
<body class="w3-container">
<body class="w3-container">
<div class="w3-container bar-color"> <div class="w3-container bar-color">
<p>This website uses technical cookies. By continuing you agree to the use of these cookies. No personal data is stored or shared. <a href="legal.html">Learn more</a></p> <p>This website uses technical cookies. By continuing you agree to the use of these cookies. No personal data is
</div> stored or shared. <a href="legal.html">Learn more</a></p>
</div>
<h1>Secure DNS profile creator</h1> <h1>Secure DNS profile creator</h1>
<h2>For iOS 14 or later and macOS Big Sur or later</h2> <h2>For iOS 14 or later and macOS Big Sur or later</h2>
<div class="w3-bar w3-border bar-color"> <div class="w3-bar w3-border bar-color">
<a href="/index.html" class="w3-bar-item w3-button w3-green w3-mobile">About</a> <a href="/" class="w3-bar-item w3-button w3-green w3-mobile">About</a>
<a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a> <a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a>
<a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a> <a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a>
<a href="/finalize.html" class="w3-bar-item w3-button w3-mobile">Finalize profile</a>
<a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a> <a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a>
<a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a> <a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a>
</div> </div>
<br> <br>
<h3>What is this?</h3> <h3>What is this?</h3>
<p>This website allows you to create configuration profiles for your Apple device to use the new built-in encrypted DNS options.</p> <p>This website allows you to create configuration profiles for your Apple device to use the new built-in encrypted
DNS options.</p>
<h3>Details</h3> <h3>Details</h3>
<p>Apple has included built-in support for DNS-over-HTTPS and DNS-over-TLS in their iOS 14 and macOS Big Sur updates. But there is no possibility to use this new feature without a third-party app or configuration profiles. I personally preferred not to install some app to manage this for me. <br> <p>Apple has included built-in support for DNS-over-HTTPS and DNS-over-TLS in their iOS 14 and macOS Big Sur
This websites generates a configuration profile which is installable on your system and activates encrypted DNS.</p> updates. But there is no possibility to use this new feature without a third-party app or configuration
profiles. I personally preferred not to install some app to manage this for me. <br>
This websites generates a configuration profile which is installable on your system and activates encrypted DNS.
</p>
<h4>Why not use an app?</h4> <h4>Why not use an app?</h4>
<p>I prefer to use tools which I can make sure do exactly what they claim to do. Configuration profiles are rather transparent, they can be opened with any text editor and viewed. This website is completely open-source. <br> <p>I prefer to use tools which I can make sure do exactly what they claim to do. Configuration profiles are rather
An app off the App Store might do what it should, sure. But it also might capture data inbetween and negate the privacy advantage that DoH and DoT bring.</p> transparent, they can be opened with any text editor and viewed. This website is completely open-source. <br>
An app off the App Store might do what it should, sure. But it also might capture data inbetween and negate the
privacy advantage that DoH and DoT bring.</p>
<h3>How do I use this?</h3> <h3>How do I use this?</h3>
<p>Visit this website using you Apple device and navigate to the tool. Then, select a pre-made configuration or enter your own settings and click/tap "Download profile". Then, open the downloaded file using the "Files" app. <br> <p>Visit this website using you Apple device and navigate to the tool. Then, select a pre-made configuration or
Your device will ask you a few times, be sure to accept the warnings.<br> enter your own settings and click/tap "Download profile". Then, open the downloaded file using the "Files" app.
<b>The generated profiles are not signed. This is normal.</b></p> <br>
Your device will ask you a few times, be sure to accept the warnings.<br>
<b>The generated profiles are not signed. This is normal.</b></p>
<h3>Why should I care about encrypted DNS?</h3> <h3>Why should I care about encrypted DNS?</h3>
<p>DNS is basically the phone book of the internet. If you visit a website, your computer first contacts the DNS server to look up where its even supposed to connect to.<br> <p>DNS is basically the phone book of the internet. If you visit a website, your computer first contacts the DNS
While the traffic itself is often encrypted nowadays, the lookup itself still is not without DoH/DoT. So anyone in the same network will still know exactly which websites you visited.<br> server to look up where its even supposed to connect to.<br>
If you want to know more about this, give <a href="https://paulmillr.com/posts/encrypted-dns/">this blog post by Paul Miller</a> a read, he explains the subject very nicely.</p> While the traffic itself is often encrypted nowadays, the lookup itself still is not without DoH/DoT. So anyone
in the same network will still know exactly which websites you visited.<br>
If you want to know more about this, give <a href="https://paulmillr.com/posts/encrypted-dns/">this blog post by
Paul Miller</a> a read, he explains the subject very nicely.</p>
<h3>DNS-over-HTTPS or DNS-over-TLS?</h3> <h3>DNS-over-HTTPS or DNS-over-TLS?</h3>
<p>There isn't a huge difference between the two protocols.<br> <p>There isn't a huge difference between the two protocols.<br>
DoH is harder to spot in regular network traffic and is also less likely to be blocked in a corporate environment, since it uses the same port as any secured website.<br> DoH is harder to spot in regular network traffic and is also less likely to be blocked in a corporate
DoT is possibly faster, since it uses one layer of transport less. But it uses it's own port and is therefore obvious to any other people monitoring the network - and might be blocked behind very strict firewalls.</p> environment, since it uses the same port as any secured website.<br>
<p>In the end, it's more personal preference than anything else. If your system supports both - as Apple systems do - you can choose whatever you want.</p> DoT is possibly faster, since it uses one layer of transport less. But it uses it's own port and is therefore
obvious to any other people monitoring the network - and might be blocked behind very strict firewalls.</p>
<p>In the end, it's more personal preference than anything else. If your system supports both - as Apple systems do
- you can choose whatever you want.</p>
<h3>Which provider should I choose?</h3> <h3>Which provider should I choose?</h3>
<p>This comes down to a few factors. First, location. Living in countries which block certain websites narrows your choice down considerably. Furthermore, different providers have different priorities. I suggest you do some research into the providers yourself. For example, you could take a look at <a href="https://www.privacytools.io/providers/dns/">this table</a> which lists a few providers and compares them.</p> <p>This comes down to a few factors. First, location. Living in countries which block certain websites narrows your
choice down considerably. Furthermore, different providers have different priorities. I suggest you do some
research into the providers yourself. For example, you could take a look at <a
href="https://www.privacytools.io/providers/dns/">this table</a> which lists a few providers and compares
them.</p>
<h3>Support</h3> <h3>Support</h3>
<p>This website does not use any ads or tracking. If you enjoy it and want to show some support, <a href="https://ko-fi.com/notjakob" target="_blank">buy me a coffee</a>. It's greatly appreciated!</p> <p>This website does not use any ads or tracking. If you enjoy it and want to show some support, <a
href="https://ko-fi.com/notjakob" target="_blank">buy me a coffee</a>. It's greatly appreciated!</p>
</body> </body>
</html> </html>

323
js/finalize.js Normal file
View file

@ -0,0 +1,323 @@
window.onload = function () {
deleteTempCookies();
buildList();
}
function deleteCard(cardNo) {
document.getElementById("card" + cardNo).remove();
document.cookie = cardNo + "provName=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "doh=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "dns1v4=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "dns2v4=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "dns1v6=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "dns2v6=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "serverUrl=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "exclWifi=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "useWifi=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "useCell=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = cardNo + "lockProfile=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
}
function buildList() {
console.log(document.cookie.split("; ")); //DEBUG!
var parent = document.getElementById("dynamicList");
for (var i = 0; i < getCookie("runningNo"); i++) {
if (getCookie(i + "provName") != "") {
var carddiv = document.createElement("div");
carddiv.classList.add("w3-card");
carddiv.id = "card" + i;
var header = document.createElement("header");
header.classList.add("w3-container");
header.classList.add("w3-light-gray");
var headertext = document.createElement("h3");
headertext.classList.add("w3-left");
headertext.appendChild(document.createTextNode(getCookie(i + "provName")));
var headerdel = document.createElement("button");
headerdel.classList.add("w3-button");
headerdel.classList.add("w3-red");
headerdel.classList.add("w3-right")
headerdel.innerHTML = "X";
headerdel.setAttribute("onclick", 'deleteCard(' + i + ')');
var infocontainer = document.createElement("div");
infocontainer.classList.add("w3-container");
var infop = document.createElement("p");
var infostring = "Connection type: ";
if (getCookie(i + "doh") == "true") {
infostring += "DNS-over-HTTPS";
} else {
infostring += "DNS-over-TLS";
}
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
var dns1v4 = getCookie(i + "dns1v4");
var dns2v4 = getCookie(i + "dns2v4");
var dns1v6 = getCookie(i + "dns1v6");
var dns2v6 = getCookie(i + "dns2v6");
var exclWifi = getCookie(i + "exclWifi");
if (dns1v4 != "") {
infostring = "Primary IPv4 DNS Server: " + getCookie(i + "dns1v4");
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
}
if (dns2v4 != "") {
infostring = "Secondary IPv4 DNS Server: " + dns2v4;
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
}
if (dns1v6 != "") {
infostring = "Primary IPv6 DNS Server: " + dns1v6;
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
}
if (dns2v6 != "") {
infostring = "Secondary IPv6 DNS Server: " + dns2v6;
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
}
infostring = "Server Address: " + getCookie(i + "serverUrl");
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
if (exclWifi != "") {
infostring = "Excluded WiFi SSIDs: " + exclWifi;
infop.appendChild(document.createTextNode(infostring));
infop.appendChild(document.createElement("br"));
}
infostring = "";
if (getCookie(i + "useWifi") == "true") {
infostring += "Enabled on WiFi. ";
}
if (getCookie(i + "useCell") == "true") {
infostring += "Enabled on Cellular. ";
}
if (getCookie(i + "lockProfile" == "true")) {
infostring += "Disablement prohibited. ";
}
infop.appendChild(document.createTextNode(infostring));
header.appendChild(headertext);
header.appendChild(headerdel);
carddiv.appendChild(header);
infocontainer.appendChild(infop);
carddiv.appendChild(infocontainer);
parent.appendChild(carddiv);
}
}
}
function deleteTempCookies() {
document.cookie = "provName=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "doh=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "dns1v4=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "dns2v4=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "dns1v6=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "dns2v6=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
document.cookie = "serverUrl=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function deleteAllCookies() {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
}
}
function getRegDNS(iterator) {
var dns1v4 = getCookie(iterator + "dns1v4");
var dns2v4 = getCookie(iterator + "dns2v4");
var dns1v6 = getCookie(iterator + "dns1v6");
var dns2v6 = getCookie(iterator + "dns2v6");
var ip4format = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
var ip6format = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
var returnstring = "<key>ServerAddresses</key>\n<array>\n";
var dnsOverride = false;
if (ip6format.test(dns1v6)) {
dnsOverride = true;
returnstring += "<string>" + dns1v6 + "</string>\n";
}
if (ip6format.test(dns2v6)) {
dnsOverride = true;
returnstring += "<string>" + dns2v6 + "</string>\n";
}
if (ip4format.test(dns1v4)) {
dnsOverride = true;
returnstring += "<string>" + dns1v4 + "</string>\n";
}
if (ip4format.test(dns2v4)) {
dnsOverride = true;
returnstring += "<string>" + dns2v4 + "</string>\n";
}
if (dnsOverride) {
returnstring += "</array>\n";
return returnstring;
} else {
return "";
}
}
function saveDynamicDataToFile() {
var fileString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
fileString += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
fileString += "<plist version=\"1.0\">\n";
fileString += "<dict>\n";
fileString += "<key>PayloadContent</key>\n";
fileString += "<array>\n";
//DNS settings start
for (var i = 0; i < getCookie("runningNo"); i++) {
var provName = getCookie(i + "provName");
if (provName != "") { //This check is to avoid empty configurations leftover by deletion.
var encValue = null;
if (getCookie(i + "doh") == "true") {
encValue = "HTTPS";
} else {
encValue = "TLS";
}
var exclWifi = getCookie(i + "")
fileString += "<dict>\n";
fileString += "<key>DNSSettings</key>\n";
fileString += "<dict>\n";
fileString += "<key>DNSProtocol</key>\n";
fileString += "<string>" + encValue + "</string>\n";
fileString += getRegDNS(i);
if (encValue == "HTTPS") {
fileString += "<key>ServerURL</key>\n";
} else {
fileString += "<key>ServerName</key>\n";
}
fileString += "<string>" + getCookie(i + "serverUrl") + "</string>\n";
fileString += "</dict>\n";
fileString += "<key>OnDemandRules</key>\n";
fileString += "<array>\n";
if (exclWifi != "") {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Disconnect</string>\n";
fileString += "<key>SSIDMatch</key>\n"
fileString += "<array>\n";
exclWifi.split(/\s*,\s*/).forEach(function (wifiString) {
fileString += "<string>" + wifiString + "</string>\n";
});
fileString += "</array>\n";
fileString += "</dict>\n";
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "</dict>\n";
}
if (getCookie(i + "useWifi") == "true") {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "<key>InterfaceTypeMatch</key>\n";
fileString += "<string>WiFi</string>\n";
fileString += "</dict>\n";
}
if (getCookie(i + "useCell") == "true") {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "<key>InterfaceTypeMatch</key>\n";
fileString += "<string>Cellular</string>\n";
fileString += "</dict>\n";
}
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Disconnect</string>\n";
fileString += "</dict>\n";
fileString += "</array>\n";
fileString += "<key>PayloadDescription</key>\n";
fileString += "<string>Configures device to use " + provName + " Encrypted DNS over " + encValue + "</string>\n";
fileString += "<key>PayloadDisplayName</key>\n";
fileString += "<string>" + provName + " DNS over " + encValue + "</string>\n";
fileString += "<key>PayloadIdentifier</key>\n";
fileString += "<string>com.apple.dnsSettings.managed." + uuidv4() + "</string>\n";
fileString += "<key>PayloadType</key>\n";
fileString += "<string>com.apple.dnsSettings.managed</string>\n";
fileString += "<key>PayloadUUID</key>\n";
fileString += "<string>" + uuidv4() + "</string>\n";
fileString += "<key>PayloadVersion</key>\n";
fileString += "<integer>1</integer>\n";
fileString += "<key>ProhibitDisablement</key>\n";
if (getCookie(i + "lockProfile") == "true") {
fileString += "<true/>\n";
} else {
fileString += "<false/>\n";
}
fileString += "</dict>\n";
fileString += "</array>\n";
}
}
//DNS settings end
fileString += "<key>PayloadDescription</key>\n";
fileString += "<string>Adds different encrypted DNS configurations to Big Sur and iOS 14 based systems</string>\n";
fileString += "<key>PayloadDisplayName</key>\n";
fileString += "<string>Encrypted DNS (DoH, DoT)</string>\n";
fileString += "<key>PayloadIdentifier</key>\n";
fileString += "<string>com.notjakob.apple-dns." + uuidv4() + "</string>\n";
fileString += "<key>PayloadRemovalDisallowed</key>\n";
fileString += "<false/>\n";
fileString += "<key>PayloadType</key>\n";
fileString += "<string>Configuration</string>\n";
fileString += "<key>PayloadUUID</key>\n";
fileString += "<string>" + uuidv4() + "</string>\n";
fileString += "<key>PayloadVersion</key>\n";
fileString += "<integer>1</integer>\n";
fileString += "</dict>\n";
fileString += "</plist>";
var blob = new Blob([fileString], {
type: "text/plain;charset=utf-8"
});
deleteAllCookies();
saveAs(blob, "dns.mobileconfig");
}
function confirmDel() {
if (confirm("This will delete all configurations on this page. Continue?") == true) {
deleteAllCookies();
window.location.reload();
}
}

View file

@ -1,195 +1,56 @@
function getCookie(cname) { function getCookie(cname) {
var name = cname + "="; var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie); var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';'); var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) { for (var i = 0; i < ca.length; i++) {
var c = ca[i]; var c = ca[i];
while (c.charAt(0) == ' ') { while (c.charAt(0) == ' ') {
c = c.substring(1); c = c.substring(1);
} }
if (c.indexOf(name) == 0) { if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length); return c.substring(name.length, c.length);
}
}
return "";
}
function deleteAllCookies() {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict; Secure";
}
}
function getRegDNS() {
var dns1v4 = document.getElementById("dns1v4").value;
var dns2v4 = document.getElementById("dns2v4").value;
var dns1v6 = document.getElementById("dns1v6").value;
var dns2v6 = document.getElementById("dns2v6").value;
var ip4format = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
var ip6format = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
var returnstring = "<key>ServerAddresses</key>\n<array>\n";
var dnsOverride = false;
if (ip6format.test(dns1v6)) {
dnsOverride = true;
returnstring += "<string>" + dns1v6 + "</string>\n";
}
if (ip6format.test(dns2v6)) {
dnsOverride = true;
returnstring += "<string>" + dns2v6 + "</string>\n";
}
if (ip4format.test(dns1v4)) {
dnsOverride = true;
returnstring += "<string>" + dns1v4 + "</string>\n";
}
if (ip4format.test(dns2v4)) {
dnsOverride = true;
returnstring += "<string>" + dns2v4 + "</string>\n";
}
if (dnsOverride) {
returnstring += "</array>\n";
return returnstring;
}
else {
return "";
}
}
function saveDynamicDataToFile() {
var encryption = document.getElementsByName('encryption');
var encValue = null;
var provName = document.getElementById("provName").value;
for (var i = 0, length = encryption.length; i < length; i++) {
if (encryption[i].checked) {
encValue = encryption[i].value;
// only one radio can be logically checked, don't check the rest
break;
} }
} }
var exclWifi = document.getElementById("exclWifi"); return "";
var fileString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
fileString += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
fileString += "<plist version=\"1.0\">\n";
fileString += "<dict>\n";
fileString += "<key>PayloadContent</key>\n";
fileString += "<array>\n";
fileString += "<dict>\n";
fileString += "<key>DNSSettings</key>\n";
fileString += "<dict>\n";
fileString += "<key>DNSProtocol</key>\n";
fileString += "<string>" + encValue + "</string>\n";
fileString += getRegDNS();
if (encValue == "HTTPS") {
fileString += "<key>ServerURL</key>\n";
}
else {
fileString += "<key>ServerName</key>\n";
}
fileString += "<string>" + document.getElementById("serverUrl").value + "</string>\n";
fileString += "</dict>\n";
fileString += "<key>OnDemandRules</key>\n";
fileString += "<array>\n";
if (exclWifi.value != "") {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Disconnect</string>\n";
fileString += "<key>SSIDMatch</key>\n"
fileString += "<array>\n";
exclWifi.value.split(/\s*,\s*/).forEach(function(wifiString) {
console.log(wifiString);
fileString += "<string>" + wifiString + "</string>\n";
});
fileString += "</array>\n";
fileString += "</dict>\n";
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "</dict>\n";
}
if (document.getElementById("useWifi").checked) {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "<key>InterfaceTypeMatch</key>\n";
fileString += "<string>WiFi</string>\n";
fileString += "</dict>\n";
}
if (document.getElementById("useCell").checked) {
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Connect</string>\n";
fileString += "<key>InterfaceTypeMatch</key>\n";
fileString += "<string>Cellular</string>\n";
fileString += "</dict>\n";
}
fileString += "<dict>\n";
fileString += "<key>Action</key>\n";
fileString += "<string>Disconnect</string>\n";
fileString += "</dict>\n";
fileString += "</array>\n";
fileString += "<key>PayloadDescription</key>\n";
fileString += "<string>Configures device to use " + provName + " Encrypted DNS over " + encValue + "</string>\n";
fileString += "<key>PayloadDisplayName</key>\n";
fileString += "<string>" + provName + " DNS over " + encValue + "</string>\n";
fileString += "<key>PayloadIdentifier</key>\n";
fileString += "<string>com.apple.dnsSettings.managed." + uuidv4() + "</string>\n";
fileString += "<key>PayloadType</key>\n";
fileString += "<string>com.apple.dnsSettings.managed</string>\n";
fileString += "<key>PayloadUUID</key>\n";
fileString += "<string>" + uuidv4() + "</string>\n";
fileString += "<key>PayloadVersion</key>\n";
fileString += "<integer>1</integer>\n";
fileString += "<key>ProhibitDisablement</key>\n";
if (document.getElementById("lockProfile").checked) {
fileString += "<true/>\n";
}
else {
fileString += "<false/>\n";
}
fileString += "</dict>\n";
fileString += "</array>\n";
fileString += "<key>PayloadDescription</key>\n";
fileString += "<string>Adds " + provName + " Encrypted DNS over " + encValue + " to Big Sur and iOS 14 based systems</string>\n";
fileString += "<key>PayloadDisplayName</key>\n";
fileString += "<string>" + provName + " DNS over " + encValue + "</string>\n";
fileString += "<key>PayloadIdentifier</key>\n";
fileString += "<string>com.notjakob.apple-dns." + uuidv4() + "</string>\n";
fileString += "<key>PayloadRemovalDisallowed</key>\n";
fileString += "<false/>\n";
fileString += "<key>PayloadType</key>\n";
fileString += "<string>Configuration</string>\n";
fileString += "<key>PayloadUUID</key>\n";
fileString += "<string>" + uuidv4() + "</string>\n";
fileString += "<key>PayloadVersion</key>\n";
fileString += "<integer>1</integer>\n";
fileString += "</dict>\n";
fileString += "</plist>";
var blob = new Blob([fileString], { type: "text/plain;charset=utf-8" });
deleteAllCookies();
saveAs(blob, "dns.mobileconfig");
} }
function addToList() {
var runningNo = getCookie("runningNo");
if (getCookie("runningNo") == "") {
runningNo = 0;
}
var d = new Date();
d.setTime(d.getTime() + (86400000)); //expires in 24h
var expires = "expires="+ d.toUTCString();
document.cookie = runningNo + "provName=" + document.getElementById("provName").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "doh=" + document.getElementById("doh").checked + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "dns1v4=" + document.getElementById("dns1v4").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "dns2v4=" + document.getElementById("dns2v4").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "dns1v6=" + document.getElementById("dns1v6").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "dns2v6=" + document.getElementById("dns2v6").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "serverUrl=" + document.getElementById("serverUrl").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "exclWifi=" + document.getElementById("exclWifi").value + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "useWifi=" + document.getElementById("useWifi").checked + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "useCell=" + document.getElementById("useCell").checked + ";" + expires + ";path=/; SameSite=Strict; Secure";
document.cookie = runningNo + "lockProfile=" + document.getElementById("lockProfile").checked + ";" + expires + ";path=/; SameSite=Strict; Secure";
runningNo++;
document.cookie = "runningNo=" + runningNo + ";" + expires + ";path=/; SameSite=Strict; Secure";
window.location.href = "/finalize.html"
}
function switchToHTTPS() { function switchToHTTPS() {
document.getElementById("serverUrl").placeholder = "https://example.com/query" + document.getElementById("serverUrl").value; document.getElementById("serverUrl").placeholder = "https://example.com/query" + document.getElementById("serverUrl").value;
document.getElementById("dohdotServerLabel").innerHTML = "DoH server URL:"; document.getElementById("dohdotServerLabel").innerHTML = "DoH server URL:";
} }
function switchToTLS() { function switchToTLS() {
document.getElementById("serverUrl").placeholder = "dot.example.com"; document.getElementById("serverUrl").placeholder = "dot.example.com";
document.getElementById("dohdotServerLabel").innerHTML = "DoT server URL:"; document.getElementById("dohdotServerLabel").innerHTML = "DoT server URL:";
} }
function loadPremade() { function loadPremade() {
var provName = document.getElementById("provName"); var provName = document.getElementById("provName");
var checkDoH = document.getElementById("doh"); var checkDoH = document.getElementById("doh");
@ -199,7 +60,7 @@ function loadPremade() {
var dns1v6 = document.getElementById("dns1v6"); var dns1v6 = document.getElementById("dns1v6");
var dns2v6 = document.getElementById("dns2v6"); var dns2v6 = document.getElementById("dns2v6");
var serverUrl = document.getElementById("serverUrl"); var serverUrl = document.getElementById("serverUrl");
provName.value = getCookie("provName"); provName.value = getCookie("provName");
if (getCookie("doh") == "true") { if (getCookie("doh") == "true") {
checkDoH.checked = true; checkDoH.checked = true;
@ -212,13 +73,13 @@ function loadPremade() {
dns2v6.value = getCookie("dns2v6"); dns2v6.value = getCookie("dns2v6");
serverUrl.value = getCookie("serverUrl"); serverUrl.value = getCookie("serverUrl");
} }
function accordion() { function accordion() {
var adv = document.getElementById("advanced_container"); var adv = document.getElementById("advanced_container");
if (adv.className.indexOf("w3-show") == -1) { if (adv.className.indexOf("w3-show") == -1) {
adv.className += " w3-show"; adv.className += " w3-show";
adv.previousElementSibling.className = adv.previousElementSibling.className.replace("w3-dark-grey", "w3-black"); adv.previousElementSibling.className = adv.previousElementSibling.className.replace("w3-dark-grey", "w3-black");
} } else {
else {
adv.className = adv.className.replace(" w3-show", ""); adv.className = adv.className.replace(" w3-show", "");
adv.previousElementSibling.className = adv.previousElementSibling.className.replace("w3-black", "w3-dark-grey"); adv.previousElementSibling.className = adv.previousElementSibling.className.replace("w3-black", "w3-dark-grey");
} }

View file

@ -12,9 +12,10 @@
<h2>For iOS 14 or later and macOS Big Sur or later</h2> <h2>For iOS 14 or later and macOS Big Sur or later</h2>
<div class="w3-bar w3-border bar-color"> <div class="w3-bar w3-border bar-color">
<a href="/index.html" class="w3-bar-item w3-button w3-mobile">About</a> <a href="/" class="w3-bar-item w3-button w3-mobile">About</a>
<a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a> <a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a>
<a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a> <a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a>
<a href="/finalize.html" class="w3-bar-item w3-button w3-mobile">Finalize profile</a>
<a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a> <a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a>
<a href="/legal.html" class="w3-bar-item w3-button w3-right w3-green w3-mobile">Legal</a> <a href="/legal.html" class="w3-bar-item w3-button w3-right w3-green w3-mobile">Legal</a>
</div> </div>

View file

@ -13,9 +13,10 @@
<h2>For iOS 14 or later and macOS Big Sur or later</h2> <h2>For iOS 14 or later and macOS Big Sur or later</h2>
<div class="w3-bar w3-border bar-color"> <div class="w3-bar w3-border bar-color">
<a href="/index.html" class="w3-bar-item w3-button w3-mobile">About</a> <a href="/" class="w3-bar-item w3-button w3-mobile">About</a>
<a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a> <a href="/tool.html" class="w3-bar-item w3-button w3-mobile">Tool</a>
<a href="/premades.html" class="w3-bar-item w3-button w3-green w3-mobile">Pre-made profiles</a> <a href="/premades.html" class="w3-bar-item w3-button w3-green w3-mobile">Pre-made profiles</a>
<a href="/finalize.html" class="w3-bar-item w3-button w3-mobile">Finalize profile</a>
<a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a> <a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a>
<a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a> <a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a>
</div> </div>
@ -52,7 +53,7 @@
Protocols: DoH, DoT</p> Protocols: DoH, DoT</p>
<h3>Default configuration</h3> <h3>Default configuration</h3>
<button class="w3-button w3-dark-gray" onclick="createCookie ('Applied Privacy', true, '', '', '', '', 'https://doh.applied-privacy.net/query');">Import DoH</button> <button class="w3-button w3-dark-gray" onclick="createCookie ('Applied Privacy', true, '', '', '', '', 'https://doh.applied-privacy.net/query');">Import DoH</button>
<button class="w3-button w3-dark-gray" onclick="createCookie ('AdGuard', false, '146.255.56.98', '', '2a02:1b8:10:234::2', '', 'dns.adguard.com');">Import DoT</button> <button class="w3-button w3-dark-gray" onclick="createCookie ('Applied Privacy', false, '', '', '', '', 'dot1.applied-privacy.net');">Import DoT</button>
</div> </div>
<br> <br>
<button onclick="accToggle('blahdns')" class="w3-button w3-block w3-left-align w3-green">BlahDNS</button> <button onclick="accToggle('blahdns')" class="w3-button w3-block w3-left-align w3-green">BlahDNS</button>

View file

@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -7,27 +8,28 @@
<link rel="stylesheet" href="css/w3.css"> <link rel="stylesheet" href="css/w3.css">
<link rel="stylesheet" href="css/form.css"> <link rel="stylesheet" href="css/form.css">
<link rel="stylesheet" href="css/dark-mode.css"> <link rel="stylesheet" href="css/dark-mode.css">
<script src="js/FileSaver.min.js"></script>
<script src="js/uuidv4.min.js"></script> <script src="js/uuidv4.min.js"></script>
<script src="js/tool.js"></script> <script src="js/tool.js"></script>
</head> </head>
<body class="w3-container" onload="loadPremade()"> <body class="w3-container" onload="loadPremade()">
<h1>Secure DNS profile creator</h1> <h1>Secure DNS profile creator</h1>
<h2>For iOS 14 or later and macOS Big Sur or later</h2> <h2>For iOS 14 or later and macOS Big Sur or later</h2>
<div class="w3-bar w3-border bar-color"> <div class="w3-bar w3-border bar-color">
<a href="/" class="w3-bar-item w3-button w3-mobile">About</a> <a href="/" class="w3-bar-item w3-button w3-mobile">About</a>
<a href="/tool.html" class="w3-bar-item w3-button w3-green w3-mobile">Tool</a> <a href="/tool.html" class="w3-bar-item w3-button w3-green w3-mobile">Tool</a>
<a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a> <a href="/premades.html" class="w3-bar-item w3-button w3-mobile">Pre-made profiles</a>
<a href="/finalize.html" class="w3-bar-item w3-button w3-mobile">Finalize profile</a>
<a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a> <a href="https://github.com/fyr77/dns-mobileconfig" class="w3-bar-item w3-button w3-right w3-black w3-mobile">GitHub</a>
<a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a> <a href="/legal.html" class="w3-bar-item w3-button w3-right w3-black w3-mobile">Legal</a>
</div> </div>
<br> <br>
<h4><a href="/premades.html">Choose a pre-configured provider</a>, or enter your own settings:</h4> <h4><a href="/premades.html">Choose a pre-configured provider</a>, or enter your own settings:</h4>
<form action="javascript:saveDynamicDataToFile()"> <form action="javascript:addToList()">
<p> <p>
<label for="provName">Name of DNS provider:</label> <label for="provName">Name of DNS provider:</label>
<input type="text" id="provName" placeholder="MyCoolSecureProvider" required> <input type="text" id="provName" placeholder="MyCoolSecureProvider" required>
@ -44,9 +46,11 @@
<label for="dns2v4" class="optional">IPv4 secondary DNS:</label> <label for="dns2v4" class="optional">IPv4 secondary DNS:</label>
<input type="text" id="dns2v4" placeholder="0.0.0.1"> <input type="text" id="dns2v4" placeholder="0.0.0.1">
<label for="dns1v6" class="optional">IPv6 primary DNS:</label> <label for="dns1v6" class="optional">IPv6 primary DNS:</label>
<input type="text" id="dns1v6" placeholder="0000:0000:0000:0000:0000:0000:0000:0000 - other formats also accepted"> <input type="text" id="dns1v6"
placeholder="0000:0000:0000:0000:0000:0000:0000:0000 - other formats also accepted">
<label for="dns2v6" class="optional">IPv6 secondary DNS:</label> <label for="dns2v6" class="optional">IPv6 secondary DNS:</label>
<input type="text" id="dns2v6" placeholder="0000:0000:0000:0000:0000:0000:0000:0001 - other formats also accepted"> <input type="text" id="dns2v6"
placeholder="0000:0000:0000:0000:0000:0000:0000:0001 - other formats also accepted">
</p> </p>
<p> <p>
<label for="serverUrl" id="dohdotServerLabel">DoH server URL:</label> <label for="serverUrl" id="dohdotServerLabel">DoH server URL:</label>
@ -57,10 +61,11 @@
<p> <p>
<label for="exclWifi" class="optional">Excluded Wi-Fi Networks:</label> <label for="exclWifi" class="optional">Excluded Wi-Fi Networks:</label>
<input type="text" id="exclWifi" placeholder="MyHomeNetwork, Silence of the LANs"> <input type="text" id="exclWifi" placeholder="MyHomeNetwork, Silence of the LANs">
<span style="color: grey">Enter a comma-separated list of Wi-Fi networks (SSID) on which the encrypted DNS will be disabled.</span> <span style="color: grey">Enter a comma-separated list of Wi-Fi networks (SSID) on which the encrypted
DNS will be disabled.</span>
</p> </p>
<p> <p>
Interfaces to use encrypted DNS on: Interfaces to use encrypted DNS on:
<label for="useWifi">Wi-Fi</label> <label for="useWifi">Wi-Fi</label>
<input type="checkbox" id="useWifi" checked> <input type="checkbox" id="useWifi" checked>
<label for="useCell">Cellular</label> <label for="useCell">Cellular</label>
@ -72,10 +77,12 @@
<label for="lockProfile">Prohibit Disablement</label> <label for="lockProfile">Prohibit Disablement</label>
<input type="checkbox" id="lockProfile"> <input type="checkbox" id="lockProfile">
<br> <br>
<span style="color: grey">Prohibit users from removing the profile. Only available on supervised devices.</span> <span style="color: grey">Prohibit users from removing the profile. Only available on supervised
devices.</span>
</p> </p>
</div> </div>
<p><input type="submit" class="button1" value="Download profile"></p> <p><input type="submit" value="Add to profile"></p>
</form> </form>
</body> </body>
</html> </html>