feat(server): HTTP_CONTROL_SERVER_PORT to HTTP_CONTROL_SERVER_ADDRESS
This commit is contained in:
@@ -160,6 +160,8 @@ ENV VPNSP=pia \
|
||||
SHADOWSOCKS_PASSWORD= \
|
||||
SHADOWSOCKS_PASSWORD_SECRETFILE=/run/secrets/shadowsocks_password \
|
||||
SHADOWSOCKS_CIPHER=chacha20-ietf-poly1305 \
|
||||
# Control server
|
||||
HTTP_CONTROL_SERVER_ADDRESS=":8000" \
|
||||
# Server data updater
|
||||
UPDATER_PERIOD=0 \
|
||||
UPDATER_VPN_SERVICE_PROVIDERS= \
|
||||
|
||||
@@ -419,7 +419,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
go shadowsocksLooper.Run(shadowsocksCtx, shadowsocksDone)
|
||||
otherGroupHandler.Add(shadowsocksHandler)
|
||||
|
||||
controlServerAddress := fmt.Sprintf(":%d", *allSettings.ControlServer.Port)
|
||||
controlServerAddress := *allSettings.ControlServer.Address
|
||||
controlServerLogging := *allSettings.ControlServer.Log
|
||||
httpServerHandler, httpServerCtx, httpServerDone := goshutdown.NewGoRoutineHandler(
|
||||
"http server", goroutine.OptionTimeout(defaultShutdownTimeout))
|
||||
|
||||
@@ -4,6 +4,8 @@ import "errors"
|
||||
|
||||
var (
|
||||
ErrCityNotValid = errors.New("the city specified is not valid")
|
||||
ErrControlServerAddress = errors.New("listening address it not valid")
|
||||
ErrControlServerPort = errors.New("listening port it not valid")
|
||||
ErrControlServerPrivilegedPort = errors.New("cannot use privileged port without running as root")
|
||||
ErrCountryNotValid = errors.New("the country specified is not valid")
|
||||
ErrFirewallZeroPort = errors.New("cannot have a zero port to block")
|
||||
@@ -33,6 +35,7 @@ var (
|
||||
ErrSystemPGIDNotValid = errors.New("process group id is not valid")
|
||||
ErrSystemPUIDNotValid = errors.New("process user id is not valid")
|
||||
ErrSystemTimezoneNotValid = errors.New("timezone is not valid")
|
||||
ErrUpdaterPeriodTooSmall = errors.New("VPN server data updater period is too small")
|
||||
ErrVPNProviderNameNotValid = errors.New("VPN provider name is not valid")
|
||||
ErrVPNTypeNotValid = errors.New("VPN type is not valid")
|
||||
ErrWireguardEndpointIPNotSet = errors.New("endpoint IP is not set")
|
||||
@@ -46,6 +49,4 @@ var (
|
||||
ErrWireguardPrivateKeyNotValid = errors.New("private key is not valid")
|
||||
ErrWireguardPublicKeyNotSet = errors.New("public key is not set")
|
||||
ErrWireguardPublicKeyNotValid = errors.New("public key is not valid")
|
||||
|
||||
ErrUpdaterPeriodTooSmall = errors.New("VPN server data updater period is too small")
|
||||
)
|
||||
|
||||
@@ -2,7 +2,9 @@ package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||
"github.com/qdm12/gotree"
|
||||
@@ -10,22 +12,30 @@ import (
|
||||
|
||||
// ControlServer contains settings to customize the control server operation.
|
||||
type ControlServer struct {
|
||||
// Port is the listening port to use.
|
||||
// It can be set to 0 to bind to a random port.
|
||||
// Address is the listening address to use.
|
||||
// It cannot be nil in the internal state.
|
||||
// TODO change to address
|
||||
Port *uint16
|
||||
Address *string
|
||||
// Log can be true or false to enable logging on requests.
|
||||
// It cannot be nil in the internal state.
|
||||
Log *bool
|
||||
}
|
||||
|
||||
func (c ControlServer) validate() (err error) {
|
||||
_, portStr, err := net.SplitHostPort(*c.Address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrControlServerAddress, err)
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrControlServerPort, err)
|
||||
}
|
||||
|
||||
uid := os.Getuid()
|
||||
const maxPrivilegedPort uint16 = 1023
|
||||
if uid != 0 && *c.Port <= maxPrivilegedPort {
|
||||
const maxPrivilegedPort = 1023
|
||||
if uid != 0 && port <= maxPrivilegedPort {
|
||||
return fmt.Errorf("%w: %d when running with user ID %d",
|
||||
ErrControlServerPrivilegedPort, *c.Port, uid)
|
||||
ErrControlServerPrivilegedPort, port, uid)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -33,15 +43,15 @@ func (c ControlServer) validate() (err error) {
|
||||
|
||||
func (c *ControlServer) copy() (copied ControlServer) {
|
||||
return ControlServer{
|
||||
Port: helpers.CopyUint16Ptr(c.Port),
|
||||
Log: helpers.CopyBoolPtr(c.Log),
|
||||
Address: helpers.CopyStringPtr(c.Address),
|
||||
Log: helpers.CopyBoolPtr(c.Log),
|
||||
}
|
||||
}
|
||||
|
||||
// mergeWith merges the other settings into any
|
||||
// unset field of the receiver settings object.
|
||||
func (c *ControlServer) mergeWith(other ControlServer) {
|
||||
c.Port = helpers.MergeWithUint16(c.Port, other.Port)
|
||||
c.Address = helpers.MergeWithStringPtr(c.Address, other.Address)
|
||||
c.Log = helpers.MergeWithBool(c.Log, other.Log)
|
||||
}
|
||||
|
||||
@@ -49,13 +59,12 @@ func (c *ControlServer) mergeWith(other ControlServer) {
|
||||
// settings object with any field set in the other
|
||||
// settings.
|
||||
func (c *ControlServer) overrideWith(other ControlServer) {
|
||||
c.Port = helpers.MergeWithUint16(c.Port, other.Port)
|
||||
c.Log = helpers.MergeWithBool(c.Log, other.Log)
|
||||
c.Address = helpers.OverrideWithStringPtr(c.Address, other.Address)
|
||||
c.Log = helpers.OverrideWithBool(c.Log, other.Log)
|
||||
}
|
||||
|
||||
func (c *ControlServer) setDefaults() {
|
||||
const defaultPort = 8000
|
||||
c.Port = helpers.DefaultUint16(c.Port, defaultPort)
|
||||
c.Address = helpers.DefaultStringPtr(c.Address, ":8000")
|
||||
c.Log = helpers.DefaultBool(c.Log, true)
|
||||
}
|
||||
|
||||
@@ -65,7 +74,7 @@ func (c ControlServer) String() string {
|
||||
|
||||
func (c ControlServer) toLinesNode() (node *gotree.Node) {
|
||||
node = gotree.New("Control server settings:")
|
||||
node.Appendf("Listening port: %d", *c.Port)
|
||||
node.Appendf("Listening address: %s", *c.Address)
|
||||
node.Appendf("Logging: %s", helpers.BoolPtrToYesNo(c.Log))
|
||||
return node
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func Test_Settings_String(t *testing.T) {
|
||||
├── HTTP proxy settings:
|
||||
| └── Enabled: no
|
||||
├── Control server settings:
|
||||
| ├── Listening port: 8000
|
||||
| ├── Listening address: :8000
|
||||
| └── Logging: yes
|
||||
├── OS Alpine settings:
|
||||
| ├── Process UID: 1000
|
||||
|
||||
2
internal/configuration/sources/env/reader.go
vendored
2
internal/configuration/sources/env/reader.go
vendored
@@ -77,7 +77,7 @@ func (r *Reader) Read() (settings settings.Settings, err error) {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
settings.ControlServer, err = readControlServer()
|
||||
settings.ControlServer, err = r.readControlServer()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
28
internal/configuration/sources/env/server.go
vendored
28
internal/configuration/sources/env/server.go
vendored
@@ -9,13 +9,13 @@ import (
|
||||
"github.com/qdm12/govalid/port"
|
||||
)
|
||||
|
||||
func readControlServer() (controlServer settings.ControlServer, err error) {
|
||||
func (r *Reader) readControlServer() (controlServer settings.ControlServer, err error) {
|
||||
controlServer.Log, err = readControlServerLog()
|
||||
if err != nil {
|
||||
return controlServer, err
|
||||
}
|
||||
|
||||
controlServer.Port, err = readControlServerPort()
|
||||
controlServer.Address, err = r.readControlServerAddress()
|
||||
if err != nil {
|
||||
return controlServer, err
|
||||
}
|
||||
@@ -37,17 +37,23 @@ func readControlServerLog() (enabled *bool, err error) {
|
||||
return &log, nil
|
||||
}
|
||||
|
||||
func readControlServerPort() (p *uint16, err error) {
|
||||
func (r *Reader) readControlServerAddress() (address *string, err error) {
|
||||
// Retro-compatibility
|
||||
s := os.Getenv("HTTP_CONTROL_SERVER_PORT")
|
||||
if s != "" {
|
||||
r.onRetroActive("HTTP_CONTROL_SERVER_PORT", "HTTP_CONTROL_SERVER_ADDRESS")
|
||||
port, err := port.Validate(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("environment variable HTTP_CONTROL_SERVER_PORT: %w", err)
|
||||
}
|
||||
address = new(string)
|
||||
*address = ":" + fmt.Sprint(port)
|
||||
return address, nil
|
||||
}
|
||||
|
||||
s = os.Getenv("HTTP_CONTROL_SERVER_ADDRESS")
|
||||
if s == "" {
|
||||
return nil, nil //nolint:nilnil
|
||||
}
|
||||
|
||||
p = new(uint16)
|
||||
*p, err = port.Validate(s, port.OptionPortListening(os.Geteuid()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("environment variable HTTP_CONTROL_SERVER_PORT: %w", err)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user