+ DNS: Get/Set DNS general settings

GET /control/dns_info
POST /control/dns_config
This commit is contained in:
Simon Zolin 2019-11-08 14:59:12 +03:00 committed by Ildar Kamalov
parent 92141e03c4
commit 26ccee47b5
3 changed files with 99 additions and 3 deletions

View File

@ -29,6 +29,9 @@ Contents:
* Static IP check/set * Static IP check/set
* Add a static lease * Add a static lease
* API: Reset DHCP configuration * API: Reset DHCP configuration
* DNS general settings
* API: Get DNS general settings
* API: Set DNS general settings
* DNS access settings * DNS access settings
* List access settings * List access settings
* Set access settings * Set access settings
@ -801,6 +804,42 @@ Response:
] ]
## DNS general settings
### API: Get DNS general settings
Request:
GET /control/dns_info
Response:
200 OK
{
"protection_enabled": true | false,
"ratelimit": 1234,
"blocking_mode": "nxdomain" | "null_ip",
}
### API: Set DNS general settings
Request:
POST /control/dns_config
{
"protection_enabled": true | false,
"ratelimit": 1234,
"blocking_mode": "nxdomain" | "null_ip",
}
Response:
200 OK
## DNS access settings ## DNS access settings
There are low-level settings that can block undesired DNS requests. "Blocking" means not responding to request. There are low-level settings that can block undesired DNS requests. "Blocking" means not responding to request.

View File

@ -101,7 +101,7 @@ type FilteringConfig struct {
BlockingMode string `yaml:"blocking_mode"` // mode how to answer filtered requests BlockingMode string `yaml:"blocking_mode"` // mode how to answer filtered requests
BlockedResponseTTL uint32 `yaml:"blocked_response_ttl"` // if 0, then default is used (3600) BlockedResponseTTL uint32 `yaml:"blocked_response_ttl"` // if 0, then default is used (3600)
Ratelimit int `yaml:"ratelimit"` // max number of requests per second from a given IP (0 to disable) Ratelimit uint32 `yaml:"ratelimit"` // max number of requests per second from a given IP (0 to disable)
RatelimitWhitelist []string `yaml:"ratelimit_whitelist"` // a list of whitelisted client IP addresses RatelimitWhitelist []string `yaml:"ratelimit_whitelist"` // a list of whitelisted client IP addresses
RefuseAny bool `yaml:"refuse_any"` // if true, refuse ANY requests RefuseAny bool `yaml:"refuse_any"` // if true, refuse ANY requests
BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only) BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only)
@ -214,7 +214,7 @@ func (s *Server) prepare(config *ServerConfig) error {
proxyConfig := proxy.Config{ proxyConfig := proxy.Config{
UDPListenAddr: s.conf.UDPListenAddr, UDPListenAddr: s.conf.UDPListenAddr,
TCPListenAddr: s.conf.TCPListenAddr, TCPListenAddr: s.conf.TCPListenAddr,
Ratelimit: s.conf.Ratelimit, Ratelimit: int(s.conf.Ratelimit),
RatelimitWhitelist: s.conf.RatelimitWhitelist, RatelimitWhitelist: s.conf.RatelimitWhitelist,
RefuseAny: s.conf.RefuseAny, RefuseAny: s.conf.RefuseAny,
CacheEnabled: true, CacheEnabled: true,

View File

@ -20,6 +20,62 @@ func httpError(r *http.Request, w http.ResponseWriter, code int, format string,
http.Error(w, text, code) http.Error(w, text, code)
} }
type dnsConfigJSON struct {
ProtectionEnabled bool `json:"protection_enabled"`
RateLimit uint32 `json:"ratelimit"`
BlockingMode string `json:"blocking_mode"`
}
func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) {
resp := dnsConfigJSON{}
s.RLock()
resp.ProtectionEnabled = s.conf.ProtectionEnabled
resp.BlockingMode = s.conf.BlockingMode
resp.RateLimit = s.conf.Ratelimit
s.RUnlock()
js, err := json.Marshal(resp)
if err != nil {
httpError(r, w, http.StatusInternalServerError, "json.Marshal: %s", err)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(js)
}
func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
req := dnsConfigJSON{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(r, w, http.StatusBadRequest, "json.Decode: %s", err)
return
}
if !(req.BlockingMode == "nxdomain" || req.BlockingMode == "null_ip") {
httpError(r, w, http.StatusBadRequest, "blocking_mode: value not supported")
return
}
restart := false
s.Lock()
s.conf.ProtectionEnabled = req.ProtectionEnabled
s.conf.BlockingMode = req.BlockingMode
if s.conf.Ratelimit != req.RateLimit {
restart = true
}
s.conf.Ratelimit = req.RateLimit
s.Unlock()
s.conf.ConfigModified()
if restart {
err = s.Restart()
if err != nil {
httpError(r, w, http.StatusInternalServerError, "%s", err)
return
}
}
}
func (s *Server) handleProtectionEnable(w http.ResponseWriter, r *http.Request) { func (s *Server) handleProtectionEnable(w http.ResponseWriter, r *http.Request) {
s.conf.ProtectionEnabled = true s.conf.ProtectionEnabled = true
s.conf.ConfigModified() s.conf.ConfigModified()
@ -270,6 +326,8 @@ func checkDNS(input string, bootstrap []string) error {
} }
func (s *Server) registerHandlers() { func (s *Server) registerHandlers() {
s.conf.HTTPRegister("GET", "/control/dns_info", s.handleGetConfig)
s.conf.HTTPRegister("POST", "/control/dns_config", s.handleSetConfig)
s.conf.HTTPRegister("POST", "/control/enable_protection", s.handleProtectionEnable) s.conf.HTTPRegister("POST", "/control/enable_protection", s.handleProtectionEnable)
s.conf.HTTPRegister("POST", "/control/disable_protection", s.handleProtectionDisable) s.conf.HTTPRegister("POST", "/control/disable_protection", s.handleProtectionDisable)
s.conf.HTTPRegister("POST", "/control/set_upstreams_config", s.handleSetUpstreamConfig) s.conf.HTTPRegister("POST", "/control/set_upstreams_config", s.handleSetUpstreamConfig)
@ -277,5 +335,4 @@ func (s *Server) registerHandlers() {
s.conf.HTTPRegister("GET", "/control/access/list", s.handleAccessList) s.conf.HTTPRegister("GET", "/control/access/list", s.handleAccessList)
s.conf.HTTPRegister("POST", "/control/access/set", s.handleAccessSet) s.conf.HTTPRegister("POST", "/control/access/set", s.handleAccessSet)
} }