diff --git a/Dockerfile b/Dockerfile index 049b59d7..74c44127 100644 --- a/Dockerfile +++ b/Dockerfile @@ -90,6 +90,7 @@ ENV VPNSP=pia \ FIREWALL=on \ EXTRA_SUBNETS= \ FIREWALL_VPN_INPUT_PORTS= \ + FIREWALL_INPUT_PORTS= \ FIREWALL_DEBUG=off \ # Tinyproxy TINYPROXY=off \ diff --git a/README.md b/README.md index af71a656..0f2b2774 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ That one is important if you want to connect to the container from your LAN for | `FIREWALL` | `on` | `on` or `off` | Turn on or off the container built-in firewall. You should use it for **debugging purposes** only. | | `EXTRA_SUBNETS` | | i.e. `192.168.1.0/24,192.168.10.121,10.0.0.5/28` | Comma separated subnets allowed in the container firewall | | `FIREWALL_VPN_INPUT_PORTS` | | i.e. `1000,8080` | Comma separated list of ports to allow from the VPN server side (useful for **vyprvpn** port forwarding) | +| `FIREWALL_INPUT_PORTS` | | i.e. `1000,8000` | Comma separated list of ports to allow through the default interface. This seems needed for Kubernetes sidecars. | | `FIREWALL_DEBUG` | `off` | `on` or `off` | Prints every firewall related command. You should use it for **debugging purposes** only. | ### Shadowsocks diff --git a/cmd/gluetun/main.go b/cmd/gluetun/main.go index 4348c36d..55fd2b45 100644 --- a/cmd/gluetun/main.go +++ b/cmd/gluetun/main.go @@ -186,6 +186,14 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go } } + for _, port := range allSettings.Firewall.InputPorts { + err = firewallConf.SetAllowedPort(ctx, port, defaultInterface) + if err != nil { + logger.Error(err) + return 1 + } + } + wg := &sync.WaitGroup{} go collectStreamLines(ctx, streamMerger, logger, signalTunnelReady) diff --git a/internal/params/firewall.go b/internal/params/firewall.go index 665c1124..a25a5882 100644 --- a/internal/params/firewall.go +++ b/internal/params/firewall.go @@ -60,6 +60,30 @@ func (r *reader) GetVPNInputPorts() (ports []uint16, err error) { return ports, nil } +// GetInputPorts obtains a list of input ports to allow through the +// default interface in the firewall, from the environment variable FIREWALL_INPUT_PORTS +func (r *reader) GetInputPorts() (ports []uint16, err error) { + s, err := r.envParams.GetEnv("FIREWALL_INPUT_PORTS", libparams.Default("")) + if err != nil { + return nil, err + } + if len(s) == 0 { + return nil, nil + } + portsStr := strings.Split(s, ",") + ports = make([]uint16, len(portsStr)) + for i := range portsStr { + portInt, err := strconv.Atoi(portsStr[i]) + if err != nil { + return nil, fmt.Errorf("Input port %q is not valid (%s)", portInt, err) + } else if portInt <= 0 || portInt > 65535 { + return nil, fmt.Errorf("Input port %d must be between 1 and 65535", portInt) + } + ports[i] = uint16(portInt) + } + return ports, nil +} + // GetFirewallDebug obtains if the firewall should run in debug verbose mode from the environment variable FIREWALL_DEBUG func (r *reader) GetFirewallDebug() (debug bool, err error) { return r.envParams.GetOnOff("FIREWALL_DEBUG", libparams.Default("off")) diff --git a/internal/params/params.go b/internal/params/params.go index beb13ccb..4fbccf7c 100644 --- a/internal/params/params.go +++ b/internal/params/params.go @@ -43,6 +43,7 @@ type Reader interface { GetFirewall() (enabled bool, err error) GetExtraSubnets() (extraSubnets []net.IPNet, err error) GetVPNInputPorts() (ports []uint16, err error) + GetInputPorts() (ports []uint16, err error) GetFirewallDebug() (debug bool, err error) // VPN getters diff --git a/internal/settings/firewall.go b/internal/settings/firewall.go index bd8026dd..661e0077 100644 --- a/internal/settings/firewall.go +++ b/internal/settings/firewall.go @@ -12,6 +12,7 @@ import ( type Firewall struct { AllowedSubnets []net.IPNet VPNInputPorts []uint16 + InputPorts []uint16 Enabled bool Debug bool } @@ -28,11 +29,16 @@ func (f *Firewall) String() string { for i, port := range f.VPNInputPorts { vpnInputPorts[i] = fmt.Sprintf("%d", port) } + inputPorts := make([]string, len(f.InputPorts)) + for i, port := range f.InputPorts { + inputPorts[i] = fmt.Sprintf("%d", port) + } settingsList := []string{ "Firewall settings:", "Allowed subnets: " + strings.Join(allowedSubnets, ", "), "VPN input ports: " + strings.Join(vpnInputPorts, ", "), + "Input ports: " + strings.Join(inputPorts, ", "), } if f.Debug { settingsList = append(settingsList, "Debug: on") @@ -50,6 +56,10 @@ func GetFirewallSettings(paramsReader params.Reader) (settings Firewall, err err if err != nil { return settings, err } + settings.InputPorts, err = paramsReader.GetInputPorts() + if err != nil { + return settings, err + } settings.Enabled, err = paramsReader.GetFirewall() if err != nil { return settings, err