feat(server): HTTP_CONTROL_SERVER_PORT to HTTP_CONTROL_SERVER_ADDRESS

This commit is contained in:
Quentin McGaw
2022-01-27 23:15:08 +00:00
parent f3692cd47f
commit 1b585159d1
7 changed files with 49 additions and 31 deletions

View File

@@ -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= \

View File

@@ -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))

View File

@@ -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")
)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}