From 273193cd15b5447cc377ab0ced8549a276aad38b Mon Sep 17 00:00:00 2001 From: Seth Ornstein Date: Wed, 7 Jun 2017 15:20:18 -0400 Subject: [PATCH] documentation of new lua commands, stripped down dnsdist.conf, improved example script in pdns/zzz-gca-example directory --- zzz-gca-example/build-dnsdist2.sh | 47 +++ zzz-gca-example/dig-test-nocookie.sh | 4 + zzz-gca-example/dig-test-rpz.sh | 4 + .../dnsdist-Lua additions-June_7_2017.abw | 212 ++++++++++ .../dnsdist-Lua additions-June_7_2017.pdf | Bin 0 -> 62627 bytes zzz-gca-example/dnsdist-check-config.sh | 17 + zzz-gca-example/dnsdist-debug.conf | 378 ++++++++++++++++++ zzz-gca-example/dnsdist.conf | 252 ++++++++++++ zzz-gca-example/dnsdist2-debug.sh | 19 + zzz-gca-example/dnsdist2.sh | 19 + zzz-gca-example/make-dnsdist2.sh | 5 + zzz-gca-example/protobuf-server2.sh | 14 + 12 files changed, 971 insertions(+) create mode 100755 zzz-gca-example/build-dnsdist2.sh create mode 100755 zzz-gca-example/dig-test-nocookie.sh create mode 100755 zzz-gca-example/dig-test-rpz.sh create mode 100644 zzz-gca-example/dnsdist-Lua additions-June_7_2017.abw create mode 100644 zzz-gca-example/dnsdist-Lua additions-June_7_2017.pdf create mode 100755 zzz-gca-example/dnsdist-check-config.sh create mode 100644 zzz-gca-example/dnsdist-debug.conf create mode 100644 zzz-gca-example/dnsdist.conf create mode 100755 zzz-gca-example/dnsdist2-debug.sh create mode 100755 zzz-gca-example/dnsdist2.sh create mode 100755 zzz-gca-example/make-dnsdist2.sh create mode 100755 zzz-gca-example/protobuf-server2.sh diff --git a/zzz-gca-example/build-dnsdist2.sh b/zzz-gca-example/build-dnsdist2.sh new file mode 100755 index 000000000..279b530da --- /dev/null +++ b/zzz-gca-example/build-dnsdist2.sh @@ -0,0 +1,47 @@ +#!/bin/bash -e +echo "" +echo "from: http://dnsdist.org/download/" +echo "" +echo "clone from: git clone https://github.com/PowerDNS/pdns.git" +echo "--or from our copy--" +echo "https://github.com/GlobalCyberAlliance/pdns.git" +echo "" + +echo "cd ../pdns/dnsdistdist" +echo "" +cd ../pdns/dnsdistdist +echo "" +echo "autoreconf -i" +echo "" +autoreconf -i +echo "" +echo "NOTE: configure with libsodium enabled to allow cache test to succeed - Seth - Global Cyber Alliance" +echo "./configure --enable-libsodium" +./configure --enable-libsodium +echo "" +echo "do a \"make clean\" incase this is not the first time through" +echo "" +make clean +echo "" +echo "now do a make" +echo "" +echo "make" +echo "" +make +echo "" +echo "test out the cache code" +echo "" +cd "../../regression-tests.dnsdist" +echo "" +echo "test_Caching" +DNSDISTBIN=../pdns/dnsdistdist/dnsdist ./runtests test_Caching +echo "" +echo "test_CacheHitResponses" +DNSDISTBIN=../pdns/dnsdistdist/dnsdist ./runtests test_CacheHitResponses +echo "" +echo "you can now do \"make install\" if desired." +echo "" +echo "finished" + + + diff --git a/zzz-gca-example/dig-test-nocookie.sh b/zzz-gca-example/dig-test-nocookie.sh new file mode 100755 index 000000000..b5f88fae7 --- /dev/null +++ b/zzz-gca-example/dig-test-nocookie.sh @@ -0,0 +1,4 @@ +echo "test dnsdist with nocookie option to allow cache hits" +echo "dig @127.0.0.1 -p 5200 +nocookie google.com" +echo "" +dig @127.0.0.1 -p 5200 +nocookie google.com diff --git a/zzz-gca-example/dig-test-rpz.sh b/zzz-gca-example/dig-test-rpz.sh new file mode 100755 index 000000000..0c1188b5d --- /dev/null +++ b/zzz-gca-example/dig-test-rpz.sh @@ -0,0 +1,4 @@ +echo "test dnsdist with rpz bad entry" +echo "dig @127.0.0.1 -p 5200 1jw2mr4fmky.net" +echo "" +dig @127.0.0.1 -p 5200 1jw2mr4fmky.net diff --git a/zzz-gca-example/dnsdist-Lua additions-June_7_2017.abw b/zzz-gca-example/dnsdist-Lua additions-June_7_2017.abw new file mode 100644 index 000000000..6ddc68ed7 --- /dev/null +++ b/zzz-gca-example/dnsdist-Lua additions-June_7_2017.abw @@ -0,0 +1,212 @@ + + + + + + + + + + + +Wed Jun 7 15:14:33 2017 + +AbiWord +SethO +Wed Jun 7 11:06:40 2017 + +application/x-abiword + + + + + + + + + + +
+

