Skip to content

Commit 39f5c50

Browse files
committed
Pull request: home: http conf
Updates #2860. Squashed commit of the following: commit 0d55a99 Merge: 73a203a d4a4bda Author: Dimitry Kolyshev <[email protected]> Date: Thu Jun 29 16:25:36 2023 +0400 Merge remote-tracking branch 'origin/master' into http-yaml-conf commit 73a203a Author: Dimitry Kolyshev <[email protected]> Date: Thu Jun 29 16:21:48 2023 +0400 home: imp docs commit a4819ac Author: Dimitry Kolyshev <[email protected]> Date: Thu Jun 29 11:45:30 2023 +0400 snap: imp script commit b0913c7 Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 17:34:03 2023 +0400 all: docs commit 14820d6 Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 13:21:43 2023 +0400 home: imp tests commit 9db800d Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 13:17:34 2023 +0400 all: docs commit 9174a0a Merge: ca8c4ae d881813 Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 10:19:01 2023 +0400 Merge remote-tracking branch 'origin/master' into http-yaml-conf # Conflicts: # CHANGELOG.md # internal/home/upgrade.go # internal/home/upgrade_test.go commit ca8c4ae Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 10:07:15 2023 +0400 snap: imp script commit d84473f Author: Dimitry Kolyshev <[email protected]> Date: Wed Jun 28 09:59:57 2023 +0400 snap: imp script commit 8a0808e Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 15:03:53 2023 +0400 home: http conf commit e8fbb89 Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 14:59:37 2023 +0400 home: imp code commit 46541aa Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 12:36:14 2023 +0400 snap: bind port commit cecda5f Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 12:12:39 2023 +0400 docker: bind port commit 8d8945b Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 11:06:32 2023 +0400 home: imp code commit ae5e8c1 Author: Dimitry Kolyshev <[email protected]> Date: Tue Jun 27 11:02:09 2023 +0400 home: imp code commit c9ee460 Author: Dimitry Kolyshev <[email protected]> Date: Mon Jun 26 17:11:10 2023 +0400 home: imp code commit 44c7244 Author: Dimitry Kolyshev <[email protected]> Date: Mon Jun 26 11:52:19 2023 +0400 all: docs commit e3bf5fa Merge: 38cc0f6 e7e6384 Author: Dimitry Kolyshev <[email protected]> Date: Mon Jun 26 11:39:12 2023 +0400 Merge remote-tracking branch 'origin/master' into http-yaml-conf commit 38cc0f6 Author: Dimitry Kolyshev <[email protected]> Date: Mon Jun 26 11:38:17 2023 +0400 snap: bind port commit 3b9cb9e Author: Dimitry Kolyshev <[email protected]> Date: Mon Jun 26 11:25:03 2023 +0400 docker: bind port ... and 4 more commits
1 parent d4a4bda commit 39f5c50

File tree

12 files changed

+246
-76
lines changed

12 files changed

+246
-76
lines changed

CHANGELOG.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,27 @@ NOTE: Add new changes BELOW THIS COMMENT.
3737

3838
#### Configuration Changes
3939

40-
In this release, the schema version has changed from 20 to 22.
40+
In this release, the schema version has changed from 20 to 23.
4141

42+
- Properties `bind_host`, `bind_port`, and `web_session_ttl` which used to setup
43+
web UI binding configuration, are now moved to a new object `http` containing
44+
new properties `address` and `session_ttl`:
45+
46+
```yaml
47+
# BEFORE:
48+
'bind_host': '1.2.3.4'
49+
'bind_port': 8080
50+
'web_session_ttl': 720
51+
52+
# AFTER:
53+
'http':
54+
'address': '1.2.3.4:8080'
55+
'session_ttl': '720h'
56+
```
57+
58+
Note that the new `http.session_ttl` property is now a duration string. To
59+
rollback this change, remove the new object `http`, set back `bind_host`,
60+
`bind_port`, `web_session_ttl`, and change the `schema_version` back to `22`.
4261
- Property `clients.persistent.blocked_services`, which in schema versions 21
4362
and earlier used to be a list containing ids of blocked services, is now an
4463
object containing ids and schedule for blocked services:

