feat(portforward): port redirection with VPN_PORT_FORWARDING_LISTENING_PORT

This commit is contained in:
Quentin McGaw
2023-11-10 17:21:35 +00:00
parent 8318be3159
commit 4105f74ce1
14 changed files with 226 additions and 6 deletions

View File

@@ -18,6 +18,8 @@ type Routing interface {
type PortAllower interface {
SetAllowedPort(ctx context.Context, port uint16, intf string) (err error)
RemoveAllowedPort(ctx context.Context, port uint16) (err error)
RedirectPort(ctx context.Context, intf string, sourcePort,
destinationPort uint16) (err error)
}
type Logger interface {

View File

@@ -39,8 +39,9 @@ func NewLoop(settings settings.PortForwarding, routing Routing,
settings: Settings{
VPNIsUp: ptrTo(false),
Service: service.Settings{
Enabled: settings.Enabled,
Filepath: *settings.Filepath,
Enabled: settings.Enabled,
Filepath: *settings.Filepath,
ListeningPort: *settings.ListeningPort,
},
},
routing: routing,

View File

@@ -10,6 +10,8 @@ import (
type PortAllower interface {
SetAllowedPort(ctx context.Context, port uint16, intf string) (err error)
RemoveAllowedPort(ctx context.Context, port uint16) (err error)
RedirectPort(ctx context.Context, intf string, sourcePort,
destinationPort uint16) (err error)
}
type Routing interface {

View File

@@ -14,6 +14,7 @@ type Settings struct {
Filepath string
Interface string // needed for PIA and ProtonVPN, tun0 for example
ServerName string // needed for PIA
ListeningPort uint16
}
func (s Settings) Copy() (copied Settings) {
@@ -22,6 +23,7 @@ func (s Settings) Copy() (copied Settings) {
copied.Filepath = s.Filepath
copied.Interface = s.Interface
copied.ServerName = s.ServerName
copied.ListeningPort = s.ListeningPort
return copied
}
@@ -31,6 +33,7 @@ func (s *Settings) OverrideWith(update Settings) {
s.Filepath = gosettings.OverrideWithString(s.Filepath, update.Filepath)
s.Interface = gosettings.OverrideWithString(s.Interface, update.Interface)
s.ServerName = gosettings.OverrideWithString(s.ServerName, update.ServerName)
s.ListeningPort = gosettings.OverrideWithNumber(s.ListeningPort, update.ListeningPort)
}
var (

View File

@@ -40,6 +40,13 @@ func (s *Service) Start(ctx context.Context) (runError <-chan error, err error)
return nil, fmt.Errorf("allowing port in firewall: %w", err)
}
if s.settings.ListeningPort != 0 {
err = s.portAllower.RedirectPort(ctx, s.settings.Interface, port, s.settings.ListeningPort)
if err != nil {
return nil, fmt.Errorf("redirecting port in firewall: %w", err)
}
}
err = s.writePortForwardedFile(port)
if err != nil {
_ = s.cleanup()

View File

@@ -35,6 +35,15 @@ func (s *Service) cleanup() (err error) {
return fmt.Errorf("blocking previous port in firewall: %w", err)
}
if s.settings.ListeningPort != 0 {
ctx := context.Background()
const listeningPort = 0 // 0 to clear the redirection
err = s.portAllower.RedirectPort(ctx, s.settings.Interface, s.port, listeningPort)
if err != nil {
return fmt.Errorf("removing previous port redirection in firewall: %w", err)
}
}
s.port = 0
filepath := s.settings.Filepath