Proposed new Lua commands for DNSDIST

+

June 7, 2017

+

Seth Ornstein

+

Global Cyber Alliance

+

sornstein@globalcyberalliance.org

+

+

+

To obtain a copy of the source for the modified DNSDIST version:

+

+

git clone -b dnsdist-mod2 https://github.com/GlobalCyberAlliance/pdns.git

+

+

Example scripts and configuration file are located in: pdns/zzz-gca-examples

+

+

+

Lua additional functions that act on the DNSQuestion parameter dq.

+

+

They are expected to be used inside of a Lua function that is setup for use in the dnsdist configuration file by the addLuaAction function. They are used to store text label and value pairs in the DNSQuestion dq and accessed by the DNSResponse Lua functions below.

+

+

To store a text label and value pair in the DNSQuestion:

+

+

dq:setTag(“LabelText”, “ValueText”)

+

+

To store values as a table in the DNSQuestion structure:

+

+

dq:setTagArray(exampleTable)

+

+

+

Lua additional functions that act on the DNSResponse parameter dr.

+

+

These are expected to be located inside of a Lua function that is setup for use in the dnsdist configuration file by the RemoteLogAction function as the “alterFunction”. They are used to obtain the text label and value pairs that were stored in the DNSQuestion Lua functions above.

+

+

To read matching value from DNSQuestion structure:

+

+

dr:getTagMatch(“LabelText”)

+

+

To read text values as an array from DNSQuestion structure:

+

+

dr:getTagArray()

+

+

+

+

+

+

+

+

Lua additional functions that act on the DNSDistProtoBufMessage parameter pbMsg.

+

+

These are expected to be located inside of a Lua function that is setup for use in the dnsdist configuration file by the RemoteLogAction function as the “alterFunction”. They are used to modify the protobuf message that is being sent to the protobuf server.

+

+

To store text values in the protobuf “tags” field:

+

+

pbMsg:setTag(“LabelText”, “ValueText”)

+

+

To store text values as a table in protobuf tag fields

+

+

pbMsg:setTagArray(exampleTable)

+

+

+

To change the protobuf message from a ‘query’ to a ‘response’.

+

The variable is the dns name the client requested to be looked up.

+

A zero is inserted in the ‘query time’ protobuf field.

+

+

pbMsg:setProtobufResponseType(“example.com”)

+

+

+

To change the protobuf message from a ‘query’ to a ‘response’ and set ‘query time’.

+

The variable is the dns name the client requested to be looked up.

+

The second variable is the query time in seconds.

+

The third variable is the fractional micro-seconds.

+

+

pbMsg:setProtobufResponseTypeQT(“example.com”, os.time(), 123456)

+

+

Building the modified dnsdist with the new Lua functions:

+

+

1. Open a console in pdns/zzz-gca-examples and run ./build-dnsdist2.sh

+

This builds dnsdist with libsodium enabled for cache testing.

+

+

+

Running the test scripts:

+

+

1. Open a console in pdns/zzz-gca-examples and run ./protobuf-server2.sh

+

+

2. Open a console in pdns/zzz-gca-examples and run ./dnsdist2.sh

+

+

3. Open a console in pdns/zzz-gca-examples and run ./dig-test-rpz.sh

+

+

4. Verify that the protobuf server console shows a response with tags indicating RPZ.

+

+

5. Open a console in pdns/zzz-gca-examples and run ./dig-test-nocookie.sh

+

+

6. Verify that the protobuf server console shows a response with tags indicating FWD.

+

+

7. Run ./dig-test-nocookie.sh a second time.

+

+

8. Verify that the protobuf server console shows a response with tags indicating CACHE.

+

+

+

+

+

+

Protobuf server sample output:

+

+

Note that the unused “Tags” protobuf field now has the entries passed by the pbMsg:setTag and pbMsg:setTagArray functions. The tag data is separated by commas and the order is label followed by value for each ‘Tag’ in the protobuf ‘Tags’ field. The values in the protobuf ‘Tags’ field were set by the pbMsg:setTagArray function in luaLogBL in dnsdist.conf

+

+

+

Typical response from the protobuf server from a RPZ ‘hit’ :

+

+

Note that since this protobuf was originally a ‘query’ and not a ‘response’ due to dnsdist’s treatment of returning a NXDOMAIN response to the client without having examined the cache or forwarded the request to a DNS server. Also since the function pbMsg:setProtobufResponseType was used the ‘Query time’ field has the zero time.

+

+

[2017-06-07 12:11:45.745800] Response of size 56: 127.0.0.1 -> 127.0.0.1 (UDP), id: 15891, uuid: dc7c809436b74bc48b7dc07b49f3831d

+

- Question: 1, 1, 1jw2mr4fmky.net.

+

- Query time: 1969-12-31 19:00:00.0

+