docker/web-bind.awk

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
# Don't consider the HTTPS hostname since the enforced HTTPS redirection should
22
# work if the SSL check skipped. See file docker/healthcheck.sh.
3-
/^bind_host:/ { host = $2 }
3+
/^[^[:space:]]/ { is_http = /^http:/ }
44

5-
/^bind_port:/ { port = $2 }
6-
7-
END {
8-
if (match(host, ":")) {
9-
print "http://[" host "]:" port
10-
} else {
11-
print "http://" host ":" port
12-
}
13-
}
5+
/^[[:space:]]+address:/ { if (is_http) print "http://" $2 }

internal/home/config.go

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,17 @@ type clientSourcesConfig struct {
9191
HostsFile bool `yaml:"hosts"`
9292
}
9393

94-
// configuration is loaded from YAML
95-
// field ordering is important -- yaml fields will mirror ordering from here
94+
// configuration is loaded from YAML.
95+
//
96+
// Field ordering is important, YAML fields better not to be reordered, if it's
97+
// not absolutely necessary.
9698
type configuration struct {
9799
// Raw file data to avoid re-reading of configuration file
98100
// It's reset after config is parsed
99101
fileData []byte
100102

101-
// BindHost is the address for the web interface server to listen on.
102-
BindHost netip.Addr `yaml:"bind_host"`
103-
// BindPort is the port for the web interface server to listen on.
104-
BindPort int `yaml:"bind_port"`
105-
103+
// HTTPConfig is the block with http conf.
104+
HTTPConfig httpConfig `yaml:"http"`
106105
// Users are the clients capable for accessing the web interface.
107106
Users []webUser `yaml:"users"`
108107
// AuthAttempts is the maximum number of failed login attempts a user
@@ -120,10 +119,6 @@ type configuration struct {
120119
// DebugPProf defines if the profiling HTTP handler will listen on :6060.
121120
DebugPProf bool `yaml:"debug_pprof"`
122121

123-
// TTL for a web session (in hours)
124-
// An active session is automatically refreshed once a day.
125-
WebSessionTTLHours uint32 `yaml:"web_session_ttl"`
126-
127122
DNS dnsConfig `yaml:"dns"`
128123
TLS tlsConfigSettings `yaml:"tls"`
129124
QueryLog queryLogConfig `yaml:"querylog"`
@@ -156,7 +151,23 @@ type configuration struct {
156151
SchemaVersion int `yaml:"schema_version"` // keeping last so that users will be less tempted to change it -- used when upgrading between versions
157152
}
158153

159-
// field ordering is important -- yaml fields will mirror ordering from here
154+
// httpConfig is a block with HTTP configuration params.
155+
//
156+
// Field ordering is important, YAML fields better not to be reordered, if it's
157+
// not absolutely necessary.
158+
type httpConfig struct {
159+
// Address is the address to serve the web UI on.
160+
Address netip.AddrPort
161+
162+
// SessionTTL for a web session.
163+
// An active session is automatically refreshed once a day.
164+
SessionTTL timeutil.Duration `yaml:"session_ttl"`
165+
}
166+
167+
// dnsConfig is a block with DNS configuration params.
168+
//
169+
// Field ordering is important, YAML fields better not to be reordered, if it's
170+
// not absolutely necessary.
160171
type dnsConfig struct {
161172
BindHosts []netip.Addr `yaml:"bind_hosts"`
162173
Port int `yaml:"port"`
@@ -261,11 +272,12 @@ type statsConfig struct {
261272
//
262273
// TODO(a.garipov, e.burkov): This global is awful and must be removed.
263274
var config = &configuration{
264-
BindPort: 3000,
265-
BindHost: netip.IPv4Unspecified(),
266-
AuthAttempts: 5,
267-
AuthBlockMin: 15,
268-
WebSessionTTLHours: 30 * 24,
275+
AuthAttempts: 5,
276+
AuthBlockMin: 15,
277+
HTTPConfig: httpConfig{
278+
Address: netip.AddrPortFrom(netip.IPv4Unspecified(), 3000),
279+
SessionTTL: timeutil.Duration{Duration: 30 * timeutil.Day},
280+
},
269281
DNS: dnsConfig{
270282
BindHosts: []netip.Addr{netip.IPv4Unspecified()},
271283
Port: defaultPortDNS,
@@ -427,8 +439,8 @@ func readLogSettings() (ls *logSettings) {
427439
// validateBindHosts returns error if any of binding hosts from configuration is
428440
// not a valid IP address.
429441
func validateBindHosts(conf *configuration) (err error) {
430-
if !conf.BindHost.IsValid() {
431-
return errors.Error("bind_host is not a valid ip address")
442+
if !conf.HTTPConfig.Address.IsValid() {
443+
return errors.Error("http.address is not a valid ip address")
432444
}
433445

434446
for i, addr := range conf.DNS.BindHosts {
@@ -462,7 +474,7 @@ func parseConfig() (err error) {
462474
}
463475

464476
tcpPorts := aghalg.UniqChecker[tcpPort]{}
465-
addPorts(tcpPorts, tcpPort(config.BindPort))
477+
addPorts(tcpPorts, tcpPort(config.HTTPConfig.Address.Port()))
466478

467479
udpPorts := aghalg.UniqChecker[udpPort]{}
468480
addPorts(udpPorts, udpPort(config.DNS.Port))

internal/home/control.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type statusResponse struct {
103103
Language string `json:"language"`
104104
DNSAddrs []string `json:"dns_addresses"`
105105
DNSPort int `json:"dns_port"`
106-
HTTPPort int `json:"http_port"`
106+
HTTPPort uint16 `json:"http_port"`
107107

108108
// ProtectionDisabledDuration is the duration of the protection pause in
109109
// milliseconds.
@@ -158,7 +158,7 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
158158
Language: config.Language,
159159
DNSAddrs: dnsAddrs,
160160
DNSPort: config.DNS.Port,
161-
HTTPPort: config.BindPort,
161+
HTTPPort: config.HTTPConfig.Address.Port(),
162162
ProtectionDisabledDuration: protectionDisabledDuration,
163163
ProtectionEnabled: protectionEnabled,
164164
IsRunning: isRunning(),

internal/home/controlinstall.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ type checkConfResp struct {
9696
func (req *checkConfReq) validateWeb(tcpPorts aghalg.UniqChecker[tcpPort]) (err error) {
9797
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
9898

99-
portInt := req.Web.Port
100-
port := tcpPort(portInt)
99+
// TODO(a.garipov): Declare all port variables anywhere as uint16.
100+
reqPort := uint16(req.Web.Port)
101+
port := tcpPort(reqPort)
101102
addPorts(tcpPorts, port)
102103
if err = tcpPorts.Validate(); err != nil {
103104
// Reset the value for the port to 1 to make sure that validateDNS
@@ -108,15 +109,15 @@ func (req *checkConfReq) validateWeb(tcpPorts aghalg.UniqChecker[tcpPort]) (err
108109
return err
109110
}
110111

111-
switch portInt {
112-
case 0, config.BindPort:
112+
switch reqPort {
113+
case 0, config.HTTPConfig.Address.Port():
113114
return nil
114115
default:
115116
// Go on and check the port binding only if it's not zero or won't be
116117
// unbound after install.
117118
}
118119

119-
return aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, uint16(portInt)))
120+
return aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, reqPort))
120121
}
121122

122123
// validateDNS returns error if the DNS part of the initial configuration can't
@@ -127,11 +128,11 @@ func (req *checkConfReq) validateDNS(
127128
) (canAutofix bool, err error) {
128129
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
129130

130-
port := req.DNS.Port
131+
port := uint16(req.DNS.Port)
131132
switch port {
132133
case 0:
133134
return false, nil
134-
case config.BindPort:
135+
case config.HTTPConfig.Address.Port():
135136
// Go on and only check the UDP port since the TCP one is already bound
136137
// by AdGuard Home for web interface.
137138
default:
@@ -318,8 +319,7 @@ type applyConfigReq struct {
318319
// copyInstallSettings copies the installation parameters between two
319320
// configuration structures.
320321
func copyInstallSettings(dst, src *configuration) {
321-
dst.BindHost = src.BindHost
322-
dst.BindPort = src.BindPort
322+
dst.HTTPConfig = src.HTTPConfig
323323
dst.DNS.BindHosts = src.DNS.BindHosts
324324
dst.DNS.Port = src.DNS.Port
325325
}
@@ -413,8 +413,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
413413
copyInstallSettings(curConfig, config)
414414

415415
Context.firstRun = false
416-
config.BindHost = req.Web.IP
417-
config.BindPort = req.Web.Port
416+
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port))
418417
config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
419418
config.DNS.Port = req.DNS.Port
420419

@@ -487,7 +486,8 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
487486
return nil, false, errors.Error("ports cannot be 0")
488487
}
489488

490-
restartHTTP = config.BindHost != req.Web.IP || config.BindPort != req.Web.Port
489+
addrPort := config.HTTPConfig.Address
490+
restartHTTP = addrPort.Addr() != req.Web.IP || int(addrPort.Port()) != req.Web.Port
491491
if restartHTTP {
492492
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port)))
493493
if err != nil {

internal/home/controlupdate.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ func (vr *versionResponse) setAllowedToAutoUpdate() (err error) {
157157
Context.tls.WriteDiskConfig(tlsConf)
158158

159159
canUpdate := true
160-
if tlsConfUsesPrivilegedPorts(tlsConf) || config.BindPort < 1024 || config.DNS.Port < 1024 {
160+
if tlsConfUsesPrivilegedPorts(tlsConf) ||
161+
config.HTTPConfig.Address.Port() < 1024 ||
162+
config.DNS.Port < 1024 {
161163
canUpdate, err = aghnet.CanBindPrivilegedPorts()
162164
if err != nil {
163165
return fmt.Errorf("checking ability to bind privileged ports: %w", err)

internal/home/home.go

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -372,25 +372,26 @@ func initContextClients() (err error) {
372372

373373
// setupBindOpts overrides bind host/port from the opts.
374374
func setupBindOpts(opts options) (err error) {
375-
if opts.bindPort != 0 {
376-
config.BindPort = opts.bindPort
375+
bindAddr := opts.bindAddr
376+
if bindAddr != (netip.AddrPort{}) {
377+
config.HTTPConfig.Address = bindAddr
377378

378-
err = checkPorts()
379-
if err != nil {
380-
// Don't wrap the error, because it's informative enough as is.
381-
return err
379+
if config.HTTPConfig.Address.Port() != 0 {
380+
err = checkPorts()
381+
if err != nil {
382+
// Don't wrap the error, because it's informative enough as is.
383+
return err
384+
}
382385
}
383-
}
384386

385-
if opts.bindHost.IsValid() {
386-
config.BindHost = opts.bindHost
387+
return nil
387388
}
388389

389-
// Rewrite deprecated options.
390-
bindAddr := opts.bindAddr
391-
if bindAddr.IsValid() {
392-
config.BindHost = bindAddr.Addr()
393-
config.BindPort = int(bindAddr.Port())
390+
if opts.bindPort != 0 {
391+
config.HTTPConfig.Address = netip.AddrPortFrom(
392+
config.HTTPConfig.Address.Addr(),
393+
uint16(opts.bindPort),
394+
)
394395

395396
err = checkPorts()
396397
if err != nil {
@@ -399,6 +400,13 @@ func setupBindOpts(opts options) (err error) {
399400
}
400401
}
401402

403+
if opts.bindHost.IsValid() {
404+
config.HTTPConfig.Address = netip.AddrPortFrom(
405+
opts.bindHost,
406+
config.HTTPConfig.Address.Port(),
407+
)
408+
}
409+
402410
return nil
403411
}
404412

@@ -480,7 +488,7 @@ func setupDNSFilteringConf(conf *filtering.Config) (err error) {
480488
// checkPorts is a helper for ports validation in config.
481489
func checkPorts() (err error) {
482490
tcpPorts := aghalg.UniqChecker[tcpPort]{}
483-
addPorts(tcpPorts, tcpPort(config.BindPort))
491+
addPorts(tcpPorts, tcpPort(config.HTTPConfig.Address.Port()))
484492

485493
udpPorts := aghalg.UniqChecker[udpPort]{}
486494
addPorts(udpPorts, udpPort(config.DNS.Port))
@@ -520,8 +528,8 @@ func initWeb(opts options, clientBuildFS fs.FS) (web *webAPI, err error) {
520528

521529
webConf := webConfig{
522530
firstRun: Context.firstRun,
523-
BindHost: config.BindHost,
524-
BindPort: config.BindPort,
531+
BindHost: config.HTTPConfig.Address.Addr(),
532+
BindPort: int(config.HTTPConfig.Address.Port()),
525533

526534
ReadTimeout: readTimeout,
527535
ReadHeaderTimeout: readHdrTimeout,
@@ -657,8 +665,8 @@ func initUsers() (auth *Auth, err error) {
657665
log.Info("authratelimiter is disabled")
658666
}
659667

660-
sessionTTL := config.WebSessionTTLHours * 60 * 60
661-
auth = InitAuth(sessFilename, config.Users, sessionTTL, rateLimiter)
668+
sessionTTL := config.HTTPConfig.SessionTTL.Seconds()
669+
auth = InitAuth(sessFilename, config.Users, uint32(sessionTTL), rateLimiter)
662670
if auth == nil {
663671
return nil, errors.Error("initializing auth module failed")
664672
}
@@ -936,7 +944,7 @@ func printHTTPAddresses(proto string) {
936944
Context.tls.WriteDiskConfig(&tlsConf)
937945
}
938946

939-
port := config.BindPort
947+
port := int(config.HTTPConfig.Address.Port())
940948
if proto == aghhttp.SchemeHTTPS {
941949
port = tlsConf.PortHTTPS
942950
}
@@ -948,9 +956,9 @@ func printHTTPAddresses(proto string) {
948956
return
949957
}
950958

951-
bindhost := config.BindHost
952-
if !bindhost.IsUnspecified() {
953-
printWebAddrs(proto, bindhost.String(), port)
959+
bindHost := config.HTTPConfig.Address.Addr()
960+
if !bindHost.IsUnspecified() {
961+
printWebAddrs(proto, bindHost.String(), port)
954962

955963
return
956964
}
@@ -961,14 +969,14 @@ func printHTTPAddresses(proto string) {
961969
// That's weird, but we'll ignore it.
962970
//
963971
// TODO(e.burkov): Find out when it happens.
964-
printWebAddrs(proto, bindhost.String(), port)
972+
printWebAddrs(proto, bindHost.String(), port)
965973

966974
return
967975
}
968976

969977
for _, iface := range ifaces {
970978
for _, addr := range iface.Addresses {
971-
printWebAddrs(proto, addr.String(), config.BindPort)
979+
printWebAddrs(proto, addr.String(), port)
972980
}
973981
}
974982
}

internal/home/tls.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ func (m *tlsManager) handleTLSValidate(w http.ResponseWriter, r *http.Request) {
320320

321321
if setts.Enabled {
322322
err = validatePorts(
323-
tcpPort(config.BindPort),
323+
tcpPort(config.HTTPConfig.Address.Port()),
324324
tcpPort(setts.PortHTTPS),
325325
tcpPort(setts.PortDNSOverTLS),
326326
tcpPort(setts.PortDNSCrypt),
@@ -407,7 +407,7 @@ func (m *tlsManager) handleTLSConfigure(w http.ResponseWriter, r *http.Request)
407407

408408
if req.Enabled {
409409
err = validatePorts(
410-
tcpPort(config.BindPort),
410+
tcpPort(config.HTTPConfig.Address.Port()),
411411
tcpPort(req.PortHTTPS),
412412
tcpPort(req.PortDNSOverTLS),
413413
tcpPort(req.PortDNSCrypt),

0 commit comments

Comments
 (0)