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