- Response Code: 3, RRs: 1, Tags: lua-time,12:11:45-06/07/17,Test1,One Two Three,lua-ver,Lua 5.1,Test2,Four Five Six,Trans,RPZ,RPZ-Info,reject-example,From,127.0.0.1:56144,TCP,false

+

- 1, 1, 1jw2mr4fmky.net., 123, 127.0.0.1

+

+

+

Typical response from the protobuf server from a forwarded message:

+

+

Note that the protobuf ‘Tags’ field has the label ‘Trans’ and the value ‘FWD’, which was set using the pbMsg:setTagArray function in luaLogForward in dnsdist.conf.

+

+

[2017-06-07 12:12:50.409444] Response of size 87: 127.0.0.1 -> 127.0.0.1 (UDP), id: 52616, uuid: 3ec48935be3846609cc175136693608f

+

- Question: 1, 1, google.com.

+

- Query time: 2017-06-07 12:12:50.390094

+

- Response Code: 0, RRs: 3, Tags: Trans,FWD

+

- 1, 1, google.com., 299, 216.58.217.78

+

- 1, 1, google.com., 299, 216.58.217.78

+

- 1, 1, google.com., 299, 216.58.217.78

+

+

+

Typical response from the protobuf server from a cache message:

+

+

Note that the protobuf ‘Tags’ field has the label ‘Trans’ and the value ‘CACHE’, which was set using the pbMsg:setTagArray function in luaLogForward in dnsdist.conf.

+

+

[2017-06-07 12:12:55.598121] Response of size 87: 127.0.0.1 -> 127.0.0.1 (UDP), id: 29215, uuid: d16852328b394d49ac0519fd7a2b6a25

+

- Question: 1, 1, google.com.

+

- Query time: 2017-06-07 12:12:55.598087

+

- Response Code: 0, RRs: 3, Tags: Trans,CACHE

+

- 1, 1, google.com., 294, 216.58.217.78

+

- 1, 1, google.com., 294, 216.58.217.78

+

- 1, 1, google.com., 294, 216.58.217.78

+

+

+

+

Additional scripts:

+

+

make-dnsdist.sh - make script for dnsdist

+

+

dnsdist-check-config.sh - quick checking of dnsdist.conf configuration file.

+

+

dnsdist2-debug.sh - run dnsdist with configuration file with debugging statements.

+

+

dnsdist-debug.conf - configuration file for use with dnsdist2-debug.sh

+

Note that you need to set lines 20 to 25 to true to enable the text debugging.

+

+

+

Source code files modified in DNSDIST:

+

+

+

dnsdist-lua.cc

+

+

dnsdist-lua2.cc

+

+

dnsdist.hh

+

+

protobuf.cc

+

+

protobuf.hh

+

+

+

To locate the modified source code search for the words Seth or GCA

+

+

ie. grep -i Seth * or grep -i GCA *

+

+

+

+

+

+

+
+
+

