Skip to content

Commit

Permalink
feat: update list config and code to use "allow/deny" language
Browse files Browse the repository at this point in the history
  • Loading branch information
ThinkChaos committed Apr 11, 2024
1 parent 3515483 commit bcd1381
Show file tree
Hide file tree
Showing 26 changed files with 262 additions and 232 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Blocky is a DNS proxy and ad-blocker for the local network written in Go with fo

## Features

- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and allowlisting

- Definition of black and white lists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external black and white lists
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external allow/denylists
- Regex support
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)

Expand Down
2 changes: 1 addition & 1 deletion cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var _ = Describe("root command", func() {
" default:",
" - 1.1.1.1",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" clientGroupsBlock:",
Expand Down
32 changes: 18 additions & 14 deletions config/blocking.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,32 @@ import (

// Blocking configuration for query blocking
type Blocking struct {
BlackLists map[string][]BytesSource `yaml:"blackLists"`
WhiteLists map[string][]BytesSource `yaml:"whiteLists"`
Denylists map[string][]BytesSource `yaml:"denylists"`
Allowlists map[string][]BytesSource `yaml:"allowlists"`
ClientGroupsBlock map[string][]string `yaml:"clientGroupsBlock"`
BlockType string `yaml:"blockType" default:"ZEROIP"`
BlockTTL Duration `yaml:"blockTTL" default:"6h"`
Loading SourceLoading `yaml:"loading"`

// Deprecated options
Deprecated struct {
DownloadTimeout *Duration `yaml:"downloadTimeout"`
DownloadAttempts *uint `yaml:"downloadAttempts"`
DownloadCooldown *Duration `yaml:"downloadCooldown"`
RefreshPeriod *Duration `yaml:"refreshPeriod"`
FailStartOnListError *bool `yaml:"failStartOnListError"`
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
StartStrategy *InitStrategy `yaml:"startStrategy"`
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
BlackLists *map[string][]BytesSource `yaml:"blackLists"`
WhiteLists *map[string][]BytesSource `yaml:"whiteLists"`
DownloadTimeout *Duration `yaml:"downloadTimeout"`
DownloadAttempts *uint `yaml:"downloadAttempts"`
DownloadCooldown *Duration `yaml:"downloadCooldown"`
RefreshPeriod *Duration `yaml:"refreshPeriod"`
FailStartOnListError *bool `yaml:"failStartOnListError"`
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
StartStrategy *InitStrategy `yaml:"startStrategy"`
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
} `yaml:",inline"`
}

func (c *Blocking) migrate(logger *logrus.Entry) bool {
return Migrate(logger, "blocking", c.Deprecated, map[string]Migrator{
"blackLists": Move(To("denylists", c)),
"whiteLists": Move(To("allowlists", c)),
"downloadTimeout": Move(To("loading.downloads.timeout", &c.Loading.Downloads)),
"downloadAttempts": Move(To("loading.downloads.attempts", &c.Loading.Downloads)),
"downloadCooldown": Move(To("loading.downloads.cooldown", &c.Loading.Downloads)),
Expand Down Expand Up @@ -67,14 +71,14 @@ func (c *Blocking) LogConfig(logger *logrus.Entry) {
logger.Info("loading:")
log.WithIndent(logger, " ", c.Loading.LogConfig)

logger.Info("blacklist:")
logger.Info("denylists:")
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
c.logListGroups(logger, c.BlackLists)
c.logListGroups(logger, c.Denylists)
})

logger.Info("whitelist:")
logger.Info("allowlists:")
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
c.logListGroups(logger, c.WhiteLists)
c.logListGroups(logger, c.Allowlists)
})
}

Expand Down
28 changes: 27 additions & 1 deletion config/blocking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var _ = Describe("BlockingConfig", func() {
cfg = Blocking{
BlockType: "ZEROIP",
BlockTTL: Duration(time.Minute),
BlackLists: map[string][]BytesSource{
Denylists: map[string][]BytesSource{
"gr1": NewBytesSources("/a/file/path"),
},
ClientGroupsBlock: map[string][]string{
Expand Down Expand Up @@ -60,4 +60,30 @@ var _ = Describe("BlockingConfig", func() {
Expect(hook.Messages).Should(ContainElement(Equal("blockType = ZEROIP")))
})
})

Describe("migrate", func() {
It("should copy values", func() {
cfg, err := WithDefaults[Blocking]()
Expect(err).Should(Succeed())

cfg.Deprecated.BlackLists = &map[string][]BytesSource{
"deny-group": NewBytesSources("/deny.txt"),
}
cfg.Deprecated.WhiteLists = &map[string][]BytesSource{
"allow-group": NewBytesSources("/allow.txt"),
}

migrated := cfg.migrate(logger)
Expect(migrated).Should(BeTrue())

Expect(hook.Calls).ShouldNot(BeEmpty())
Expect(hook.Messages).Should(ContainElements(
ContainSubstring("blocking.allowlists"),
ContainSubstring("blocking.denylists"),
))

Expect(cfg.Allowlists).Should(Equal(*cfg.Deprecated.WhiteLists))
Expect(cfg.Denylists).Should(Equal(*cfg.Deprecated.BlackLists))
})
})
})
16 changes: 8 additions & 8 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -988,8 +988,8 @@ func defaultTestFileConfig(config *Config) {
Expect(config.Conditional.Mapping.Upstreams["multiple.resolvers"]).Should(HaveLen(2))
Expect(config.ClientLookup.Upstream.Host).Should(Equal("192.168.178.1"))
Expect(config.ClientLookup.SingleNameOrder).Should(Equal([]uint{2, 1}))
Expect(config.Blocking.BlackLists).Should(HaveLen(2))
Expect(config.Blocking.WhiteLists).Should(HaveLen(1))
Expect(config.Blocking.Denylists).Should(HaveLen(2))
Expect(config.Blocking.Allowlists).Should(HaveLen(1))
Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2))
Expect(config.Blocking.BlockTTL).Should(Equal(Duration(time.Minute)))
Expect(config.Blocking.Loading.RefreshPeriod).Should(Equal(Duration(2 * time.Hour)))
Expand Down Expand Up @@ -1029,7 +1029,7 @@ func writeConfigYml(tmpDir *helpertest.TmpFolder) *helpertest.TmpFile {
"fqdnOnly:",
" enable: true",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
Expand All @@ -1039,9 +1039,9 @@ func writeConfigYml(tmpDir *helpertest.TmpFolder) *helpertest.TmpFile {
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
" special:",
" - https://hosts-file.net/ad_servers.txt",
" whiteLists:",
" allowlists:",
" ads:",
" - whitelist.txt",
" - allowlist.txt",
" clientGroupsBlock:",
" default:",
" - ads",
Expand Down Expand Up @@ -1119,7 +1119,7 @@ func writeConfigDir(tmpDir *helpertest.TmpFolder) {

tmpDir.CreateStringFile("config2.yaml",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
Expand All @@ -1129,9 +1129,9 @@ func writeConfigDir(tmpDir *helpertest.TmpFolder) {
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
" special:",
" - https://hosts-file.net/ad_servers.txt",
" whiteLists:",
" allowlists:",
" ads:",
" - whitelist.txt",
" - allowlist.txt",
" clientGroupsBlock:",
" default:",
" - ads",
Expand Down
11 changes: 5 additions & 6 deletions docs/additional_information.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ To print runtime configuration / statistics, you can send `SIGUSR1` signal to ru
INFO server: MEM NumGC = 1533
INFO server: RUN NumCPU = 4
INFO server: RUN NumGoroutine = 18

```

!!! hint
Expand All @@ -49,7 +48,7 @@ automatically.

Some links/ideas for lists:

### Blacklists
### Denylists

* [https://github.com/StevenBlack/hosts](https://github.com/StevenBlack/hosts)
* [https://github.com/nickspaargaren/no-google](https://github.com/nickspaargaren/no-google)
Expand All @@ -60,11 +59,11 @@ Some links/ideas for lists:

!!! warning

Use only blacklists from the sources you trust!
Use only denylists from the sources you trust!

### Whitelists
### Allowlists

* [https://github.com/anudeepND/whitelist](https://github.com/anudeepND/whitelist)
* [https://github.com/anudeepND/whitelist](https://github.com/anudeepND/allowlist)

## List of public DNS servers

Expand All @@ -74,7 +73,7 @@ Some links/ideas for lists:

Please read the description before using the DNS server as upstream. Some of them provide already an ad-blocker, some
filters other content. If you use external DNS server with included ad-blocker, you can't choose which domains should be
blocked, and you can't use whitelisting.
blocked, and you can't use allowlisting.

This is only a small excerpt of all free available DNS servers and should only be understood as an idee.

Expand Down
6 changes: 3 additions & 3 deletions docs/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ info:
## Features
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and allowlisting
- Definition of black and white lists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external black and white lists
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external allow/denylists
- Regex support
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
Expand Down
12 changes: 6 additions & 6 deletions docs/blocky-grafana.json
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@
"datasource": {
"uid": "${DS_PROMETHEUS}"
},
"description": "Number of blacklist entries",
"description": "Number of denylist entries",
"fieldConfig": {
"defaults": {
"mappings": [
Expand Down Expand Up @@ -487,15 +487,15 @@
"uid": "${DS_PROMETHEUS}"
},
"exemplar": true,
"expr": "sum(blocky_blacklist_cache) / sum(up{job=~\"$job\"})",
"expr": "sum(blocky_denylist_cache) / sum(up{job=~\"$job\"})",
"format": "table",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"title": "Blacklist entries total",
"title": "Denylist entries total",
"transparent": true,
"type": "stat"
},
Expand Down Expand Up @@ -1683,15 +1683,15 @@
"uid": "${DS_PROMETHEUS}"
},
"exemplar": false,
"expr": "topk(1, blocky_blacklist_cache) by (group)",
"expr": "topk(1, blocky_denylist_cache) by (group)",
"format": "time_series",
"instant": true,
"interval": "",
"legendFormat": "{{ group }}",
"refId": "A"
}
],
"title": "Blacklist by group",
"title": "Denylist by group",
"transparent": true,
"type": "piechart"
},
Expand Down Expand Up @@ -1978,4 +1978,4 @@
"uid": "JvOqE4gRk",
"version": 1,
"weekStart": ""
}
}
2 changes: 1 addition & 1 deletion docs/blocky-query-grafana-postgres.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
]
}
],
"title": "Blocked by Blacklist",
"title": "Blocked by Denylist",
"type": "piechart"
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/blocky-query-grafana.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
]
}
],
"title": "Blocked by Blacklist",
"title": "Blocked by Denylist",
"type": "piechart"
},
{
Expand Down
18 changes: 10 additions & 8 deletions docs/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ conditional:
fritz.box: 192.168.178.1
lan.net: 192.168.178.1,192.168.178.2

# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.)
# optional: use allow/denylists to block queries (for example ads, trackers, adult pages etc.)
blocking:
# definition of blacklist groups. Can be external link (http/https) or local file
blackLists:
# definition of denylist groups. Can be external link (http/https) or local file
denylists:
ads:
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
Expand All @@ -77,14 +77,16 @@ blocking:
*.example.com
special:
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
# definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked
whiteLists:
# definition of allowlist groups.
# Note: if the same group has both allow/denylists, allowlists take precedence. Meaning if a domain is both blocked and allowed, it will be allowed.
# If a group has only allowlist entries, only domains from this list are allowed, and all others be blocked.
allowlists:
ads:
- whitelist.txt
- allowlist.txt
- |
# inline definition with YAML literal block scalar style
# hosts format
whitelistdomain.com
allowlistdomain.com
# this is a regex
/^banners?[_.-]/
# definition: which groups should be applied for which client
Expand Down Expand Up @@ -242,7 +244,7 @@ minTlsServeVersion: 1.3
#certFile: server.crt
#keyFile: server.key

# optional: use these DNS servers to resolve blacklist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
# optional: use these DNS servers to resolve denylist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
bootstrapDns:
- tcp+udp:1.1.1.1
- https://1.1.1.1/dns-query
Expand Down
Loading

0 comments on commit bcd1381

Please sign in to comment.