Skip to content

Commit c147198

Browse files
committed
update log-format, add option to log in JSON-format
1 parent af8cc46 commit c147198

File tree

8 files changed

+184
-34
lines changed

8 files changed

+184
-34
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
652652
If the program does terminal interaction, make it output a short
653653
notice like this when it starts in an interactive mode:
654654

655-
<program> Copyright (C) <year> <name of author>
655+
DNS-BL Server Copyright (C) 2025 OXL IT Services / Rath Pascal
656656
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657657
This is free software, and you are welcome to redistribute it
658658
under certain conditions; type `show c' for details.

README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,33 @@ Users can query the DNS-BL as configured in your config-file through:
2828
* `d.<DOMAIN>` => for Domain-Lookups
2929

3030
```bash
31-
dnsbl-server -domain test.at -config ./config.yml -port 10000
31+
rath@gate:~ dnsbl-server -help
32+
> Usage of dnsbl-server:
33+
> -config string
34+
> Path to the config file (in YAML format) (required)
35+
> -domain string
36+
> Domain to serve for (required)
37+
> -log-json
38+
> Log in JSON-format (defaut false)
39+
> -no-log
40+
> Disable request logging (defaut false)
41+
> -no-log-time
42+
> Disable log timestamp (defaut false)
43+
> -port int
44+
> Port to listen on (default 5353)
45+
46+
rath@gate:~ dnsbl-server -domain test.at -config ./config.yml -port 10000
47+
3248
2025/07/24 21:46:12 DNS-BL server listening on 10000
3349
> IP Lookup: ip.test.at.
3450
> Domain Lookup: d.test.at.
35-
# <time> [<client-IP>] => <IP/DOMAIN>: <request> <= response-code
51+
# <time> [<client-IP>] => <IP/DOMAIN>: <request> <= <status> <response>
3652
# 200 = found, 400 = bad request, 404 = not found
37-
2025/07/24 21:46:16 [127.0.0.1] => IP: 192.0.2.88 <= 200
38-
2025/07/24 21:46:18 [127.0.0.1] => IP: 192.0.2.130 <= 200
53+
2025/07/24 21:46:16 [127.0.0.1] => IP: 192.0.2.88 <= 200 127.0.0.2
54+
2025/07/24 21:46:18 [127.0.0.1] => IP: 192.0.2.130 <= 200 127.0.0.2
3955
2025/07/24 21:46:23 [127.0.0.1] => IP: 1.1.1.1 <= 404
40-
2025/07/24 21:46:53 [127.0.0.1] => IP: fe80::9fe:dc1c:42f0:6e60 <= 200
41-
2025/07/24 21:48:08 [127.0.0.1] => Domain: malicious.risk.oxl.app <= 200
56+
2025/07/24 21:46:53 [127.0.0.1] => IP: fe80::9fe:dc1c:42f0:6e60 <= 200 127.0.0.2
57+
2025/07/24 21:48:08 [127.0.0.1] => Domain: malicious.risk.oxl.app <= 200 127.0.0.2
4258
2025/07/24 21:47:42 [127.0.0.1] => Domain: good.oxl.app <= 404
4359
4460
# examples of bad requests

scripts/build.sh

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
#!/usr/bin/env bash
22

3-
set -e
3+
set -eo pipefail
4+
5+
if [ -z "$GO_BIN" ]
6+
then
7+
GO_BIN='go'
8+
fi
9+
10+
if [ -z "$GOOS" ]
11+
then
12+
GOOS='linux'
13+
fi
14+
15+
if [ -z "$GOARCH" ]
16+
then
17+
GOARCH='amd64'
18+
fi
19+
20+
cgo=''
21+
if [ -n "$CGO_ENABLED" ]
22+
then
23+
cgo="-CGO${CGO_ENABLED}"
24+
fi
425

526
cd "$(dirname "$0")/.."
627

728
PATH_OUT="$(pwd)/build"
8-
FILE_OUT="${PATH_OUT}/dnsbl-server"
29+
FILE_OUT="${PATH_OUT}/dnsbl-server-${GOOS}-${GOARCH}${cgo}"
930
mkdir -p "$PATH_OUT"
1031