+
+
diff --git a/zzz-gca-example/dnsdist-Lua additions-June_7_2017.pdf b/zzz-gca-example/dnsdist-Lua additions-June_7_2017.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fa63dbf1f33a5682539ba59399e47bd048c5977d GIT binary patch literal 62627 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�dri(e8!$@2?C_}H)_WvD)g#! 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 literal 0 HcmV?d00001 diff --git a/zzz-gca-example/dnsdist-check-config.sh b/zzz-gca-example/dnsdist-check-config.sh new file mode 100755 index 000000000..f33fbe9b9 --- /dev/null +++ b/zzz-gca-example/dnsdist-check-config.sh @@ -0,0 +1,17 @@ +echo "dnsdist-check-config.sh - check dnsdist config file" +echo "" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SLASH="/" +CFG_FILE="dnsdist.conf" +CONFIG_FILE=$DIR$SLASH$CFG_FILE +echo "current directory: " $DIR +echo "" +echo "configuration file: " $CONFIG_FILE +echo "" +echo "cd ../pdns/dnsdistdist" +echo "" +cd ../pdns/dnsdistdist +echo "" +./dnsdist --config=$CONFIG_FILE --check-config +echo "" + diff --git a/zzz-gca-example/dnsdist-debug.conf b/zzz-gca-example/dnsdist-debug.conf new file mode 100644 index 000000000..a4bfe800b --- /dev/null +++ b/zzz-gca-example/dnsdist-debug.conf @@ -0,0 +1,378 @@ +-- ----------------------------------------------------------------------------------------------- +-- dnsdist2.conf +-- Seth Ornstein - sornstein@globalcyberalliance.org +-- 6/7/2017 +-- for use in testing out new Lua commands for dnsdist +-- git clone -b dnsdist-mod2 https://github.com/GlobalCyberAlliance/pdns.git +-- ----------------------------------------------------------------------------------------------- + + warnlog(string.format("Script starting ----------------- %s ", "dnsdist2.conf")) + + warnlog(string.format("Script starting ----------------- %s ", os.date("%X-%x"))) + + warnlog(string.format("Script starting ----------------- Lua Version: %s - (should be 5.1)", _VERSION)) + + + + strTestDns1 = "1jw2mr4fmky.net" -- test #1 dns lookup name - (reject) + + maintCounter = 0 -- maintainance counter + + bDebugCheckBL = false -- true if debugging luaCheckBL + bDebugLogBL = false -- true if debugging luaLogBL + bDebugLogForward = false -- true if debugging luaLogForward + bDebugLogCache = false -- true if debugging luaLogCache + bDebugRetNXDOMAIN = false -- true if debugging luaRetNXDOMAIN + + + +-- ----------------------------------------------------------------------------------------------- + +-- ----------------------------------------------------------------------------------------------- +-- setup servers to use + warnlog(string.format("Script starting ----------------- %s ", "*** setup servers to use ***")) +-- ----------------------------------------------------------------------------------------------- + +--newServer({address="64.6.64.6:53", name="Verisign_1", pool="masterpool"}) -- verisign dns server #1 +--newServer({address="64.6.65.6:53", name="Verisign_2", pool="masterpool"}) -- verisign dns server #2 +newServer({address="8.8.8.8:53", name="Google_1", pool="masterpool"}) -- google dns server #1 +newServer({address="8.8.4.4:53", name="Google_2", pool="masterpool"}) -- google dns server #2 +--newServer({address="208.67.222.222:53", name="Opendns_1", pool="masterpool"}) -- opendns dns server #1 +--newServer({address="208.67.220.220:53", name="Opendns_2", pool="masterpool"}) -- opendns dns server #2 + + +-- ----------------------------------------------------------------------------------------------- +-- set up the cache +-- 10000 -> maximum number of entries stored in the cache (required) +-- 86400 -> maximum lifetime of an entry in the cache (seconds) +-- 0 -> minimum TTL an entry should have to be considered for insertion in the cache (seconds) +-- 60 -> TTL used for a Server Failure or a Refused response (seconds) +-- 60 -> TTL that will be used when a stale cache entry is returned (seconds) + warnlog(string.format("Script starting ----------------- %s ", "*** setup cache *** ")) +-- ----------------------------------------------------------------------------------------------- + + pc = newPacketCache(10000, 86400, 0, 60, 60) -- new cache + getPool("masterpool"):setCache(pc) -- masterpool cache + + + setStaleCacheEntriesTTL(3600) -- If no backends working, use cached data + + +-- ----------------------------------------------------------------------------------------------- +-- listen on local port 5200 + warnlog(string.format("Script starting ----------------- %s ", "*** listen on port 0.0.0.0:5200 for DNS requests ***")) +-- ----------------------------------------------------------------------------------------------- + + setLocal("0.0.0.0:5200") + + + rlBlkLst = newRemoteLogger('127.0.0.1:60000') -- rpz hit protobuf handler for local address, port 60,000 + rlCache = newRemoteLogger('127.0.0.1:60000') -- cache hit protobuf handler for local address, port 60,000 + rlFwd = newRemoteLogger('127.0.0.1:60000') -- forward protobuf handler for local address, port 60,000 + + +-- ----------------------------------------------------------------------------------------------- +-- maintenance() function called every second + + function maintenance() + + if ((maintCounter % 60) == 0) then -- do this once a minute + print(string.format("\n maintenance() - %s", os.date("%X-%x"))) + + local tableStat = getStatisticsCounters() -- display statistics + for k, v in pairs( tableStat ) do + print(string.format(" %-23s %d ", k, v)) + end + + + end + maintCounter = maintCounter + 1 + end + +-- ----------------------------------------------------------------------------------------------- +-- luaCheckBL() - check for rpz hit +-- if in blacklist then spoof response +-- else forward normally to masterpool + warnlog(string.format("Script starting ----------------- %s ", "*** luaCheckBL() *** ")) +-- ----------------------------------------------------------------------------------------------- + + function luaCheckBL(dq) + + if (bDebugCheckBL) + then + print(string.format("luaCheckBL -> qname.: %s ", dq.qname:toString())) + + print(string.format("luaCheckBL -> qtype.: %d ", dq.qtype)) + print(string.format("luaCheckBL -> from..: %s ", dq.remoteaddr:toStringWithPort())) + print(string.format("luaCheckBL -> opcode: %d ", dq.opcode)) + print(string.format("luaCheckBL -> rcode.: %d ", dq.rcode)) + print(string.format("luaCheckBL -> qclass: %d ", dq.qclass)) + print(string.format("luaCheckBL -> DO....: %s ", tostring(dq:getDO()))) + print(string.format("luaCheckBL -> Len...: %d ", dq.len)) + print(string.format("luaCheckBL -> Size..: %d ", dq.size)) + print(string.format("luaCheckBL -> TCP...: %s ", tostring(dq.tcp))) + end + + + local tKey = dq.qname:toString() -- get dns name client requested to be looked up + if(tKey ~= nil) + then + local tKey2 = string.sub(tKey, 1, string.len(tKey) - 1) -- get rid of final period at end of dnsname + if (bDebugCheckBL) + then + print(string.format("luaCheckBL -> tKey2.: %s ", tKey2)) + end + if(tKey2 == strTestDns1) + then + dq:setTag("Trans", "RPZ") -- label this transaction as rpz for protobuf - NEW LUA COMMAND - 5/22/2017 + dq:setTag("RPZ-Info", "reject-example") -- store blacklist extra data in dq for protobuf later -- NEW LUA COMMAND - 5/22/2017 + dq:setTag("lua-time", os.date("%X-%x")) -- an example of storing extra data -- NEW LUA COMMAND - 5/22/2017 + dq:setTag("lua-ver", _VERSION) -- another example of storing extra data -- NEW LUA COMMAND - 5/22/2017 + dq:setTag("From", dq.remoteaddr:toStringWithPort()) -- store blacklist extra data in dq for protobuf later -- NEW LUA COMMAND - 5/22/2017 + dq:setTag("TCP", tostring(dq.tcp)) -- store blacklist extra data in dq for protobuf later -- NEW LUA COMMAND - 5/22/2017 + + local tableTags = {} -- create a table as an experiment + tableTags["TestLabel1"] = "Test Value One" -- add transaction type to table + tableTags["TestLabel2"] = "Test Value Two" -- add transaction type to table + dq:setTagArray(tableTags) -- store table in dq for protobuf later -- NEW LUA COMMAND - 6/2/2017 + + if (bDebugCheckBL) + then + print(string.format("luaCheckBL -> RpzHit: %s **********", tValue)) + print(string.format("--")) + end + + return DNSAction.None, "" -- continue to the next rule + + end + end + + if (bDebugCheckBL) + then + print(string.format("luaCheckBL -> return DNSAction.Pool to masterpool ")) + print(string.format("--")) + end + + return DNSAction.Pool, "masterpool" -- use the specified pool to forward this query + + end + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action functino to alter the protobuf when a BlackList (RPZ) hit occurs + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogBL() -> 127.0.0.1:60000 ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogBL(dr, pbMsg) -- this is the lua code that executes for a request + + + if (bDebugLogBL) + then + print(string.format("luaLogBL -> qname: %s qtype: %d from: %s TCP: %s ", dr.qname:toString(), dr.qtype, dr.remoteaddr:toStringWithPort(), tostring(dr.tcp))) + print(string.format("luaLogBL -> pb: %s ", pbMsg:toDebugString())) + end + + + if (bDebugLogBL) + then + print(string.format("luaLogBL -> dr:getTagArray() ")) + end + + local tableTags = dr:getTagArray() -- get array of tags inserted by setTag() - NEW LUA COMMAND - 5/24/2017 + + if (bDebugLogBL) + then + for k, v in pairs( tableTags ) do + print(string.format("\t Label: %-15s Value: %s ", k, v)) + end + end + + if (bDebugLogBL) + then + print(string.format("luaLogBL-> Test adding to table tableTags")) + tableTags["dude1"] = "test1" -- test adding extra entries to table + tableTags["dude2"] = "test2" -- test adding extra entries to table + tableTags["dude3"] = "test3" -- test adding extra entries to table + tableTags["dude4"] = "test4" -- test adding extra entries to table + end + + if (bDebugLogBL) + then + print(string.format("luaLogBL-> setTagArray(tableTags)")) + end + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + if (bDebugLogBL) + then + print(string.format("luaLogBL-> setResponseCode(dnsdist.NXDOMAIN)")) + end + + + pbMsg:setResponseCode(dnsdist.NXDOMAIN) -- set protobuf response code to be NXDOMAIN + + + if (bDebugLogBL) + then + print(string.format("luaLogBL-> get dns name")) + end + + + local strReqName = dr.qname:toString() -- get request dns name + + + if (bDebugLogBL) + then + print(string.format("luaLogBL-> strReqName = %s", strReqName)) + end + + pbMsg:setProtobufResponseType(strReqName) -- set protobuf to look like a response and not a query, no query time -- NEW LUA COMMAND + -- strReqName - The DNS name that was sent by the client to be looked up. + +-- pbMsg:setProtobufResponseTypeQT(strReqName, os.time(), 0) -- set protobuf to look like a response and not a query, insert query time -- NEW LUA COMMAND + -- strReqName - The DNS name that was sent by the client to be looked up. + -- timestamp - Timestamp for protobuf field + -- timestamp - microseconds + + if (bDebugLogBL) + then + print(string.format("--")) + end + + +end + + + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action function to alter the protobuf when a normal forwarding happens + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogForward() ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogForward(dr, pbMsg) + + + if (bDebugLogForward) + then + print(string.format("luaLogForward -> qname: %s qtype: %d from: %s TCP: %s ", dr.qname:toString(), dr.qtype, dr.remoteaddr:toStringWithPort(), tostring(dr.tcp))) + print(string.format("luaLogForward -> opcode: %d ", dr.opcode)) + print(string.format("luaLogForward -> rcode.: %d ", dr.rcode)) + print(string.format("luaLogForward -> qclass: %d ", dr.qclass)) + print(string.format("luaLogForward -> len...: %d ", dr.len)) + print(string.format("luaLogForward -> pb: %s ", pbMsg:toDebugString())) + end + + + if (bDebugLogForward) + then + print(string.format("luaLogForward -> Creating a table with transaction type. ")) + end + + local tableTags = {} -- create a table + tableTags["Trans"] = "FWD" -- add transaction type to table + + if (bDebugLogForward) + then + print(string.format("luaLogBL-> setTagArray(tableTags)")) + end + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + + + if (bDebugLogForward) + then + print(string.format("--")) + end + +end + + + + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action function to alter the protobuf when a Cache hit occurs + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogCache() ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogCache(dr, pbMsg) -- this is the lua code that executes after a cache hit + + + if (bDebugLogCache) + then + print(string.format("luaLogCache -> qname: %s qtype: %d from: %s TCP: %s ", dr.qname:toString(), dr.qtype, dr.remoteaddr:toStringWithPort(), tostring(dr.tcp))) + end + + if (bDebugLogCache) + then + print(string.format("luaLogForward -> Creating a table with transaction type. ")) + end + + local tableTags = {} -- create a table + tableTags["Trans"] = "CACHE" -- add transaction type to table + + if (bDebugLogCache) + then + print(string.format("luaLogBL-> setTagArray(tableTags)")) + end + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + + + if (bDebugLogForward) + then + print(string.format("--")) + end + + + if (bDebugLogCache) + then + print(string.format("--")) + end + +end + + + + +-- ---------------------------------------------------------------------------------------------- + -- put this here so blacklist sends out protobuf...... +function luaRetNXDOMAIN(dq) + + if (bDebugRetNXDOMAIN) + then + print(string.format("luaRetNXDOMAIN() - return NXDOMAIN to client")) + print(string.format("--")) + end + return DNSAction.Nxdomain, "" -- return NXDOMAIN response to client +end + + + + +-- ----------------------------------------------------------------------------------------------- +-- Rules + warnlog(string.format("Script starting ----------------- %s ", "*** setting rules *** ")) +-- ----------------------------------------------------------------------------------------------- + + + addLuaAction(AllRule(), luaCheckBL) -- first, check blacklist, if match process next rule below, else send to "masterpool" + + addAction(AllRule(), RemoteLogAction(rlBlkLst, luaLogBL)) -- then send out protobuf for rpz hit + + addLuaAction(AllRule(), luaRetNXDOMAIN) -- then send nxdomain response back to the client. + + addAction(AllRule(), PoolAction("masterpool")) -- direct requests that are not RPZ to pool "masterpool" + + + addCacheHitResponseAction(AllRule(), RemoteLogResponseAction(rlCache, luaLogCache)) -- used to send out protobuf on cache hit + + + addResponseAction(AllRule(), RemoteLogResponseAction(rlFwd, luaLogForward)) -- used to send out protobuf on forward (normal) out + +-- ----------------------------------------------------------------------------------------------- +-- finished setting up script +-- ----------------------------------------------------------------------------------------------- + + warnlog(string.format("Script finished ----------------- %s ", os.date("%X-%x"))) + diff --git a/zzz-gca-example/dnsdist.conf b/zzz-gca-example/dnsdist.conf new file mode 100644 index 000000000..a79521a6a --- /dev/null +++ b/zzz-gca-example/dnsdist.conf @@ -0,0 +1,252 @@ +-- ----------------------------------------------------------------------------------------------- +-- dnsdist2.conf - with NO text debugging comments....... +-- see dnsdist2-debug.conf for a copy with text debugging. +-- Seth Ornstein - sornstein@globalcyberalliance.org +-- 6/7/2017 +-- for use in testing out new Lua commands for dnsdist +-- git clone -b dnsdist-mod2 https://github.com/GlobalCyberAlliance/pdns.git +-- ----------------------------------------------------------------------------------------------- + + warnlog(string.format("Script starting ----------------- %s ", "dnsdist2.conf")) + + warnlog(string.format("Script starting ----------------- %s ", os.date("%X-%x"))) + + warnlog(string.format("Script starting ----------------- Lua Version: %s - (should be 5.1)", _VERSION)) + + + + strTestDns1 = "1jw2mr4fmky.net" -- test #1 dns lookup name - (reject) + + maintCounter = 0 -- maintainance counter + + bDebugCheckBL = false -- true if debugging luaCheckBL + bDebugLogBL = false -- true if debugging luaLogBL + bDebugLogForward = false -- true if debugging luaLogForward + bDebugLogCache = false -- true if debugging luaLogCache + bDebugRetNXDOMAIN = false -- true if debugging luaRetNXDOMAIN + + + +-- ----------------------------------------------------------------------------------------------- + +-- ----------------------------------------------------------------------------------------------- +-- setup servers to use + warnlog(string.format("Script starting ----------------- %s ", "*** setup servers to use ***")) +-- ----------------------------------------------------------------------------------------------- + +--newServer({address="64.6.64.6:53", name="Verisign_1", pool="masterpool"}) -- verisign dns server #1 +--newServer({address="64.6.65.6:53", name="Verisign_2", pool="masterpool"}) -- verisign dns server #2 +newServer({address="8.8.8.8:53", name="Google_1", pool="masterpool"}) -- google dns server #1 +newServer({address="8.8.4.4:53", name="Google_2", pool="masterpool"}) -- google dns server #2 +--newServer({address="208.67.222.222:53", name="Opendns_1", pool="masterpool"}) -- opendns dns server #1 +--newServer({address="208.67.220.220:53", name="Opendns_2", pool="masterpool"}) -- opendns dns server #2 + + +-- ----------------------------------------------------------------------------------------------- +-- set up the cache +-- 10000 -> maximum number of entries stored in the cache (required) +-- 86400 -> maximum lifetime of an entry in the cache (seconds) +-- 0 -> minimum TTL an entry should have to be considered for insertion in the cache (seconds) +-- 60 -> TTL used for a Server Failure or a Refused response (seconds) +-- 60 -> TTL that will be used when a stale cache entry is returned (seconds) + warnlog(string.format("Script starting ----------------- %s ", "*** setup cache *** ")) +-- ----------------------------------------------------------------------------------------------- + + pc = newPacketCache(10000, 86400, 0, 60, 60) -- new cache + getPool("masterpool"):setCache(pc) -- masterpool cache + + + setStaleCacheEntriesTTL(3600) -- If no backends working, use cached data + + +-- ----------------------------------------------------------------------------------------------- +-- listen on local port 5200 + warnlog(string.format("Script starting ----------------- %s ", "*** listen on port 0.0.0.0:5200 for DNS requests ***")) +-- ----------------------------------------------------------------------------------------------- + + setLocal("0.0.0.0:5200") + + + rlBlkLst = newRemoteLogger('127.0.0.1:60000') -- rpz hit protobuf handler for local address, port 60,000 + rlCache = newRemoteLogger('127.0.0.1:60000') -- cache hit protobuf handler for local address, port 60,000 + rlFwd = newRemoteLogger('127.0.0.1:60000') -- forward protobuf handler for local address, port 60,000 + + +-- ----------------------------------------------------------------------------------------------- +-- maintenance() function called every second + + function maintenance() + + if ((maintCounter % 60) == 0) then -- do this once a minute + print(string.format("\n maintenance() - %s", os.date("%X-%x"))) + + local tableStat = getStatisticsCounters() -- display statistics + for k, v in pairs( tableStat ) do + print(string.format(" %-23s %d ", k, v)) + end + + + end + maintCounter = maintCounter + 1 + end + +-- ----------------------------------------------------------------------------------------------- +-- luaCheckBL() - check for rpz hit +-- if in blacklist then spoof response +-- else forward normally to masterpool + warnlog(string.format("Script starting ----------------- %s ", "*** luaCheckBL() *** ")) +-- ----------------------------------------------------------------------------------------------- + + function luaCheckBL(dq) + + + + local tKey = dq.qname:toString() -- get dns name client requested to be looked up + if(tKey ~= nil) + then + local tKey2 = string.sub(tKey, 1, string.len(tKey) - 1) -- get rid of final period at end of dnsname + if(tKey2 == strTestDns1) + then + dq:setTag("Trans", "RPZ") -- label this transaction as rpz for protobuf - NEW LUA COMMAND - 5/22/2017 + dq:setTag("RPZ-Info", "reject-example") -- store blacklist extra data in dq for protobuf later -- NEW LUA COMMAND - 5/22/2017 + + local tableTags = {} -- create a table as an experiment + tableTags["TestLabel1"] = "Test Value One" -- add transaction type to table + tableTags["TestLabel2"] = "Test Value Two" -- add transaction type to table + dq:setTagArray(tableTags) -- store table in dq for protobuf later -- NEW LUA COMMAND - 6/2/2017 + + + return DNSAction.None, "" -- continue to the next rule + + end + end + + + return DNSAction.Pool, "masterpool" -- use the specified pool to forward this query + + end + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action functino to alter the protobuf when a BlackList (RPZ) hit occurs + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogBL() -> 127.0.0.1:60000 ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogBL(dr, pbMsg) -- this is the lua code that executes for a request + + + + + + local tableTags = dr:getTagArray() -- get array of tags inserted by setTag() - NEW LUA COMMAND - 5/24/2017 + + + + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + + + pbMsg:setResponseCode(dnsdist.NXDOMAIN) -- set protobuf response code to be NXDOMAIN + + + + + local strReqName = dr.qname:toString() -- get request dns name + + + + pbMsg:setProtobufResponseType(strReqName) -- set protobuf to look like a response and not a query, no query time -- NEW LUA COMMAND + -- strReqName - The DNS name that was sent by the client to be looked up. + +-- pbMsg:setProtobufResponseTypeQT(strReqName, os.time(), 0) -- set protobuf to look like a response and not a query, insert query time -- NEW LUA COMMAND + -- strReqName - The DNS name that was sent by the client to be looked up. + -- timestamp - Timestamp for protobuf field + -- timestamp - microseconds + + + +end + + + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action function to alter the protobuf when a normal forwarding happens + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogForward() ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogForward(dr, pbMsg) + + + + + local tableTags = {} -- create a table + tableTags["Trans"] = "FWD" -- add transaction type to table + + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + + + +end + + + + +-- ----------------------------------------------------------------------------------------------- +-- declare a Lua action function to alter the protobuf when a Cache hit occurs + warnlog(string.format("Script starting ----------------- %s ", "*** luaLogCache() ***")) +-- ----------------------------------------------------------------------------------------------- + +function luaLogCache(dr, pbMsg) -- this is the lua code that executes after a cache hit + + + + local tableTags = {} -- create a table + tableTags["Trans"] = "CACHE" -- add transaction type to table + + + pbMsg:setTagArray(tableTags) -- store tableTags in the 'tags' field of the protobuf - NEW LUA COMMAND - 5/24/2017 + + +end + + + + +-- ---------------------------------------------------------------------------------------------- + -- put this here so blacklist sends out protobuf...... +function luaRetNXDOMAIN(dq) + + return DNSAction.Nxdomain, "" -- return NXDOMAIN response to client +end + + + + +-- ----------------------------------------------------------------------------------------------- +-- Rules + warnlog(string.format("Script starting ----------------- %s ", "*** setting rules *** ")) +-- ----------------------------------------------------------------------------------------------- + + + addLuaAction(AllRule(), luaCheckBL) -- first, check blacklist, if match process next rule below, else send to "masterpool" + + addAction(AllRule(), RemoteLogAction(rlBlkLst, luaLogBL)) -- then send out protobuf for rpz hit + + addLuaAction(AllRule(), luaRetNXDOMAIN) -- then send nxdomain response back to the client. + + addAction(AllRule(), PoolAction("masterpool")) -- direct requests that are not RPZ to pool "masterpool" + + + addCacheHitResponseAction(AllRule(), RemoteLogResponseAction(rlCache, luaLogCache)) -- used to send out protobuf on cache hit + + + addResponseAction(AllRule(), RemoteLogResponseAction(rlFwd, luaLogForward)) -- used to send out protobuf on forward (normal) out + +-- ----------------------------------------------------------------------------------------------- +-- finished setting up script +-- ----------------------------------------------------------------------------------------------- + + warnlog(string.format("Script finished ----------------- %s ", os.date("%X-%x"))) + diff --git a/zzz-gca-example/dnsdist2-debug.sh b/zzz-gca-example/dnsdist2-debug.sh new file mode 100755 index 000000000..1f2016305 --- /dev/null +++ b/zzz-gca-example/dnsdist2-debug.sh @@ -0,0 +1,19 @@ +echo "test-dnsdist2.sh - test dnsdist - debugging configuration" +echo "" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SLASH="/" +CFG_FILE="dnsdist-debug.conf" +CONFIG_FILE=$DIR$SLASH$CFG_FILE +echo "current directory: " $DIR +echo "" +echo "configuration file: " $CONFIG_FILE +echo "" +echo "cd ../pdns/dnsdistdist" +echo "" +cd ../pdns/dnsdistdist +echo "" +###echo "listen on port 5200 for requests" +###echo "" +###./dnsdist --config=$CONFIG_FILE --local=0.0.0.0:5200 + +./dnsdist --config=$CONFIG_FILE diff --git a/zzz-gca-example/dnsdist2.sh b/zzz-gca-example/dnsdist2.sh new file mode 100755 index 000000000..410d4de28 --- /dev/null +++ b/zzz-gca-example/dnsdist2.sh @@ -0,0 +1,19 @@ +echo "test-dnsdist2.sh - test dnsdist" +echo "" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SLASH="/" +CFG_FILE="dnsdist.conf" +CONFIG_FILE=$DIR$SLASH$CFG_FILE +echo "current directory: " $DIR +echo "" +echo "configuration file: " $CONFIG_FILE +echo "" +echo "cd ../pdns/dnsdistdist" +echo "" +cd ../pdns/dnsdistdist +echo "" +###echo "listen on port 5200 for requests" +###echo "" +###./dnsdist --config=$CONFIG_FILE --local=0.0.0.0:5200 + +./dnsdist --config=$CONFIG_FILE diff --git a/zzz-gca-example/make-dnsdist2.sh b/zzz-gca-example/make-dnsdist2.sh new file mode 100755 index 000000000..f4f952988 --- /dev/null +++ b/zzz-gca-example/make-dnsdist2.sh @@ -0,0 +1,5 @@ +echo "-------------- cd ../pdns/dnsdistdist -----------" +cd ../pdns/dnsdistdist +echo "-------------- make--------------------------------" +make + diff --git a/zzz-gca-example/protobuf-server2.sh b/zzz-gca-example/protobuf-server2.sh new file mode 100755 index 000000000..6bfc39340 --- /dev/null +++ b/zzz-gca-example/protobuf-server2.sh @@ -0,0 +1,14 @@ +echo "protobuf-server2 for testing dnsdist Seth Global Cyber Alliance 6/7/2017" + +cd ../contrib/ + +echo "" +echo "----------------------------" +echo "listening on 127.0.0.1:60000" +echo "----------------------------" +echo "" + +./ProtobufLogger.py 127.0.0.1 60000 + + + -- 2.50.1