Since our BIND server currently does not support TLS secured queries natively, we will be using nginx rather than stunnel to provide a secured endpoint. Not only is Nginx already part of our system, it also allows more granular configuration. We will proxy the requests to our local BIND instance.
The nginx stream module needs to be configured inside nginx.conf
on the same level as the http directives. We will need to create a symbolic link inside
stream { upstream dns_tcp_servers {server 127.0.0.1:53; } server { listen 10.0.0.1:853 ssl; listen [2a02:beef:fa:1000::1]:853 ssl; proxy_pass dns_tcp_servers; ssl_certificate /etc/ssl/certs/ns_example_com_ACME.pem; ssl_certificate_key /etc/ssl/private/ns_example_com_ACME.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_prefer_server_ciphers on; ssl_dhparam /etc/nginx/dh4096.pem; ssl_session_cache shared:DNS:10m; ssl_session_timeout 4h; ssl_handshake_timeout 30s; } }
Having no means to control access via BIND’s ACL statements in this case, we will filter our clients using a rule in nftables.
set ipv4_dns_over_tls { type ipv4_addr elements = { 192.168.1.1 } } chain input { type filter hook input priority 0; policy drop; jump global meta nfproto ipv4 ip daddr . tcp dport @ipv4_tcp_services accept meta nfproto ipv4 ip daddr . udp dport @ipv4_udp_services accept meta nfproto ipv6 ip6 daddr . tcp dport @ipv6_tcp_services accept meta nfproto ipv6 ip6 daddr . udp dport @ipv6_udp_services acceptip saddr @ipv4_dns_over_tls tcp dport 853 ip daddr 10.0.0.1 accept }