Skip to content

Commit

Permalink
feat(pf): VPN_PORT_FORWARDING_PROVIDER variable
Browse files Browse the repository at this point in the history
- Defaults to current provider in use
- Can be chosen from a list of providers with custom code implemented
  • Loading branch information
qdm12 committed Jun 28, 2023
1 parent 76a92b9 commit 969d1a9
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ ENV VPN_SERVICE_PROVIDER=pia \
# # Private Internet Access only:
PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET= \
VPN_PORT_FORWARDING=off \
VPN_PORT_FORWARDING_PROVIDER= \
VPN_PORT_FORWARDING_STATUS_FILE="/tmp/gluetun/forwarded_port" \
# # Cyberghost only:
OPENVPN_CERT= \
Expand Down
26 changes: 23 additions & 3 deletions internal/configuration/settings/portforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ type PortForwarding struct {
// Enabled is true if port forwarding should be activated.
// It cannot be nil for the internal state.
Enabled *bool `json:"enabled"`
// Provider is set to specify which custom port forwarding code
// should be used. This is especially necessary for the custom
// provider using Wireguard for a provider where Wireguard is not
// natively supported but custom port forwading code is available.
// It defaults to the empty string, meaning the current provider
// should be the one used for port forwarding.
// It cannot be nil for the internal state.
Provider *string `json:"provider"`
// Filepath is the port forwarding status file path
// to use. It can be the empty string to indicate not
// to write to a file. It cannot be nil for the
Expand All @@ -27,9 +35,13 @@ func (p PortForwarding) validate(vpnProvider string) (err error) {
return nil
}

// Validate Enabled
// Validate current provider or custom provider specified
providerSelected := vpnProvider
if *p.Provider != "" {
providerSelected = *p.Provider
}
validProviders := []string{providers.PrivateInternetAccess}
if err = validate.IsOneOf(vpnProvider, validProviders...); err != nil {
if err = validate.IsOneOf(providerSelected, validProviders...); err != nil {
return fmt.Errorf("%w: %w", ErrPortForwardingEnabled, err)
}

Expand All @@ -47,22 +59,26 @@ func (p PortForwarding) validate(vpnProvider string) (err error) {
func (p *PortForwarding) copy() (copied PortForwarding) {
return PortForwarding{
Enabled: gosettings.CopyPointer(p.Enabled),
Provider: gosettings.CopyPointer(p.Provider),
Filepath: gosettings.CopyPointer(p.Filepath),
}
}

func (p *PortForwarding) mergeWith(other PortForwarding) {
p.Enabled = gosettings.MergeWithPointer(p.Enabled, other.Enabled)
p.Provider = gosettings.MergeWithPointer(p.Provider, other.Provider)
p.Filepath = gosettings.MergeWithPointer(p.Filepath, other.Filepath)
}

func (p *PortForwarding) overrideWith(other PortForwarding) {
p.Enabled = gosettings.OverrideWithPointer(p.Enabled, other.Enabled)
p.Provider = gosettings.OverrideWithPointer(p.Provider, other.Provider)
p.Filepath = gosettings.OverrideWithPointer(p.Filepath, other.Filepath)
}

func (p *PortForwarding) setDefaults() {
p.Enabled = gosettings.DefaultPointer(p.Enabled, false)
p.Provider = gosettings.DefaultPointer(p.Provider, "")
p.Filepath = gosettings.DefaultPointer(p.Filepath, "/tmp/gluetun/forwarded_port")
}

Expand All @@ -76,7 +92,11 @@ func (p PortForwarding) toLinesNode() (node *gotree.Node) {
}

node = gotree.New("Automatic port forwarding settings:")
node.Appendf("Enabled: yes")
if *p.Provider == "" {
node.Appendf("Use port forwarding code for current provider")
} else {
node.Appendf("Use code for provider: %s", *p.Provider)
}

filepath := *p.Filepath
if filepath == "" {
Expand Down
2 changes: 2 additions & 0 deletions internal/configuration/sources/env/portforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func (s *Source) readPortForward() (
return portForwarding, err
}

portForwarding.Provider = s.env.Get("VPN_PORT_FORWARDING_PROVIDER")

portForwarding.Filepath = s.env.Get("VPN_PORT_FORWARDING_STATUS_FILE",
env.ForceLowercase(false),
env.RetroKeys(
Expand Down
8 changes: 7 additions & 1 deletion internal/vpn/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
providerConf := l.providers.Get(*settings.Provider.Name)

portForwarding := *settings.Provider.PortForwarding.Enabled
customPortForwardingProvider := *settings.Provider.PortForwarding.Provider
portForwader := providerConf
if portForwarding && customPortForwardingProvider != "" {
portForwader = l.providers.Get(customPortForwardingProvider)
}

var vpnRunner interface {
Run(ctx context.Context, waitError chan<- error, tunnelReady chan<- struct{})
}
Expand All @@ -45,7 +51,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
tunnelUpData := tunnelUpData{
portForwarding: portForwarding,
serverName: serverName,
portForwarder: providerConf,
portForwarder: portForwader,
vpnIntf: vpnInterface,
}

Expand Down

0 comments on commit 969d1a9

Please sign in to comment.