feat: configuration to enable/disable external interfaces

This commit is contained in:
Dimitri Herzog 2023-10-13 14:28:55 +00:00
parent 9f49291177
commit 70399fdaa6
6 changed files with 98 additions and 25 deletions

View File

@ -212,6 +212,7 @@ type Config struct {
Filtering FilteringConfig `yaml:"filtering"`
Ede EdeConfig `yaml:"ede"`
SUDN SUDNConfig `yaml:"specialUseDomains"`
Interfaces InterfacesConfig `yaml:"interfaces"`
// Deprecated options
Deprecated struct {

15
config/interfaces.go Normal file
View File

@ -0,0 +1,15 @@
package config
// InterfacesConfig configuration for blocky's interfaces (REST, DoH, ...)
type InterfacesConfig struct {
Rest RESTConfig `yaml:"rest"`
DoH DoHConfig `yaml:"dns-over-http"`
}
type RESTConfig struct {
Enable bool `yaml:"enable" default:"true"`
}
type DoHConfig struct {
Enable bool `yaml:"enable" default:"true"`
}

View File

@ -331,3 +331,12 @@ specialUseDomains:
# optional: block recomended private TLDs
# default: true
rfc6762-appendixG: true
# optional: configuration for external interfaces
interfaces:
rest:
# optional: if true and http port is defined, provides REST API to control blocky. Default: true
enable: false
dns-over-http:
# optional: if true and http port is defined, provides DNS-over-HTTP endpoint. Default: true
enable: true

View File

@ -12,7 +12,7 @@ configuration properties as [JSON](config.yml).
## Basic configuration
| Parameter | Type | Mandatory | Default value | Description |
|---------------------|---------------------|-----------|---------------|------------------------------------------------------------------------------------------------------------|
| ------------------- | ------------------- | --------- | ------------- | ---------------------------------------------------------------------------------------------------------- |
| certFile | path | no | | Path to cert and key file for SSL encryption (DoH and DoT); if empty, self-signed certificate is generated |
| keyFile | path | no | | Path to cert and key file for SSL encryption (DoH and DoT); if empty, self-signed certificate is generated |
| dohUserAgent | string | no | | HTTP User Agent for DoH upstreams |
@ -31,8 +31,8 @@ configuration properties as [JSON](config.yml).
All logging port are optional.
| Parameter | Type | Default value | Description |
|------------|------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Parameter | Type | Default value | Description |
| ----------- | ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ports.dns | [IP]:port[,[IP]:port]* | 53 | Port(s) and optional bind ip address(es) to serve DNS endpoint (TCP and UDP). If you wish to specify a specific IP, you can do so such as `192.168.0.1:53`. Example: `53`, `:53`, `127.0.0.1:53,[::1]:53` |
| ports.tls | [IP]:port[,[IP]:port]* | | Port(s) and optional bind ip address(es) to serve DoT DNS endpoint (DNS-over-TLS). If you wish to specify a specific IP, you can do so such as `192.168.0.1:853`. Example: `83`, `:853`, `127.0.0.1:853,[::1]:853` |
| ports.http | [IP]:port[,[IP]:port]* | | Port(s) and optional bind ip address(es) to serve HTTP used for prometheus metrics, pprof, REST API, DoH... If you wish to specify a specific IP, you can do so such as `192.168.0.1:4000`. Example: `4000`, `:4000`, `127.0.0.1:4000,[::1]:4000` |
@ -47,12 +47,35 @@ All logging port are optional.
https: 443
```
## Interfaces
Blocky listens on port 53 (or other user defined port, see `ports.dns`) and accepts plain DNS queries vie UDP and TCP. If `ports.tls` is defined, it will also provide DoT (DNS-over-TLS) endpoint.
If `ports.http` or `ports.https` is defined, blocky will provide a REST API to control blocky and the DNS-over-HTTP interface by default. See [Interfaces](interfaces.md) for more details.
You can disable the REST API and the DNS-over-HTTP interface if needed by configuring:
!!! example
```yaml
interfaces:
rest:
enable: false
dns-over-http:
enable: false
```
!!! note
Both interfaces are enabled by default if HTTP/HTTPS port is configured
## Logging configuration
All logging options are optional.
| Parameter | Type | Default value | Description |
|---------------|---------------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------- | ------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| log.level | enum (debug, info, warn, error) | info | Log level |
| log.format | enum (text, json) | text | Log format (text or json). |
| log.timestamp | bool | true | Log time stamps (true or false). |
@ -86,7 +109,7 @@ following network protocols (net part of the resolver URL):
Each resolver must be defined as a string in following format: `[net:]host:[port][/path][#commonName]`.
| Parameter | Type | Mandatory | Default value |
|------------|----------------------------------|-----------|---------------------------------------------------|
| ---------- | -------------------------------- | --------- | ------------------------------------------------- |
| net | enum (tcp+udp, tcp-tls or https) | no | tcp+udp |
| host | IP or hostname | yes | |
| port | int (1 - 65535) | no | 53 for udp/tcp, 853 for tcp-tls and 443 for https |
@ -178,7 +201,7 @@ These DNS servers are used to resolve upstream DoH and DoT servers that are spec
It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
| Parameter | Type | Mandatory | Default value | Description |
|-----------|----------------------|-----------------------------|---------------|--------------------------------------|
| --------- | -------------------- | --------------------------- | ------------- | ------------------------------------ |
| upstream | Upstream (see above) | no | | |
| ips | List of IPs | yes, if upstream is DoT/DoH | | Only valid if upstream is DoH or DoT |
@ -233,7 +256,7 @@ or define a domain name for your local device on order to use the HTTPS certific
domain must be separated by a comma.
| Parameter | Type | Mandatory | Default value |
|---------------------|-----------------------------------------|-----------|---------------|
| ------------------- | --------------------------------------- | --------- | ------------- |
| customTTL | duration (no unit is minutes) | no | 1h |
| rewrite | string: string (domain: domain) | no | |
| mapping | string: string (hostname: address list) | no | |
@ -467,7 +490,7 @@ You can configure, which response should be sent to the client, if a requested q
queries, NXDOMAIN for other types):
| blockType | Example | Description |
|------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ---------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| zeroIP | zeroIP | This is the default block type. Server returns 0.0.0.0 (or :: for IPv6) as result for A and AAAA queries |
| nxDomain | nxDomain | return NXDOMAIN as return code |
| custom IPs | 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344 | comma separated list of destination IP addresses. Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. |
@ -512,7 +535,7 @@ With following parameters you can tune the caching behavior:
Wrong values can significantly increase external DNS traffic or memory consumption.
| Parameter | Type | Mandatory | Default value | Description |
|-------------------------------|-----------------|-----------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ----------------------------- | --------------- | --------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| caching.minTime | duration format | no | 0 (use TTL) | How long a response must be cached (min value). If <=0, use response's TTL, if >0 use this value, if TTL is smaller |
| caching.maxTime | duration format | no | 0 (use TTL) | How long a response must be cached (max value). If <0, do not cache responses. If 0, use TTL. If > 0, use this value, if TTL is greater |
| caching.maxItemsCount | int | no | 0 (unlimited) | Max number of cache entries (responses) to be kept in cache (soft limit). Default (0): unlimited. Useful on systems with limited amount of RAM. |
@ -537,7 +560,7 @@ Blocky can synchronize its cache and blocking state between multiple instances t
Synchronization is disabled if no address is configured.
| Parameter | Type | Mandatory | Default value | Description |
|--------------------------|-----------------|-----------|---------------|---------------------------------------------------------------------|
| ------------------------ | --------------- | --------- | ------------- | ------------------------------------------------------------------- |
| redis.address | string | no | | Server address and port or master name if sentinel is used |
| redis.username | string | no | | Username if necessary |
| redis.password | string | no | | Password if necessary |
@ -574,7 +597,7 @@ Blocky can expose various metrics for prometheus. To use the prometheus feature,
see [Basic Configuration](#basic-configuration)).
| Parameter | Mandatory | Default value | Description |
|-------------------|-----------|---------------|-------------------------------------|
| ----------------- | --------- | ------------- | ----------------------------------- |
| prometheus.enable | no | false | If true, enables prometheus metrics |
| prometheus.path | no | /metrics | URL path to the metrics endpoint |
@ -623,7 +646,7 @@ You can choose which information from processed DNS request and response should
Configuration parameters:
| Parameter | Type | Mandatory | Default value | Description |
|---------------------------|--------------------------------------------------------------------------------------|-----------|---------------|------------------------------------------------------------------------------------|
| ------------------------- | ------------------------------------------------------------------------------------ | --------- | ------------- | ---------------------------------------------------------------------------------- |
| queryLog.type | enum (mysql, postgresql, csv, csv-client, console, none (see above)) | no | | Type of logging target. Console if empty |
| queryLog.target | string | no | | directory for writing the logs (for csv) or database url (for mysql or postgresql) |
| queryLog.logRetentionDays | int | no | 0 | if > 0, deletes log files/database entries which are older than ... days |
@ -668,7 +691,7 @@ You can enable resolving of entries, located in local hosts file.
Configuration parameters:
| Parameter | Type | Mandatory | Default value | Description |
|--------------------------|--------------------------------|-----------|---------------|-------------------------------------------------|
| ------------------------ | ------------------------------ | --------- | ------------- | ----------------------------------------------- |
| hostsFile.filePath | string | no | | Path to hosts file (e.g. /etc/hosts on Linux) |
| hostsFile.hostsTTL | duration (no units is minutes) | no | 1h | TTL |
| hostsFile.refreshPeriod | duration format | no | 1h | Time between hosts file refresh |
@ -690,7 +713,7 @@ DNS responses can be extended with EDE codes according to [RFC8914](https://data
Configuration parameters:
| Parameter | Type | Mandatory | Default value | Description |
|------------|------|-----------|---------------|----------------------------------------------------|
| ---------- | ---- | --------- | ------------- | -------------------------------------------------- |
| ede.enable | bool | no | false | If true, DNS responses are deliverd with EDE codes |
!!! example
@ -708,7 +731,7 @@ Some RFCs have optional recommendations, which are configurable as described bel
Configuration parameters:
| Parameter | Type | Mandatory | Default value | Description |
|-------------------------------------|------|-----------|---------------|-----------------------------------------------------------------------------------------------|
| ----------------------------------- | ---- | --------- | ------------- | --------------------------------------------------------------------------------------------- |
| specialUseDomains.rfc6762-appendixG | bool | no | true | Block TLDs listed in [RFC 6762 Appendix G](https://www.rfc-editor.org/rfc/rfc6762#appendix-G) |
!!! example
@ -787,7 +810,7 @@ A value of zero or less will disable this feature.
Configures how HTTP(S) sources are downloaded:
| Parameter | Type | Mandatory | Default value | Description |
|-----------|----------|-----------|---------------|------------------------------------------------|
| --------- | -------- | --------- | ------------- | ---------------------------------------------- |
| timeout | duration | no | 5s | Download attempt timeout |
| attempts | int | no | 3 | How many download attempts should be performed |
| cooldown | duration | no | 500ms | Time between the download attempts |
@ -808,7 +831,7 @@ This configures how Blocky startup works.
The default strategy is blocking.
| strategy | Description |
|-------------|------------------------------------------------------------------------------------------------------------------------------------------|
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| blocking | all sources are loaded before DNS resolution starts |
| failOnError | like blocking but blocky will shut down if any source fails to load |
| fast | blocky starts serving DNS immediately and sources are loaded asynchronously. The features requiring the sources should enable soon after |

View File

@ -65,22 +65,39 @@ func (s *Server) createOpenAPIInterfaceImpl() (impl api.StrictServerInterface, e
}
func (s *Server) registerAPIEndpoints(router *chi.Mux) error {
if s.cfg.Interfaces.Rest.Enable {
err := s.registerOpenAPIEndpoints(router)
if err != nil {
return fmt.Errorf("unable to register OpenAPI endpoints %w", err)
}
}
s.registerDohEndpoints(router)
return nil
}
func (s *Server) registerDohEndpoints(router *chi.Mux) {
const pathDohQuery = "/dns-query"
if s.cfg.Interfaces.DoH.Enable {
router.Get(pathDohQuery, s.dohGetRequestHandler)
router.Get(pathDohQuery+"/", s.dohGetRequestHandler)
router.Get(pathDohQuery+"/{clientID}", s.dohGetRequestHandler)
router.Post(pathDohQuery, s.dohPostRequestHandler)
router.Post(pathDohQuery+"/", s.dohPostRequestHandler)
router.Post(pathDohQuery+"/{clientID}", s.dohPostRequestHandler)
}
}
func (s *Server) registerOpenAPIEndpoints(router *chi.Mux) error {
openAPIImpl, err := s.createOpenAPIInterfaceImpl()
if err != nil {
return err
return fmt.Errorf("unable to create OpenAPI server implementation %w", err)
}
api.RegisterOpenAPIEndpoints(router, openAPIImpl)
router.Get(pathDohQuery, s.dohGetRequestHandler)
router.Get(pathDohQuery+"/", s.dohGetRequestHandler)
router.Get(pathDohQuery+"/{clientID}", s.dohGetRequestHandler)
router.Post(pathDohQuery, s.dohPostRequestHandler)
router.Post(pathDohQuery+"/", s.dohPostRequestHandler)
router.Post(pathDohQuery+"/{clientID}", s.dohPostRequestHandler)
return nil
}

View File

@ -164,6 +164,14 @@ var _ = BeforeSuite(func() {
Enable: true,
Path: "/metrics",
},
Interfaces: config.InterfacesConfig{
Rest: config.RESTConfig{
Enable: true,
},
DoH: config.DoHConfig{
Enable: true,
},
},
})
Expect(err).Should(Succeed())