Implement blahdns verification service

Blahdns.com is one of my personal projects try to bring Ads block by default to my personal use. Since 2016, I started to make it public and implement tons of block list such as malware, scam, phishing, fake news, etc.
In 2018 Jun, after implement unencrypted DNS service, I think is time to move forward to an encrypted DNS world. So I learned how to do DNS over HTTPS, TLS and implement TLS1.3 to ensure the security and makes ISP or GOV harder to sniff the DNS traffic.

DEMO

Implement dns verficication service into my site

# Select a div#status and try to fetch url, if url found will return status 0 or 403, then success.

const text = document.querySelector("#status")
    const url = 'https://test.blahdns.com'
    fetch(url, {
        credentials: 'same-origin',
        method: "HEAD",
        mode: "no-cors",
        cache: "no-cache",
    })
    .then(function(response){
        console.log(response.status)
        console.log(text)
        if (response.status == 0 || response.status == 403) {
            text.innerHTML = "You're <strong>using</strong> Blahdns"
        } else {
            text.innerHTML = "You're <strong> not </strong> usingBlahdns"
        }
    })
    .catch(error => console.log(error) );

From the very beginning, I tried to just deal with HTTP. It is easier to do a test, but I realize that Chrome 70 and Firefox 65 they already block CORS and HTTPS, so I try out myself by following steps.

  1. Add domain test.blahdns.com A record at domain provider
  2. Put a real IP into test.blahdns.com and get a Let’s Encrypt SSL cert
  3. Remove the A record, and add vhost in Nginx server to serve test.blahdns.com
  4. In my blahdns resolver, I manually insert A record in it. 
  5. Done !

I tried on HAproxy and some Javascript, here is some hints to achieve.

# HA Proxy
frontend www
  acl app_2 req.ssl_sni -i test.blahdns.com
  # http acl app_2 hdr_dom(host) -i foo.bar.com
  use-server server2 if app_2
  ... OR ...
  default_backend no-match

backend no-match
  http-request deny deny_status 400

# Javascript
# Some sample show out I can use HEAD to check
$.ajax({url: "http://xxx.com",
        type: "HEAD",
        timeout:1000,
        statusCode: {
            200: function (response) {
                alert('Working!');
            },
            400: function (response) {
                alert('Not working!');
            },
            0: function (response) {
                alert('Not working!');
            }              
        }
 });

# HTML
# Mixed Content error?
## allow 
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
## block
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">

# NGiNX disable HSTS
server {
#...
        ssl on;
#...
        add_header Strict-Transport-Security "max-age=0;";
#...
}

References
1. https://stackoverflow.com/questions/17877639/is-there-any-way-to-check-reachability-test-of-server-in-jquery?answertab=votes#tab-top 
2. https://enable-cors.org/server_nginx.html (Nginx add CORS allow header)
3. https://gist.github.com/nasrulhazim/3f726dbe91c0fa87730809a014f89a02 (HAproxy add CORS allow header)
4. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
5. https://stackoverflow.com/questions/18251128/why-am-i-suddenly-getting-a-blocked-loading-mixed-active-content-issue-in-fire
6. https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
7. https://superuser.com/questions/565409/how-to-stop-an-automatic-redirect-from-http-to-https-in-chrome
8. https://cors-anywhere.herokuapp.com/ (CROSS-Proxy)

Featured Image by Ricardo Gomez Angel on Unsplash