11-
cd src/cmd/
12-
13-
go build -o "$FILE_OUT"
32+
go build -o "$FILE_OUT" ./src/cmd/
1433

1534
echo "DONE: ${FILE_OUT}"

scripts/build_all_bin.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
cd "$(dirname "$0")"
6+
7+
PATH_SCRIPT="$(pwd)"
8+
PATH_REPO="${PATH_SCRIPT}/.."
9+
PATH_BUILD="${PATH_REPO}/build"
10+
FILE_BEG="dnsbl-server-"
11+
12+
cd "$PATH_REPO"
13+
mkdir -p "$PATH_BUILD"
14+
rm -f "$PATH_BUILD"/*
15+
16+
17+
function compile() {
18+
os="$1" arch="$2"
19+
echo ''
20+
echo ''
21+
echo "# COMPILING BINARIES FOR ${os}-${arch} #"
22+
echo ''
23+
24+
GOOS="$os" GOARCH="$arch" bash "${PATH_SCRIPT}/build.sh"
25+
echo ''
26+
GOOS="$os" GOARCH="$arch" CGO_ENABLED=0 bash "${PATH_SCRIPT}/build.sh"
27+
28+
echo ''
29+
echo '### COMPRESSING ###'
30+
file="${FILE_BEG}${os}-${arch}"
31+
cd "$PATH_BUILD"
32+
tar -czf "${file}.tar.gz" "$file"
33+
tar -czf "${file}-CGO0.tar.gz" "${file}-CGO0"
34+
}
35+
36+
compile "linux" "amd64"
37+
38+
# untested
39+
compile "linux" "386"
40+
compile "linux" "arm"
41+
compile "linux" "arm64"
42+
43+
compile "freebsd" "386"
44+
compile "freebsd" "amd64"
45+
compile "freebsd" "arm"
46+
47+
compile "openbsd" "386"
48+
compile "openbsd" "amd64"
49+
compile "openbsd" "arm"
50+
51+
compile "darwin" "amd64"
52+
compile "darwin" "arm64"

src/cmd/main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,34 @@ import (
1313
"github.com/miekg/dns"
1414
)
1515

16+
const VERSION = "1.0.0"
17+
1618
func main() {
1719
var domain string
1820
var configFile string
1921
var port int
2022
var noLog bool
2123
var noLogTime bool
24+
var logJSON bool
2225

2326
flag.StringVar(&domain, "domain", "", "Domain to serve for")
2427
flag.StringVar(&configFile, "config", "", "Path to the config file (in YAML format)")
2528
flag.IntVar(&port, "port", 5353, "Port to listen on")
2629
flag.BoolVar(&noLog, "no-log", false, "Disable request logging")
2730
flag.BoolVar(&noLogTime, "no-log-time", false, "Disable log timestamp")
31+
flag.BoolVar(&logJSON, "log-json", false, "Log in JSON-format")
2832
flag.Parse()
2933

34+
fmt.Printf("DNS-BL Server v%v\n © OXL IT Service\n License: GPLv3\n\n", VERSION)
35+
3036
if domain == "" || configFile == "" {
31-
fmt.Println("Domain and config-file need to be provided!")
37+
fmt.Println("ERROR: Domain and config-file need to be provided!")
3238
os.Exit(1)
3339
}
3440

3541
validDomain, _ := regexp.MatchString(internal.REGEX_DOMAIN, domain)
3642
if !validDomain {
37-
fmt.Println("Invalid domain provided! Example: 'dnsbl.risk.oxl.app'")
43+
fmt.Println("ERROR: Invalid domain provided! Example: 'dnsbl.risk.oxl.app'")
3844
os.Exit(1)
3945
}
4046
if !strings.HasSuffix(domain, ".") {
@@ -47,6 +53,7 @@ func main() {
4753
BL: internal.DNSBLConfigFlat{},
4854
Log: !noLog,
4955
LogTime: !noLogTime,
56+
LogJSON: logJSON,
5057
BaseIP: fmt.Sprintf(".%v", baseIP),
5158
BaseDomain: fmt.Sprintf(".%v", baseDomain),
5259
}

src/internal/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type DNSBLRunningConfig struct {
3535
BaseDomain string
3636
Log bool
3737
LogTime bool
38+
LogJSON bool
3839
}
3940

4041
func (config *DNSBLRunningConfig) LookupIP(w dns.ResponseWriter, r *dns.Msg) {

src/internal/logger.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package internal
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
"time"
8+
)
9+
10+
type requestLog struct {
11+
Client string `json:"cli"`
12+
Type string `json:"type"`
13+
Request string `json:"req"`
14+
Status int `json:"status"`
15+
Response string `json:"res"`
16+
}
17+
18+
type requestLogTime struct {
19+
Time string `json:"time"`
20+
Client string `json:"cli"`
21+
Type string `json:"type"`
22+
Request string `json:"req"`
23+
Status int `json:"status"`
24+
Response string `json:"res"`
25+
}
26+
27+
func logRequest(q string, s int, cli string, c *DNSBLRunningConfig, t int, res string) {
28+
if !c.Log {
29+
return
30+
}
31+
ts := "IP"
32+
if t == LOOKUP_DOMAIN {
33+
ts = "Domain"
34+
}
35+
36+
if c.LogJSON {
37+
var err error
38+
var l []byte
39+
if c.LogTime {
40+
l, err = json.Marshal(requestLogTime{
41+
Time: time.Now().Format(time.RFC3339),
42+
Client: cli,
43+
Type: ts,
44+
Request: q,
45+
Status: s,
46+
Response: res,
47+
})
48+
} else {
49+
l, err = json.Marshal(requestLog{
50+
Client: cli,
51+
Type: ts,
52+
Request: q,
53+
Status: s,
54+
Response: res,
55+
})
56+
}
57+
58+
if err != nil {
59+
fmt.Printf("ERROR: Unable to log in JSON-format - %v", err)
60+
return
61+
}
62+
fmt.Println(string(l))
63+
64+
} else {
65+
l := fmt.Sprintf("[%s] => %s: %s <= %d %s", cli, ts, q, s, res)
66+
if c.LogTime {
67+
log.Println(l)
68+
} else {
69+
fmt.Println(l)
70+
}
71+
}
72+
}

src/internal/server.go

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package internal
22

33
import (
44
"fmt"
5-
"log"
65
"net/netip"
76
"regexp"
87
"slices"
@@ -15,22 +14,6 @@ const RES_RATE = "127.255.255.255"
1514
const BAD_REQ = "-"
1615
const REGEX_DOMAIN = "^[a-z0-9\\-\\.]{1,253}\\.[a-z0-9\\-]{2,63}(\\.?)$"
1716

18-
func logRequest(q string, res string, cli string, c *DNSBLRunningConfig, t int) {
19-
if !c.Log {
20-
return
21-
}
22-
ts := "IP"
23-
if t == LOOKUP_DOMAIN {
24-
ts = "Domain"
25-
}
26-
l := fmt.Sprintf("[%s] => %s: %s <= %s", cli, ts, q, res)
27-
if c.LogTime {
28-
log.Println(l)
29-
} else {
30-
fmt.Println(l)
31-
}
32-
}
33-
3417
func checkIP(q dns.Question, c *DNSBLRunningConfig) (string, string) {
3518
req := strings.Replace(q.Name, c.BaseIP, "", 1)
3619
parts := strings.Split(req, ".")
@@ -105,17 +88,17 @@ func parseQuery(m *dns.Msg, w dns.ResponseWriter, c *DNSBLRunningConfig, t int)
10588
}
10689

10790
if res == BAD_REQ {
108-
logRequest(query, "400", cli, c, t)
91+
logRequest(query, 400, cli, c, t, "")
10992

11093
} else if res != "" {
111-
logRequest(query, "200", cli, c, t)
94+
logRequest(query, 200, cli, c, t, res)
11295
rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, res))
11396
if err == nil {
11497
m.Answer = append(m.Answer, rr)
11598
}
11699

117100
} else {
118-
logRequest(query, "404", cli, c, t)
101+
logRequest(query, 404, cli, c, t, "")
119102
}
120103
}
121104
}

0 commit comments

Comments
 (0)