diff --git a/nginx/conf.d/doh.conf b/nginx/conf.d/doh.conf index 559b226..153c1ff 100644 --- a/nginx/conf.d/doh.conf +++ b/nginx/conf.d/doh.conf @@ -1,14 +1,4 @@ -# server{ -# listen 8080; -# listen [::]:8080; -# server_name doh.fcms.ir; - -# location / { -# # proxy_pass http://127.0.0.1:8053/; -# return https://doh.fcms.ir:${DOH_PORT}$request_uri; -# } -# } upstream dohloop { zone dohloop 64k; server tariq-doh:8053; @@ -28,18 +18,11 @@ server { ssl_certificate_key /ssl/key.pem; ssl_session_cache shared:ssl_cache:10m; ssl_session_timeout 10m; - # server_name ${domain}; # DoH may use GET or POST requests, Cache both proxy_cache_methods GET POST; - # Return 404 to all responses, except for those using our published DoH URI - # location / { - # return 404 "404 Not Found\n"; - # } - # This is our published DoH URI - # location /dns-query { location / { # Proxy HTTP/1.1, clear the connection header to enable Keep-Alive proxy_http_version 1.1; @@ -51,48 +34,3 @@ server { proxy_pass http://dohloop; } } - -# server { -# listen 8080; -# location /api { -# api write=on; -# allow 127.0.0.1; -# # allow 192.168.64.1; -# deny all; -# } -# } - -# server{ - -# listen ${DOH_PORT} ssl; -# listen [::]:${DOH_PORT} ssl; -# server_name ${domain}; - -# ssl_certificate ${cert_path}; -# ssl_certificate_key ${key_path}; -# ssl_dhparam ${dhparam_path}; -# ssl_protocols TLSv1.2 TLSv1.3; # TLS 1.3 requires nginx >= 1.13.0 -# ssl_prefer_server_ciphers on; -# ssl_ciphers EECDH+AESGCM:EDH+AESGCM; -# ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0 -# ssl_session_timeout 10m; -# ssl_session_cache shared:SSL:10m; -# ssl_session_tickets off; # Requires nginx >= 1.5.9 -# ssl_stapling on; # Requires nginx >= 1.3.7 -# ssl_stapling_verify on; # Requires nginx => 1.3.7 -# ssl_early_data off; # 0-RTT, enable if desired - Requires nginx >= 1.15.4 -# resolver 127.0.0.1 valid=300s; # Replace with your local resolver -# resolver_timeout 5s; -# # HTTP Security Headers -# add_header X-Frame-Options DENY; -# add_header X-Content-Type-Options nosniff; -# add_header X-XSS-Protection "1; mode=block"; -# add_header Strict-Transport-Security "max-age=63072000"; - -# location / { -# proxy_pass http://127.0.0.1:8053/; -# proxy_set_header Host $host; -# proxy_set_header X-Real-IP $remote_addr; -# } -# } - diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 3789331..5c6e368 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -2,7 +2,7 @@ user nginx; worker_processes auto; -load_module modules/ngx_stream_js_module.so; +# load_module modules/ngx_stream_js_module.so; # load_module modules/ngx_http_js_module.so; error_log /var/log/nginx/error.log notice; diff --git a/nginx/njs.d/dns/dns.js b/nginx/njs.d/dns/dns.js deleted file mode 100644 index 44ec433..0000000 --- a/nginx/njs.d/dns/dns.js +++ /dev/null @@ -1,304 +0,0 @@ -import dns from "libdns.js"; -export default {get_qname, get_response, preread_doh_request, preread_dns_request, filter_doh_request}; - -/** - * DNS Decode Level - * 0: No decoding, minimal processing required to strip packet from HTTP wrapper (fastest) - * 1: Parse DNS Header and Question. We can log the Question, Class, Type, and Result Code - * 2: As 1, but also parse answers. We can log the answers, and also cache responses in HTTP Content-Cache - * 3: Very Verbose, log everything as above, but also write packet data to error log (slowest) -**/ -var dns_decode_level = 3; - -/** - * DNS Question Load Balancing - * Set this to true, if you want to pick the upstream pool based on the DNS Question. - * Doing so will disable HTTP KeepAlives for DoH so that we can create a new socket for each query -**/ -var dns_question_balancing = false; - -// The DNS Question name -var dns_name = String.bytesFrom([]); - -function get_qname(s) { - return dns_name; -} - -// The Optional DNS response, this is set when we want to block a specific domain -var dns_response = String.bytesFrom([]); - -function get_response(s) { - return dns_response.toString(); -} - -// Encode the given number to two bytes (16 bit) -function to_bytes( number ) { - return String.fromCodePoint( ((number>>8) & 0xff), (number & 0xff) ).toBytes(); -} - -function debug(s, msg) { - if ( dns_decode_level >= 3 ) { - s.warn(msg); - } -} - -function process_doh_request(s, decode, scrub) { - s.on("upload", function(data,flags) { - if ( data.length == 0 ) { - return; - } - const lines = data.split("\r\n"); - var bytes; - var packet; - if(lines[0].startsWith("GET")) { - var line = lines[0]; - var path = line.split(" ")[1] - var params = path.split("?")[1] - var qs = params.split("&"); - debug(s, "process_doh_request: QS Params: " + qs ); - qs.some( param => { - if (param.startsWith("dns=") ) { - bytes = String.bytesFrom(param.slice(4), "base64url"); - return true; - } - return false; - }); - } - - if(lines[0].startsWith("POST")) { - const index = lines.findIndex(line=>{ - if(line.length == 0) { - return true; - } - }) - if(index>0 && lines.length >= index + 1){ - bytes = lines[index + 1]; - } - } - - if (bytes) { - debug(s, "process_doh_request: DNS Req: " + bytes.toString('hex') ); - if (decode) { - packet = dns.parse_packet(bytes); - debug(s, "process_doh_request: DNS Req ID: " + packet.id ); - dns.parse_question(packet); - debug(s,"process_doh_request: DNS Req Name: " + packet.question.name); - dns_name = packet.question.name; - } - if (scrub) { - domain_scrub(s, bytes, packet); - s.done(); - } else { - s.send( to_bytes(bytes.length) ); - s.send( bytes, {flush: true} ); - } - } else { - if ( ! scrub) { - debug(s, "process_doh_request: DNS Req: " + line.toString() ); - s.send(""); - data = ""; - } - } - }); -} - -function process_dns_request(s, decode, scrub) { - s.on("upload", function(bytes,flags) { - if ( bytes.length == 0 ) { - return; - } - var packet; - if (bytes) { - if (s.variables.protocol == "TCP") { - // Drop the TCP length field - bytes = bytes.slice(2); - } - debug(s, "process_dns_request: DNS Req: " + bytes.toString('hex') ); - if (decode) { - packet = dns.parse_packet(bytes); - debug(s, "process_dns_request: DNS Req ID: " + packet.id ); - dns.parse_question(packet); - debug(s,"process_dns_request: DNS Req Name: " + packet.question.name); - dns_name = packet.question.name; - } - if (scrub) { - domain_scrub(s, bytes, packet); - s.done(); - } else { - if (s.variables.protocol == "TCP") { - s.send( to_bytes(bytes.length) ); - } - s.send( bytes, {flush: true} ); - } - } - }); -} - -function domain_scrub(s, data, packet) { - var found = false; - if ( s.variables.server_port == 9953 ) { - dns_response = dns.shortcut_nxdomain(data, packet); - if (s.variables.protocol == "TCP" ) { - dns_response = to_bytes( dns_response.length ) + dns_response; - } - debug(s,"Scrubbed: Response: " + dns_response.toString('hex') ); - } else if ( s.variables.server_port == 9853 ) { - var answers = []; - if ( packet.question.type == dns.dns_type.A ) { - answers.push( {name: packet.question.name, type: dns.dns_type.A, class: dns.dns_class.IN, ttl: 300, rdata: "0.0.0.0" } ); - } else if ( packet.question.type == dns.dns_type.AAAA ) { - answers.push( {name: packet.question.name, type: dns.dns_type.AAAA, class: dns.dns_class.IN, ttl: 300, rdata: "0000:0000:0000:0000:0000:0000:0000:0000" } ); - } - dns_response = dns.shortcut_response(data, packet, answers); - if (s.variables.protocol == "TCP" ) { - dns_response = to_bytes( dns_response.length ) + dns_response; - } - debug(s,"Scrubbed: Response: " + dns_response.toString('hex') ); - } else { - debug(s,"Scrubbing: Check: Name: " + packet.question.name ); - if ( s.variables.scrub_action ) { - debug(s, "Scrubbing: Check: EXACT MATCH: Name: " + packet.question.name + ", Action: " + s.variables.scrub_action ); - dns_response = s.variables.scrub_action; - return; - } else { - ["blocked", "blackhole"].forEach( function( list ) { - if(found) { return }; - var blocked = s.variables[ list + "_domains" ]; - if ( blocked ) { - blocked = blocked.split(','); - blocked.forEach( function( domain ) { - if (packet.question.name.endsWith( domain )) { - debug(s,"Scrubbing: Check: LISTED: Name: " + packet.question.name + ", Action: " + list ); - dns_response = list; - found = true; - return; - } - }); - } - }); - if(found) { return }; - } - debug(s,"Scrubbing: Check: NOT FOUND: Name: " + packet.question.name); - } -} - -function preread_dns_request(s) { - process_dns_request(s, true, true); -} - -function preread_doh_request(s) { - process_doh_request(s, true, true); -} - -function filter_doh_request(s) { - - if ( dns_decode_level >= 3 ) { - process_doh_request(s, true, false); - } else { - process_doh_request(s, false, false); - } - - s.on("download", function(data, flags) { - if ( data.length == 0 ) { - return; - } - // Drop the TCP length field - data = data.slice(2); - - debug(s, "DNS Res: " + data.toString('hex') ); - var packet; - var answers = ""; - var cache_time = 10; - if ( dns_question_balancing ) { - s.send("HTTP/1.1 200\r\nConnection: Close\r\nContent-Type: application/dns-message\r\nContent-Length:" + data.length + "\r\n"); - } else { - s.send("HTTP/1.1 200\r\nConnection: Keep-Alive\r\nKeep-Alive: timeout=60, max=1000\r\nContent-Type: application/dns-message\r\nContent-Length:" + data.length + "\r\n"); - } - - if ( dns_decode_level > 0 ) { - packet = dns.parse_packet(data); - dns.parse_question(packet); - dns_name = packet.question.name; - s.send("X-DNS-Question: " + dns_name + "\r\n"); - s.send("X-DNS-Type: " + dns.dns_type.value[packet.question.type] + "\r\n"); - s.send("X-DNS-Result: " + dns.dns_codes.value[packet.codes & 0x0f] + "\r\n"); - - if ( dns_decode_level > 1 ) { - if ( dns_decode_level == 2 ) { - dns.parse_answers(packet, 2); - } else if ( dns_decode_level > 2 ) { - dns.parse_complete(packet, 2); - } - debug(s, "DNS Res Answers: " + JSON.stringify( Object.entries(packet.answers)) ); - if ( "min_ttl" in packet ) { - cache_time = packet.min_ttl; - s.send("X-DNS-TTL: " + packet.min_ttl + "\r\n"); - } - - if ( packet.an > 0 ) { - packet.answers.forEach( function(r) { answers += "[" + dns.dns_type.value[r.type] + ":" + r.data + "]," }) - answers.slice(0,-1); - } else { - answers = "[]"; - } - s.send("X-DNS-Answers: " + answers + "\r\n"); - } - debug(s, "DNS Res Packet: " + JSON.stringify( Object.entries(packet)) ); - } - - var d = new Date( Date.now() + (cache_time*1000) ).toUTCString(); - if ( ! d.includes(",") ) { - d = d.split(" ") - d = [d[0] + ',', d[2], d[1], d[3], d[4], d[5]].join(" "); - } - s.send("Cache-Control: public, max-age=" + cache_time + "\r\n" ); - s.send("Expires: " + d + "\r\n" ); - - s.send("\r\n"); - s.send( data, {flush: true} ); - if ( dns_question_balancing ) { - s.done(); - } - }); -} - -/** - * Function to perform testing of DNS packet generation for various DNS types -**/ -function test_dns_responder(s, data, packet) { - debug(s,"Testing: DNS Req Name: " + packet.question.name); - var answers = []; - if ( packet.question.type == dns.dns_type.A ) { - answers.push( {name: packet.question.name, type: dns.dns_type.A, class: dns.dns_class.IN, ttl: 300, rdata: "10.2.3.4" } ); - } else if ( packet.question.type == dns.dns_type.AAAA ) { - answers.push( {name: packet.question.name, type: dns.dns_type.AAAA, class: dns.dns_class.IN, ttl: 300, rdata: "fe80:0002:0003:0004:0005:0006:0007:0008" } ); - } else if ( packet.question.type == dns.dns_type.CNAME ) { - answers.push( {name: packet.question.name, type: dns.dns_type.CNAME, class: dns.dns_class.IN, ttl: 300, rdata: "www.foo.bar.baz" } ); - } else if ( packet.question.type == dns.dns_type.NS ) { - answers.push( {name: packet.question.name, type: dns.dns_type.NS, class: dns.dns_class.IN, ttl: 300, rdata: "ns1.foo.bar.baz" } ); - answers.push( {name: packet.question.name, type: dns.dns_type.NS, class: dns.dns_class.IN, ttl: 300, rdata: "ns2.foo.bar.baz" } ); - } else if ( packet.question.type == dns.dns_type.TXT ) { - answers.push( {name: packet.question.name, type: dns.dns_type.TXT, class: dns.dns_class.IN, ttl: 300, rdata: ["ns1.foo.bar.baz","1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1234567890"] } ); - } else if ( packet.question.type == dns.dns_type.MX ) { - answers.push( {name: packet.question.name, type: dns.dns_type.MX, class: dns.dns_class.IN, ttl: 300, rdata: { priority: 1, exchange: "mx1.foo.com"} } ); - answers.push( {name: packet.question.name, type: dns.dns_type.MX, class: dns.dns_class.IN, ttl: 300, rdata: { priority: 10, exchange: "mx2.foo.com"} } ); - } else if ( packet.question.type == dns.dns_type.SRV ) { - answers.push( {name: packet.question.name, type: dns.dns_type.SRV, class: dns.dns_class.IN, ttl: 300, rdata: { priority: 1, weight: 10, port: 443, target: "server1.foo.com"} } ); - } else if ( packet.question.type == dns.dns_type.SOA ) { - answers.push( {name: packet.question.name, type: dns.dns_type.SOA, class: dns.dns_class.IN, ttl: 300, rdata: { primary: "ns1.foo.com", mailbox: "mb.nginx.com", serial: 2019102801, refresh: 1800, retry: 3600, expire: 826483, minTTL:300} } ); - } - if ( packet.question.name.endsWith("bar.com") ) { - dns_response = dns.shortcut_response(data, packet, answers); - } else { - packet.flags |= dns.dns_flags.AA | dns.dns_flags.QR; - packet.codes |= dns.dns_codes.RA; - packet.authority.push( {name: packet.question.name, type: dns.dns_type.SOA, class: dns.dns_class.IN, ttl: 300, rdata: { primary: "ns1.foo.com", mailbox: "mb.nginx.com", serial: 2019102801, refresh: 1800, retry: 3600, expire: 826483, minTTL:300} }); - packet.additional.push( {name: packet.question.name, type: dns.dns_type.NS, class: dns.dns_class.IN, ttl: 300, rdata: "ns1.foo.bar.baz" } ); - packet.additional.push( {name: packet.question.name, type: dns.dns_type.NS, class: dns.dns_class.IN, ttl: 300, rdata: "ns2.foo.bar.baz" } ); - dns_response = dns.encode_packet(packet); - } - if (s.variables.protocol == "TCP" ) { - dns_response = to_bytes( dns_response.length ) + dns_response; - } - debug(s,"Testing: Response: " + dns_response.toString('hex') ); -} diff --git a/nginx/njs.d/dns/glb.js b/nginx/njs.d/dns/glb.js deleted file mode 100644 index 416256a..0000000 --- a/nginx/njs.d/dns/glb.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - - BEGIN GLB Functions - -**/ - -import dns from "libdns.js"; -export default {get_response, get_edns_subnet, process_request}; - -// Any encoded response packets for NGINX to send back go here -var glb_res_packet = String.bytesFrom([]); - -// Client subnet gets stored in the variable if we have one -var glb_edns_subnet = String.bytesFrom([]); - -// Function for js_set to use in order to pick up the glb_res_packet above -function get_response(s) { - return glb_res_packet; -} - -// Function to get the EDNS subnet -function get_edns_subnet(s) { - return glb_edns_subnet; -} - -// Process a DNS request and generate a response packet, saving it into glb_res_packet -function process_request(s) { - s.on("upload", function(data,flags) { - s.warn( "Received: " + data.toString('hex') ); - var packet = dns.parse_packet(data); - var glb_use_edns = new Boolean(parseInt(s.variables.glb_use_edns)); - s.warn( "ID: " + packet.id ); - s.warn( "QD: " + packet.qd ); - s.warn( "AR: " + packet.ar ); - if ( packet.qd == 1 ) { - dns.parse_question(packet); - s.warn("Name: " + packet.question.name); - - // Decode additional records, most clients will send an EDNS (OPT) to increase payload size - // and for EDNS Client Subnet, Cookies, etc. - if ( packet.ar > 0 ) { - // only decode if EDNS is enabled - s.warn( "USE EDNS: " + glb_use_edns ); - if ( glb_use_edns ) { - dns.parse_complete(packet,1); - if ( "edns" in packet ) { - if ( packet.edns.opts.csubnet ) { - s.warn( "EDNS Subnet: " + packet.edns.opts.csubnet.subnet ); - glb_edns_subnet = packet.edns.opts.csubnet.subnet; - } - } - } - } - - // Check if we're doing GLB for the given name - var config = glb_get_config( packet, "", s ); - if ( ! Array.isArray(config) ) { - s.warn("Failed to get config for: " + packet.question.name ); - glb_res_packet = glb_failure(packet, dns.dns_codes.NXDOMAIN ); - s.warn( "Sending: " + glb_res_packet.toString('hex') ); - s.done(); - return; - } - - // GSLB this muther - var nodes = glb_get_nodes( packet, config, s ); - if ( ! Array.isArray(nodes) ) { - s.warn("Failed to get any nodes for: " + packet.question.name ); - glb_res_packet = glb_failure(packet, dns.dns_codes.SERVFAIL ); - s.warn( "Sending: " + glb_res_packet.toString('hex') ); - s.done(); - return; - } - - // Build an array of answers from the nodes - var answers = []; - if ( config[1] == "active" ) { - nodes.forEach( function(node) { - answers.push( {name: packet.question.name, type: dns.dns_type.A, class: dns.dns_class.IN, ttl: config[2], rdata: node} ); - }); - } else if ( config[1] == "random" ) { - var node = nodes[Math.floor(Math.random()*nodes.length)]; - answers.push( {name: packet.question.name, type: dns.dns_type.A, class: dns.dns_class.IN, ttl: config[2], rdata: node} ); - } else if ( config[1] == "geoip" ) { - var distance=99999999; - var closest = []; - var client_ip, client_lat, client_lon; - /**if ( glb_edns_subnet ) { - client_lat = s.variables.edns_latitude; - client_lon = s.variables.edns_longitude; - client_ip = glb_edns_subnet; - } else { **/ - client_lat = s.variables.geoip2_latitude; - client_lon = s.variables.geoip2_longitude; - client_ip = s.variables.geoip_source; - //} - s.warn( "Client: " + client_ip + ", Lat: " + client_lat ); - s.warn( "Client: " + client_ip + ", Lon: " + client_lon ); - for (var i=0; i< nodes.length; i++ ) { - var suffix = "_geoip_" + nodes[i].replace(/\./g, '_'); - var node_location = glb_get_config( packet, suffix, s ) - if ( ! node_location ) { - s.warn( "GEO location missing. Please add GEOIP key for node: " + nodes[i] ); - continue; - } - var nd = glb_calc_distance( client_lon, client_lat, - node_location[1], node_location[0]); - s.warn( "Distance to: " + nodes[i] + " - " + nd ); - if ( nd < distance ) { - closest = [ nodes[i] ]; - distance = nd; - } else if ( nd == distance ) { - closest.push( nodes[i] ); - } - } - closest.forEach( function(node) { - answers.push( {name: packet.question.name, type: dns.dns_type.A, class: dns.dns_class.IN, ttl: config[2], rdata: node} ); - }); - } else { - s.warn("Unknown LB Algorithm: '" + config[1] + "' for: " + packet.question.name ); - glb_res_packet = glb_failure(packet, dns.dns_codes.SERVFAIL ); - s.warn( "Sending: " + glb_res_packet.toString('hex') ); - s.done(); - return; - } - - // Shortcut - copy data from request - glb_res_packet = dns.shortcut_response(data, packet, answers); - - // The long way, decode/encode - //var response = dns.gen_response_packet( packet, packet.question, answers, [], [] ); - //glb_res_packet = dns.encode_packet( response ); - - s.warn( "Sending: " + glb_res_packet.toString('hex') ); - s.done(); - } - }); -} - -function glb_failure(packet, code) { - var failed = dns.gen_new_packet( packet.id, packet.flags, packet.codes); - failed.question = packet.question; - failed.qd = 1; - failed.codes |= code; - failed.flags |= dns.dns_flags.QR; - return dns.encode_packet( failed ); -} - -function glb_get_config( packet, suffix, s) { - var key = packet.question.name.replace(/\./g, '_') + suffix; - var uri = '/4/stream/keyvals/glb_config'; - var config; - if ( njs.version.slice(0,3) >= 0.9 ) { - // future functionality - var db = s.api( uri ); - config = db.read(key); - } else { - config = s.variables[ key ]; - } - if ( config ) { - config = config.split(','); - } - return config; -} - -function glb_get_nodes( packet, config, s ) { - var key = packet.question.name.replace(/\./g, '_'); - var uri = "/4/" + config[0] + "/upstreams/" + key; - var nodes; - if ( njs.version.slice(0,3) >= 0.9 ) { - var db = s.api( uri ); - var json = db.read(key); - nodes = glb_process_upstream_status( json, config ); - } else { - // No API, so try _nodes list - nodes = s.variables[ key + "_nodes" ]; - nodes = nodes.split(','); - } - return nodes; -} - -function glb_process_upstream_status( json, config ) { - // TODO process upstream peers - var primary = []; - var backup = []; -} - -/** - * Calculate distance between two GPS locations. - * Thanks to: https://www.barattalo.it/coding/decimal-degrees-conversion-and-distance-of-two-points-on-google-map/ -**/ -function glb_calc_distance(lat1,lon1,lat2,lon2) { - var R = 6371; // km (change this constant to get miles) - var dLat = (lat2-lat1) * Math.PI / 180; - var dLon = (lon2-lon1) * Math.PI / 180; - var a = Math.sin(dLat/2) * Math.sin(dLat/2) + - Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) * - Math.sin(dLon/2) * Math.sin(dLon/2); - var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); - var d = R * c; - if (d>1) return Math.round(d); - else if (d<=1) return Math.round(d*1000)+"m"; - return d; -} - diff --git a/nginx/njs.d/dns/libdns.js b/nginx/njs.d/dns/libdns.js deleted file mode 100644 index a555e91..0000000 --- a/nginx/njs.d/dns/libdns.js +++ /dev/null @@ -1,632 +0,0 @@ -/** - - BEGIN DNS Functions - -**/ - -export default {dns_type, dns_class, dns_flags, dns_codes, - parse_packet, parse_question, parse_answers, - parse_complete, parse_resource_record, - shortcut_response, shortcut_nxdomain, - gen_new_packet, gen_response_packet, encode_packet} - -// DNS Types -var dns_type = Object.freeze({ - A: 1, - NS: 2, - CNAME: 5, - SOA: 6, - PTR: 12, - MX: 15, - TXT: 16, - AAAA: 28, - SRV: 33, - OPT: 41, - AXFR: 252, - value: { 1:"A", 2:"NS", 5:"CNAME", 6:"SOA", 12:"PTR", 15:"MX", 16:"TXT", - 28:"AAAA", 33:"SRV", 41:"OPT", 252:"AXFR" } -}); - -// DNS Classes -var dns_class = Object.freeze({ - IN: 1, - CS: 2, - CH: 3, - HS: 4, - value: { 1:"IN", 2:"CS", 3:"CH", 4:"HS" } -}); - -// DNS flags (made up of QR, Opcode (4bits), AA, TrunCation, Recursion Desired) -var dns_flags = Object.freeze({ - QR: 0x80, - AA: 0x4, - TC: 0x2, - RD: 0x1 -}); - -// DNS Codes (made up of RA (Recursion Available), Zero (3bits), Response Code (4bits)) -var dns_codes = Object.freeze({ - RA: 0x80, - Z: 0x70, - //RCODE: 0xf, - NOERROR: 0x0, - FORMERR: 0x1, - SERVFAIL: 0x2, - NXDOMAIN: 0x3, - NOTIMPL: 0x4, - REFUSED: 0x5, - value: { 0x80:"RA", 0x70:"Z", 0x0:"NOERROR", 0x1:"FORMERR", 0x2:"SERVFAIL", 0x3:"NXDOMAIN", 0x4:"NOTIMPL", 0x5:"REFUSED" } -}); - -// Convert two bytes in a packet to a 16bit int -function to_int(A, B) { - return (((A & 0xFF) << 8) | (B & 0xFF)); -} - -// Convert four bytes in a packet to a 32bit int -function to_int32(A, B, C, D) { - return ( ((A & 0xFF) << 24) | ((B & 0xFF) << 16) | ((C & 0xFF) << 8) | (D & 0xFF) ); -} - -// Encode the given number to two bytes (16 bit) -function to_bytes( number ) { - return String.fromCodePoint( ((number>>8) & 0xff), (number & 0xff) ).toBytes(); -} - -// Encode the given number to 4 bytes (32 bit) -function to_bytes32( number ) { - return String.fromCodePoint( (number>>24)&0xff, (number>>16)&0xff, (number>>8)&0xff, number&0xff ).toBytes(); -} - -// Create a new empty DNS packet structure -function gen_new_packet(id, flags, codes) { - var dns_packet = { id: id, flags: flags, codes: codes, qd: 0, an: 0, ns: 0, ar: 0, - question: {}, - answers: [], - authority: [], - additional: [] - }; - return dns_packet; -} - -/** Create a new response packet suitable as a reply to the given request - * You should also supply some answers, authority and/or additional records - * in arrays to populate the various sections. -**/ -function gen_response_packet( request, question, answers, authority, additional ) { - var response = gen_new_packet(request.id, request.flags, request.codes); - response.flags |= dns_flags.AA + dns_flags.QR; - response.codes |= dns_codes.RA; - if ( question == null ) { - response.qd = 0; - } else { - response.qd = 1; - response.question = request.question; - } - answers.forEach( function(answer) { - response.an++; - response.answers.push( answer ); - }); - return response; -} - -/** Encode the provided packet, converting it from the javascript object structure into a bytestring - * Returns a bytestring suitable for dropping into a UDP packet, or returning to NGINX -**/ -function encode_packet( packet ) { - var encoded = to_bytes( packet.id ); - encoded += String.fromCodePoint( packet.flags ).toBytes(); - encoded += String.fromCodePoint( packet.codes ).toBytes(); - encoded += to_bytes( packet.qd ); // Questions - encoded += to_bytes( packet.answers.length ); // Answers - encoded += to_bytes( packet.authority.length ); // Authority - encoded += to_bytes( packet.additional.length ); // Additional - encoded += encode_question(packet); - packet.answers.forEach( function(answer) { - encoded += gen_resource_record(packet, answer.name, answer.type, answer.class, answer.ttl, answer.rdata); - }); - packet.authority.forEach( function(rec) { - encoded += gen_resource_record(packet, rec.name, rec.type, rec.class, rec.ttl, rec.rdata); - }); - packet.additional.forEach( function(rec) { - encoded += gen_resource_record(packet, rec.name, rec.type, rec.class, rec.ttl, rec.rdata); - }); - return encoded; -} - -/** Don't mess about. This is a shortcut for responding to DNS Queries. We copy the question out of the query - * and cannibalise the original request to generate our response. -**/ -function shortcut_response(data, packet, answers) { - var response = String.bytesFrom([]); - response += data.slice(0, 2); - response += String.fromCodePoint( packet.flags |= dns_flags.AA | dns_flags.QR ).toBytes(); - response += String.fromCodePoint( packet.codes |= dns_codes.RA ).toBytes(); - response += to_bytes( 1 ); // Questions - response += to_bytes( answers.length ); // Answers - response += to_bytes( 0 ); // Authority - response += to_bytes( 0 ); // Additional - response += data.slice(12, packet.question.qend ); - answers.forEach( function(answer) { - response += gen_resource_record(packet, answer.name, answer.type, answer.class, answer.ttl, answer.rdata); - }); - return response; -} - -function shortcut_nxdomain(data, packet) { - var response = String.bytesFrom([]); - response += data.slice(0,2); - response += String.fromCodePoint( packet.flags |= dns_flags.AA | dns_flags.QR ).toBytes(); - response += String.fromCodePoint( packet.codes |= dns_codes.NXDOMAIN | dns_codes.RA ).toBytes(); - response += to_bytes( 1 ); // Questions - response += to_bytes( 0 ); // Answers - response += to_bytes( 0 ); // Authority - response += to_bytes( 0 ); // Additional - response += data.slice(12, packet.question.qend ); - return response; -} - -/** Encode a question object into a bytestring suitable for use in a UDP packet -**/ -function encode_question(packet) { - var encoded = encode_label(packet.question.name); - encoded += to_bytes(packet.question.type); - encoded += to_bytes(packet.question.class); - return encoded; -} - -/** - * Parse an incoming request bytestring into a DNS packet object. This function decodes the first 12 bytes of the headers. - * You will probably want to call parse_question() next. -**/ -function parse_packet(data) { - var packet = { id: to_int(data.codePointAt(0), data.codePointAt(1)), flags: data.codePointAt(2), codes: data.codePointAt(3), min_ttl: 2147483647, - qd: to_int(data.codePointAt(4), data.codePointAt(5)), an: to_int(data.codePointAt(6), data.codePointAt(7)), ns: to_int(data.codePointAt(8), data.codePointAt(9)), - ar: to_int(data.codePointAt(10), data.codePointAt(11)), data: data.slice(12), question: [], answers:[], authority: [], additional: [], offset: 0 }; - return packet; -} - -/** - * Parse the question section of a DNS request packet, adds the QNAME, QTYPE, and QCLASS to the packet object, and stores the - * offset in the packet for processing any further sections. -**/ -function parse_question(packet) { - - /** QNAME, QTYPE, QCLASS **/ - - var name = parse_label(packet); - packet.question = { name: name, type: to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)), - class: to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)), qend: packet.offset + 12 }; - if ( packet.qd != 1 ) { - return false; - } - return true; -} - -function parse_answers(packet, decode_level) { - - // Process the question section if necessary - if ( packet.question.length == 0 ) { - parse_question(packet); - } - - // Process answers - if ( packet.an > 0 && packet.answers.length == 0 ) { - packet.answers = parse_section(packet, packet.an, decode_level); - } - - // If we didn't have any ttls in the packet, then cache for 5 minutes. - if (packet.min_ttl == 2147483647) { - packet.min_ttl = 300; - } - -} - - -// Parse all sections of the packet -function parse_complete(packet, decode_level) { - - // Process the question section if necessary - if ( packet.question.length == 0 ) { - parse_question(packet); - } - - // Process answers - if ( packet.an > 0 && packet.answers.length == 0 ) { - packet.answers = parse_section(packet, packet.an, decode_level); - } - - // Process authority - if ( packet.ns > 0 && packet.authority.length == 0) { - packet.authority = parse_section(packet, packet.ns, decode_level); - } - - // Process Additional - if ( packet.ar > 0 && packet.additional.length == 0) { - packet.additional = parse_section(packet, packet.ar, decode_level); - } - - // If we didn't have any ttls in the packet, then cache for 5 minutes. - if (packet.min_ttl == 2147483647) { - packet.min_ttl = 300; - } - -} - -function parse_section(packet, recs, decode_level) { - var rrs = []; - for (var i=0; i 63 ) { - // Invalid DNS name, individual labels are limited to 63 bytes. - //s.warn("DNS Error - parse_label encountered invaliad DNS name"); - break; - } else { - name += packet.data.slice(++pos, pos+length) + "."; - pos += length; - } - } - - if ( ! compressed ) { - packet.offset = pos - } - - name = name.slice(0,-1); - return name; -} - -/** TODO Check sizes on resources/packets -labels 63 octets or less -names 255 octets or less -TTL positive values of a signed 32 bit number. -UDP messages 512 octets or less -**/ - -function encode_label( name ) { - - var data = String.bytesFrom([]); - name.split('.').forEach( function(part){ - data += String.fromCodePoint(part.length); - data += part; - }); - data += String.fromCodePoint(0); - return data; - -} - -function gen_resource_record(packet, name, type, clss, ttl, rdata) { - - /** - NAME - TYPE (2 octets) - CLASS (2 octects) - TTL 32bit signed int - RDLength 16bit int length of RDATA - RDATA variable length string - **/ - - var resource = ""; - var record = ""; - - if ( name == packet.question.name ) { - // The name matches the query, set a compression pointer. - resource += String.fromCodePoint(192, 12).toBytes(); - } else { - // gen labels for the name - resource += encode_label(name); - } - - resource += String.fromCodePoint(type & 0xff00, type & 0xff); - switch(type) { - case dns_type.A: - record = encode_arpa_v4(rdata); - break; - case dns_type.AAAA: - record = encode_arpa_v6(rdata); - break; - case dns_type.NS: - record = encode_label(rdata); - break; - case dns_type.CNAME: - record = encode_label(rdata); - break; - case dns_type.SOA: - record = encode_soa_record(rdata); - break; - case dns_type.SRV: - record = encode_srv_record(rdata); - break; - case dns_type.MX: - record = encode_mx_record(rdata); - break; - case dns_type.TXT: - record = encode_txt_record(rdata); - break; - default: - //TODO Barf - } - - switch(clss) { - case dns_class.IN: - resource += String.fromCodePoint(0,1).toBytes(); - break; - default: - //TODO Barf - resource += String.fromCodePoint(99,99).toBytes(); - } - - resource += to_bytes32(ttl); - resource += to_bytes( record.length ); - resource += record; - return resource; -} - -// Process resource records, to a varying depth dictated by decode_level -// decode_level {0: name+type, 1: name+type+class+ttl, 2: everything} -function parse_resource_record(packet, decode_level) { - - /** - NAME - TYPE (2 octets) - CLASS (2 octects) - TTL 32bit signed int - RDLength 16bit int length of RDATA - RDATA variable length string - **/ - - var resource = {} - resource.name = parse_label(packet); - resource.type = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - - if ( decode_level > 0 ) { - if (resource.type == dns_type.OPT ) { - // EDNS - parse_edns_options(packet); - } else { - resource.class = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - resource.ttl = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - resource.rdlength = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - if ( decode_level == 1 ) { - resource.data = packet.data.slice(packet.offset, packet.offset + resource.rdlength); - packet.offset += resource.rdlength; - } else { - switch(resource.type) { - case dns_type.A: - resource.data = parse_arpa_v4(packet, resource); - break; - case dns_type.AAAA: - resource.data = parse_arpa_v6(packet, resource); - break; - case dns_type.NS: - resource.data = parse_label(packet); - break; - case dns_type.CNAME: - resource.data = parse_label(packet); - break; - case dns_type.SOA: - resource.data = parse_soa_record(packet); - break; - case dns_type.SRV: - resource.data = parse_srv_record(packet); - break; - case dns_type.MX: - resource.data = parse_mx_record(packet); - break; - case dns_type.TXT: - resource.data = parse_txt_record(packet, resource.rdlength); - break; - default: - resource.data = packet.data.slice(packet.offset, packet.offset + resource.rdlength); - packet.offset += resource.rdlength; - } - } - } - } - return resource; -} - -function encode_arpa_v4( ipv4 ) { - var rdata = ""; - ipv4.split('\.').forEach( function(octet) { - rdata += String.fromCodePoint( octet ).toBytes(); - }); - return rdata; -} - -function parse_arpa_v4(packet) { - var octet = [0,0,0,0]; - for (var i=0; i< 4 ; i++ ) { - octet[i] = packet.data.codePointAt(packet.offset++); - } - return octet.join("."); -} - -function encode_arpa_v6( ipv6 ) { - var rdata = ""; - ipv6.split(':').forEach( function(segment) { - rdata += String.bytesFrom(segment[0] + segment[1], 'hex'); - rdata += String.bytesFrom(segment[2] + segment[3], 'hex'); - }); - return rdata; -} - -function parse_arpa_v6(packet) { - var ipv6 = ""; - for (var i=0; i<8; i++ ) { - var a = packet.data.charCodeAt(packet.offset++).toString(16); - var b = packet.data.charCodeAt(packet.offset++).toString(16); - ipv6 += a + b + ":"; - } - return ipv6.slice(0,-1); -} - -function encode_txt_record( text_array ) { - var rdata = String.bytesFrom([]); - text_array.forEach( function(text) { - var tl = text.length; - if ( tl > 255 ) { - for (var i=0 ; i < tl ; i++ ) { - var len = (tl > (i+255)) ? 255 : tl - i; - rdata += String.fromCodePoint(len).toBytes(); - rdata += text.slice(i,i+len); - i += len; - } - } else { - rdata += String.fromCodePoint(tl).toBytes(); - rdata += text; - } - }); - return rdata; -} - -function parse_txt_record(packet, length) { - var txt = []; - var pos = 0; - while ( pos < length ) { - var tl = packet.data.codePointAt(packet.offset++); - txt.push( packet.data.slice(packet.offset, packet.offset + tl)); - pos += tl + 1; - packet.offset += tl; - } - return txt; -} - -function encode_mx_record( mx ) { - var rdata = String.bytesFrom([]); - rdata += to_bytes( mx.priority ); - rdata += encode_label( mx.exchange ); - return rdata; -} - -function parse_mx_record(packet) { - var mx = {}; - mx.priority = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - mx.exchange = parse_label(packet); - return mx; -} - -function encode_srv_record( srv ) { - var rdata = String.bytesFrom([]); - rdata += to_bytes( srv.priority ); - rdata += to_bytes( srv.weight ); - rdata += to_bytes( srv.port ); - rdata += encode_label( srv.target ); - return rdata; -} - -function parse_srv_record(packet) { - var srv = {}; - srv.priority = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - srv.weight = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - srv.port = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - srv.target = parse_label(packet); - return srv; -} - -function encode_soa_record( soa ) { - var rdata = String.bytesFrom([]); - rdata += encode_label(soa.primary); - rdata += encode_label(soa.mailbox); - rdata += to_bytes32(soa.serial); - rdata += to_bytes32(soa.refresh); - rdata += to_bytes32(soa.retry); - rdata += to_bytes32(soa.expire); - rdata += to_bytes32(soa.minTTL); - return rdata; -} - -function parse_soa_record(packet) { - var soa = {}; - soa.primary = parse_label(packet); - soa.mailbox = parse_label(packet); - soa.serial = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - soa.refresh = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - soa.retry = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - soa.expire = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - soa.minTTL = to_int32(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++), - packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - return soa; -} - -function parse_edns_options(packet) { - - packet.edns = {} - packet.edns.opts = {} - packet.edns.size = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - packet.edns.rcode = packet.data.codePointAt(packet.offset++); - packet.edns.version = packet.data.codePointAt(packet.offset++); - packet.edns.z = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - packet.edns.rdlength = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - - var end = packet.offset + packet.edns.rdlength; - for ( ; packet.offset < end ; ) { - var opcode = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - var oplength = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - if ( opcode == 8 ) { - //client subnet - packet.edns.opts.csubnet = {} - packet.edns.opts.csubnet.family = to_int(packet.data.codePointAt(packet.offset++), packet.data.codePointAt(packet.offset++)); - packet.edns.opts.csubnet.netmask = packet.data.codePointAt(packet.offset++); - packet.edns.opts.csubnet.scope = packet.data.codePointAt(packet.offset++); - if ( packet.edns.opts.csubnet.family == 1 ) { - // IPv4 - var octet = [0,0,0,0]; - for (var i=4; i< oplength ; i++ ) { - octet[i-4] = packet.data.codePointAt(packet.offset++); - } - packet.edns.opts.csubnet.subnet = octet.join("."); - break; - } else { - // We don't support IPv6 yet. - packet.edns.opts = {} - break; - } - } else { - // We only look for CSUBNET... Not interested in anything else at this time. - packet.offset += oplength; - } - } - -} - - diff --git a/nginx/njs.d/nginx_stream.js b/nginx/njs.d/nginx_stream.js deleted file mode 100644 index b181dbc..0000000 --- a/nginx/njs.d/nginx_stream.js +++ /dev/null @@ -1,54 +0,0 @@ - -import glb from './dns/glb.js'; -import dns from './dns/dns.js'; - -/** - * GLB Functions -**/ - -// GLB return the response packet to js_set -function glb_get_response(s) { - return glb.get_response(s); -} - -// GLB setup the on(upload) callback to process DNS packets -function glb_process_request(s) { - return glb.process_request(s); -} - -// GLB return the EDNS subnet to the js_set call for GEOIP2 -function glb_get_edns_subnet(s) { - return glb.get_edns_subnet(s); -} - -/** - * DNS Functions -**/ - -// DNS over HTTPS gateway - use as js_filter -function dns_filter_doh_request(s) { - return dns.filter_doh_request(s); -} - -function dns_preread_doh_request(s) { - return dns.preread_doh_request(s); -} - -function dns_preread_dns_request(s) { - return dns.preread_dns_request(s); -} - -// Return the DNS Question -function dns_get_qname(s) { - return dns.get_qname(s); -} - -// return the DNS Response, if we want to override (block) the domain -function dns_get_response(s) { - return dns.get_response(s); -} - -//function dns_filter_udp_request(s) { -// return dns.filter_udp_request(s); -//} - diff --git a/nginx/stream.d/dot.conf b/nginx/stream.d/dot.conf index b7549d0..92e110d 100644 --- a/nginx/stream.d/dot.conf +++ b/nginx/stream.d/dot.conf @@ -1,155 +1,16 @@ -# server { -# listen 853 ssl; - -# # ssl_certificate ${cert_path}; -# # ssl_certificate_key ${key_path}; - -# # ssl_protocols TLSv1.2 TLSv1.3; -# # ssl_ciphers HIGH:!aNULL:!MD5; -# # ssl_prefer_server_ciphers on; - -# # ssl_handshake_timeout 10s; -# # ssl_session_cache shared:SSL:20m; -# # ssl_session_timeout 4h; -# ssl_certificate ${cert_path}; -# ssl_certificate_key ${key_path}; -# # ssl_dhparam ${dhparam_path}; -# # ssl_protocols TLSv1.2 TLSv1.3; # TLS 1.3 requires nginx >= 1.13.0 -# # ssl_prefer_server_ciphers on; -# # ssl_ciphers EECDH+AESGCM:EDH+AESGCM; -# # ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0 -# # ssl_session_timeout 10m; -# # ssl_session_cache shared:SSLDOT:10m; -# # ssl_session_tickets off; # Requires nginx >= 1.5.9 -# # ssl_stapling on; # Requires nginx >= 1.3.7 -# # ssl_stapling_verify on; # Requires nginx => 1.3.7 -# # ssl_early_data off; # 0-RTT, enable if desired - Requires nginx >= 1.15.4 -# # resolver 1.1.1.1 valid=300s; # Replace with your local resolver -# # resolver_timeout 5s; - -# proxy_pass dns-servers; -# } - - - # KeyValue store for blocking domains (NGINX Plus only) - # keyval_zone zone=dns_config:64k state=/etc/nginx/zones/dns_config.zone; - # keyval "blocked_domains" $blocked_domains zone=dns_config; - # keyval "blackhole_domains" $blackhole_domains zone=dns_config; - # keyval $dns_qname $scrub_action zone=dns_config; - - # DNS logging - # log_format dns '$remote_addr [$time_local] $protocol "$dns_qname" "$upstream_pool"'; - # access_log /var/log/nginx/dns-access.log dns; - - # Import the NJS DNS module - # js_import /etc/nginx/njs.d/dns/dns.js; - - # # The $dns_qname variable can be populated by preread calls, and can be used for DNS routing - # js_set $dns_qname dns.get_qname; - - # # The DNS response packet, if we're blocking the domain, this will be set. - # js_set $dns_response dns.get_response; - - -# upstream tariq-dns { -# zone dns 64k; -# server 127.0.0.1:53; -# } -# upstream tariq-dot { -# zone dns 64k; -# server 127.0.0.1:853; -# } - - - # # upstream pool for blocked requests - # upstream blocked { - # zone blocked 64k; - # server 127.0.0.1:9953; - # } - - # upstream blackhole { - # zone blackhole 64k; - # server 127.0.0.1:9853; - # } - - # # upstream pools (google DNS) - # upstream google { - # zone dns 64k; - # server 127.0.0.1:53; - # } - - # # upstream pools (another DNS) - # upstream dnsmasq { - # zone dns 64k; - # server 192.168.64.1:5353; - # } - - # DNS upstream pool. - upstream dns { - zone dns 64k; - server tariq:53; - } - - # DNS over TLS upstream pool - upstream dot { - zone dot 64k; - server 127.0.0.1:853; - } - # # When doing DNS routing, use $dns_qname to map the questions to the upstream pools. - # map $dns_qname $upstream { - # # hostnames; - # # *.nginx dnsmasq; - # # *.k8s dnsmasq; - # default dns; - # } - - # # Set upstream to be the pool defined above if dns_response is empty, else pass to the @block location - # map $dns_response $upstream_pool { - # # "blocked" blocked; - # # "blackhole" blackhole; - # default $upstream; - # } - - - # DNS(TCP) and DNS over TLS (DoT) Server - # Upstream can be either DNS(TCP) or DoT. If upstream is DNS, proxy_ssl should be off. - server { - listen 553; - listen 853 ssl; - ssl_certificate /ssl/cert.pem; - ssl_certificate_key /ssl/key.pem; - # js_preread dns.preread_dns_request; - #proxy_ssl on; - proxy_pass dns; - } - - # DNS(UDP) Server - # Upstream can only be another DNS(UDP) server. - # server { - # listen 553 udp; - # js_preread dns.preread_dns_request; - # proxy_responses 1; - # proxy_pass dns; - # } - - # # DNS over HTTPS (gateway) Service - # # Upstream can be either DNS(TCP) or DoT. If upstream is DNS, proxy_ssl should be off. - # server { - # listen 127.0.0.1:8053; - # js_filter dns.filter_doh_request; - # proxy_ssl on; - # proxy_pass dot; - # } - - # # Server for sending blackhole/blocked responses - # server { - # listen 127.0.0.1:9953; - # listen 127.0.0.1:9853; - # listen 127.0.0.1:9953 udp; - # listen 127.0.0.1:9853 udp; - # js_preread dns.preread_dns_request; - # return dns; - # } - - +# DNS upstream pool. +upstream dns { + zone dns 64k; + server tariq:53; +} + +server { + listen 553; + listen 853 ssl; + ssl_certificate /ssl/cert.pem; + ssl_certificate_key /ssl/key.pem; + # js_preread dns.preread_dns_request; + #proxy_ssl on; + proxy_pass dns; +}