How Maintain Online Optimal Security - DNS OVER TLS Servers' SPKI pin(s) Maintenance and UpKeep -
See VERY IMPORTANT UPDATE: at end of this post for best DNS Privacy Test Servers configuration for STUBBY.
ForeThought: If you have figured out how to keep your DNS OVER TLS servers' SPKI pin(s) up to date and secure then skip to the last section where there is an excellent website : https://www.immuniweb.com/ssl/?id=Su8SeUQ4 for running an in depth SSL Security Test for all the servers you chose to deploy on your network.
My Dear Community,
There has been some understandable consternation and occasional grumblings concerning the hassles and difficulties inherent in having
to update and authenticate SPKI pin(s) when running DNS OVER TLS ( DNS Privacy Test Servers ). Towards making this process somewhat more
manageable and easier, I will share with you here some of the methods I employ towards achieving this goal.
First - I have found there are times where listed DNS Privacy Test Servers change their server IP's and / or hostnames from the ones listed found here: https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers ) on the official page for this project. A few are horribly outdated. In order to avoid falling into this pitfall, I suggest that you do the following periodically.
A - Enter this command from SSH - dig +short dot-jp.blahdns.com ( for example ). This will return the current IP address of the server.
In this case 188.8.131.52 - For instance I use a DNS OVER TLS server not mentioned on the DNS Privacy Test Server page - doh.defaultroutes.de - by running dig +short doh.defaultroutes.de - I confirmed the server address as 184.108.40.206. By the way the maintainer of this server mistakenly posted the SPKI pin for his server as the main Let's Encrypt Certificate - not the first one in the hierarchy. See below after I ran command - kdig -d @220.127.116.11 +tls-ca +tls-host=doh.defaultroutes.de example.com - the prinout read:
;; DEBUG: #1, CN=doh.defaultroutes.de
;; DEBUG: SHA-256 PIN: zYnx/ptyLlxHp9RQ5cHXbe2HJLXyZUT3A/lbyhd0B/M=
;; DEBUG: #2, C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3
;; DEBUG: SHA-256 PIN: YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=
;; DEBUG: TLS, skipping certificate PIN check
;; DEBUG: TLS, The certificate is trusted.
You see the first certificate is the correct one. While # 2 belongs to Let's Encrypt ( YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg= ) and is on all the certificates they issue and is valid for the next 697 days - you do the math. He in error listed the wrong PIN.
You may also issue the host command - host dot-jp.blahdns.com - which returns dot-jp.blahdns.com has address 18.104.22.168 and dot-jp.blahdns.com has IPv6 address 2001:19f0:7001:1ded:5400:1ff:fe90:945b
You may also use nslookup command which works both ways - nslookup dot-jp.blahdns.com returns both the IPv4 and IPV6 server addresses.
nslookup 22.214.171.124 this returned with an answer for the server being jp1.blahdns.com - this error is why you need to run more than method to validate your findings for your settings.
I chose BlahDNS because not too long ago they changed both their servers' IP and hostnames. In addition their SPKI pin(s) have been updated ( changed ). Many ( not all ) of these DNS Privacy Test Server providers use Let's Encrypt Certificates and as many of you well know these must be renewed every three months. I will address this as we continue along.
Lastly, if needs be for any reason try Googling the server hostname or IP address to see if either has been modified.
Secondly - Now let's move on to see if are DNS OVER TLS servers' SPKI pin(s) are verified as being current ( not expired ) and trusted.
A - The easiest and most straightforward method of attempting to do this is to issue this command: gnutls-cli --print-cert -p 443 126.96.36.199 - where 443 is the port I chose to connect to the dot-jp.blahdns.com DNS TLS server. If I selected to connect over port 853 the I would have issued - gnutls-cli --print-cert -p 853 188.8.131.52 . BlahDNS permits both ports 443 and 853 for TLS - see here for real time status and configuration of DNS Privacy Test Servers : https://dnsprivacy.org/jenkins/job/dnsprivacy-monitoring/ You must install
gnutls-utils in order to run the commands. The problem here is that at times the output will falsely state that the certificate is not trusted. However - if you look along the top the printout will tell you much of this needed information.
CN=dot-jp.blahdns.com', issuerCN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US', serial 0x04dc4acf35d3bc6a62c79b553835e66351ac, RSA key 2048 bits, signed using RSA-SHA256, activated
2019-04-10 19:13:11 UTC', expires2019-07-09 19:13:11 UTC', pin-sha256="B0mMSct7Bbz4E7Lk6BwXuVzdxA1KuYtDs8pw7uaPmB4="
The certificate is B0mMSct7Bbz4E7Lk6BwXuVzdxA1KuYtDs8pw7uaPmB4= and is good from 2019-04-10 19 until 2019-07-09 19. Run kdig below in order to see if the certificate is truly trusted.
B - The second method is to install knot-dig ( OpenWrt ) or Knot2 ( FreeBsd ) ( you need to be able to run kdig command ). keeping with our example: kdig -d @184.108.40.206 +tls-ca +tls-host=dot-jp.blahdns.com example.com - this methods prints the CN ( Certificate Name ) and SHA-256 PIN: B0mMSct7Bbz4E7Lk6BwXuVzdxA1KuYtDs8pw7uaPmB4= ( aka SPKI pin ) for this server. Also here we see from the printout:
;; DEBUG: TLS, skipping certificate PIN check
;; DEBUG: TLS, The certificate is trusted.
C - The third method for getting DNS OVER TLS servers' SPKI pin(s) will give you the pin- but virtually nothing else. Issue command as follows: echo | openssl s_client -connect '220.127.116.11:853' 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 - The print out reads - B0mMSct7Bbz4E7Lk6BwXuVzdxA1KuYtDs8pw7uaPmB4= which is the correct certificate. However, you can not tell if it is expired or trusted. For example, Surfnet ( which is getdns ) has several servers. dnsovertls3.sinodun.com ( 18.104.22.168 ) currently has an expired certificate. When I run - echo | openssl s_client -connect '22.214.171.124:853' 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 - The printed out gives me the correct certificate - 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8= - However the certificate is expired. Running gnutls-cli --print-cert -p 853 126.96.36.199 - provides verification of expiration below:
- Certificate info:
CN=dnsovertls3.sinodun.com', issuerCN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US', serial 0x030566ee19f2ef98451faa2322093fb000b3, RSA key 4096 bits, signed using RSA-SHA256, activated
2018-11-19 11:15:34 UTC', expires2019-02-17. The certificate was good from 2018-11-19 until 2019-02-17. You can once again check real time status here: https://dnsprivacy.org/jenkins/job/dnsprivacy-monitoring/
Running kdig -d @188.8.131.52 +tls-ca +tls-host=dnsovertls3.sinodun.com example.com - The readout is below which confirms expiration:
;; DEBUG: TLS, The certificate is NOT trusted. The certificate chain uses expired certificate.
So you see you must combine methods listed above to be truly secure and encrypted when running DNS Privacy Test Servers which essentially depend and rely on proper DNS OVER TLS servers' SPKI pin(s) being up to date and trusted.
Finally the Bonus:
As I wandered over the internet in search of security - I came across this website : ImmuniWeb SSL Security Test found here:
https://www.immuniweb.com/ssl/?id=Su8SeUQ4 Once on the website, you may test your remote DNS OVER TLS Servers. At the top of the page - simply enter the server hostname and port that you are using to connect to the remote server. For example I would enter -
dot-jp.blahdns.com:443 in keeping with the example I have been using throughout this guide. This site will resent you with a rating of the server and its' features. It will also list the certificate - when it was activated - when is the expiration date and encryption protocols and so much more. By the way, dot-jp.blahdns.com earns an A+ ratings. DNS is the backbone of your network - stay safe and secure out there
while you and your loved ones peruse the world of cyber connectivity. With dot-jp.blahdns.com:443 I encountered errors getting the correct certificate information. When I entered dot-jp.blahdns.com alone - everything went fine. You may have to play around with the entries. This is why it is best to have multiple tools and methods to cross check your certificates aka DNS OVER TLS Servers' SPKI pin(s) - hostnames and IP addresses. For instance - I know from two of these methods - one being this website the other using gnutls-utils - that the certificate for DNS TLS SERVER doh.defaultroutes.de ( 184.108.40.206 ) will expire in four days on 2019-04-24.
VERY IMPORTANT UPDATE:
After checking, rechecking and the triple checking on this website mentioned above : https://www.immuniweb.com/ssl/?id=Su8SeUQ4 I have made some very serious discoveries regarding which DNS Privacy Test Servers to use. The bottom line that I strongly suggest you only choose to deploy servers which support the TLSv1.3 protocol. See here for information and importance of TLSv1.3 : https://kinsta.com/blog/tls-1-3/
I will save you some considerable leg work and post below the best configuration for your stubby.yml file. Here it is:
nano /etc/stubby/stubby.yml resolution_type: GETDNS_RESOLUTION_STUB round_robin_upstreams: 1 appdata_dir: "/var/lib/stubby" tls_authentication: GETDNS_AUTHENTICATION_REQUIRED tls_query_padding_blocksize: 128 edns_client_subnet_private: 1 idle_timeout: 60000 listen_addresses: - 127.0.0.1@5453 dns_transport_list: - GETDNS_TRANSPORT_TLS tls_connection_retries: 5 tls_backoff_time: 900 timeout: 2000 upstream_recursive_servers: # IPV4 Servers ### DNS Privacy Test Servers ### ## The Surfnet/Sinodun DNS TLS Server - address_data: 220.127.116.11 tls_port: 853 tls_auth_name: "dnsovertls3.sinodun.com" tls_pubkey_pinset: - digest: "sha256" value: 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8= # The securedns.eu DNS TLS Server dot.securedns.eu - address_data: 18.104.22.168 tls_auth_name: "ads-dot.securedns.eu" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: h3mufC43MEqRD6uE4lz6gAgULZ5/riqH/E+U+jE3H8g= #The BlahDNS German DNS TLS Server - address_data: 22.214.171.124 tls_auth_name: "dot-de.blahdns.com" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: GsfF6a28usi59J/pUUtqbyfmmyKE7+7OfzdLXzUt/Aw= #The BlahDNS Japan DNS TLS Server - address_data: 126.96.36.199 tls_auth_name: "dot-jp.blahdns.com" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: B0mMSct7Bbz4E7Lk6BwXuVzdxA1KuYtDs8pw7uaPmB4= #The DNS Warden DNS TLS Primary Server - address_data: 188.8.131.52 tls_auth_name: "dot1.dnswarden.com" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: deCWLScS/hqOKvzPDNr9JZdoBYsrWM7AWQ56biseGxA= #The DNS Warden DNS TLS Secondary Server - address_data: 184.108.40.206 tls_auth_name: "dot2.dnswarden.com" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: deCWLScS/hqOKvzPDNr9JZdoBYsrWM7AWQ56biseGxA= #The Primary appliedprivacy.net DNS TLS Server - address_data: 220.127.116.11 tls_auth_name: "dot1.appliedprivacy.net" tls_port: 443 tls_pubkey_pinset: - digest: "sha256" value: ScYkwTIhR1AZGwAsy9Fgn+ET70+t8HR8giYq9abl7tA= #The ibksturm DNS TLS Server - address_data: 18.104.22.168 tls_auth_name: "ibksturm.synology.me" tls_port: 853 tls_pubkey_pinset: - digest: "sha256" value: v9DZ6wtFZcs26wzq6lwHSlcV6o0Nvw/9pLiBarQJfQE= #The dns.seby.io - Vultr DNS TLS Server - address_data: 22.214.171.124 tls_auth_name: "dot.seby.io" tls_port: 853 tls_pubkey_pinset: - digest: "sha256" value: xTjAOypMRG8ef7ZnQPk1TAku3xvtdQBPH+H3dCQyqDs= #The Secure DNS Project by PumpleX DNS TLS Server - address_data: 126.96.36.199 tls_auth_name: "dns.oszx.co" tls_port: 853 tls_pubkey_pinset: - digest: "sha256" value: P/Auj1pm8MiUpeIxGcrEuMJOQV+pgPY0MR4awpclvT4= #The edns.233py.com DNS TLS Server - address_data: 188.8.131.52 tls_auth_name: "dns.233py.com" tls_port: 853 tls_pubkey_pinset: - digest: "sha256" value: Aqo3emoFTNuVG85U26NnGJmjlTuUCm9H5cySw0HUYas= #The Rubyfish Internet Tech DNS TLS Server - address_data: 184.108.40.206 tls_port: 853 tls_auth_name: "uw-dns.rubyfish.cn" tls_pubkey_pinset: - digest: "sha256" value: DBDigty3zDS7TN/zbQOmnjZ0qW+qbRVzlsDKSsTwSxo= ### Anycast DNS Privacy Public Resolvers ### #Quad9 'secure' DNS TLS Secondary Server - address_data: 220.127.116.11 tls_auth_name: "dns.quad9.net" tls_port: 853 tls_pubkey_pinset: - digest: "sha256" value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg= tls_min_version: GETDNS_TLS1_3 tls_ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" Save and Exit - Then reboot your Router for changes to take effect