@@ -91,6 +91,7 @@ ENV VPNSP=pia \
|
||||
FIREWALL=on \
|
||||
FIREWALL_VPN_INPUT_PORTS= \
|
||||
FIREWALL_INPUT_PORTS= \
|
||||
FIREWALL_OUTBOUND_SUBNETS= \
|
||||
FIREWALL_DEBUG=off \
|
||||
# Tinyproxy
|
||||
TINYPROXY=off \
|
||||
|
||||
@@ -223,9 +223,7 @@ None of the following values are required.
|
||||
| `DNS_PLAINTEXT_ADDRESS` | `1.1.1.1` | Any IP address | IP address to use as DNS resolver if `DOT` is `off` |
|
||||
| `DNS_KEEP_NAMESERVER` | `off` | `on` or `off` | Keep the nameservers in /etc/resolv.conf untouched, but disabled DNS blocking features |
|
||||
|
||||
### Firewall
|
||||
|
||||
That one is important if you want to connect to the container from your LAN for example, using Shadowsocks or Tinyproxy.
|
||||
### Firewall and routing
|
||||
|
||||
| Variable | Default | Choices | Description |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -233,6 +231,7 @@ That one is important if you want to connect to the container from your LAN for
|
||||
| `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. |
|
||||
| `FIREWALL_OUTBOUND_SUBNETS` | | i.e. `192.168.1.0/24,192.168.10.121,10.0.0.5/28` | Comma separated subnets that Gluetun and the containers sharing its network stack are allowed to access. This involves firewall and routing modifications. |
|
||||
|
||||
### Shadowsocks
|
||||
|
||||
|
||||
@@ -148,7 +148,13 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
|
||||
return 1
|
||||
}
|
||||
|
||||
firewallConf.SetNetworkInformation(defaultInterface, defaultGateway, localSubnet)
|
||||
defaultIP, err := routingConf.DefaultIP()
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
firewallConf.SetNetworkInformation(defaultInterface, defaultGateway, localSubnet, defaultIP)
|
||||
|
||||
if err := routingConf.Setup(); err != nil {
|
||||
logger.Error(err)
|
||||
@@ -160,6 +166,15 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
|
||||
}
|
||||
}()
|
||||
|
||||
if err := firewallConf.SetOutboundSubnets(ctx, allSettings.Firewall.OutboundSubnets); err != nil {
|
||||
logger.Error(err)
|
||||
return 1
|
||||
}
|
||||
if err := routingConf.SetOutboundRoutes(allSettings.Firewall.OutboundSubnets); err != nil {
|
||||
logger.Error(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if err := ovpnConf.CheckTUN(); err != nil {
|
||||
logger.Warn(err)
|
||||
err = ovpnConf.CreateTUN()
|
||||
|
||||
@@ -94,6 +94,12 @@ func (c *configurator) enable(ctx context.Context) (err error) {
|
||||
return fmt.Errorf("cannot enable firewall: %w", err)
|
||||
}
|
||||
|
||||
for _, subnet := range c.outboundSubnets {
|
||||
if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subnet, remove); err != nil {
|
||||
return fmt.Errorf("cannot enable firewall: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Allows packets from any IP address to go through eth0 / local network
|
||||
// to reach Gluetun.
|
||||
if err := c.acceptInputToSubnet(ctx, c.defaultInterface, c.localSubnet, remove); err != nil {
|
||||
|
||||
@@ -18,10 +18,11 @@ type Configurator interface {
|
||||
SetEnabled(ctx context.Context, enabled bool) (err error)
|
||||
SetVPNConnection(ctx context.Context, connection models.OpenVPNConnection) (err error)
|
||||
SetAllowedPort(ctx context.Context, port uint16, intf string) (err error)
|
||||
SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error)
|
||||
RemoveAllowedPort(ctx context.Context, port uint16) (err error)
|
||||
SetDebug()
|
||||
// SetNetworkInformation is meant to be called only once
|
||||
SetNetworkInformation(defaultInterface string, defaultGateway net.IP, localSubnet net.IPNet)
|
||||
SetNetworkInformation(defaultInterface string, defaultGateway net.IP, localSubnet net.IPNet, localIP net.IP)
|
||||
}
|
||||
|
||||
type configurator struct { //nolint:maligned
|
||||
@@ -34,11 +35,13 @@ type configurator struct { //nolint:maligned
|
||||
defaultInterface string
|
||||
defaultGateway net.IP
|
||||
localSubnet net.IPNet
|
||||
localIP net.IP
|
||||
networkInfoMutex sync.Mutex
|
||||
|
||||
// State
|
||||
enabled bool
|
||||
vpnConnection models.OpenVPNConnection
|
||||
outboundSubnets []net.IPNet
|
||||
allowedInputPorts map[uint16]string // port to interface mapping
|
||||
stateMutex sync.Mutex
|
||||
}
|
||||
@@ -58,10 +61,12 @@ func (c *configurator) SetDebug() {
|
||||
c.debug = true
|
||||
}
|
||||
|
||||
func (c *configurator) SetNetworkInformation(defaultInterface string, defaultGateway net.IP, localSubnet net.IPNet) {
|
||||
func (c *configurator) SetNetworkInformation(
|
||||
defaultInterface string, defaultGateway net.IP, localSubnet net.IPNet, localIP net.IP) {
|
||||
c.networkInfoMutex.Lock()
|
||||
defer c.networkInfoMutex.Unlock()
|
||||
c.defaultInterface = defaultInterface
|
||||
c.defaultGateway = defaultGateway
|
||||
c.localSubnet = localSubnet
|
||||
c.localIP = localIP
|
||||
}
|
||||
|
||||
@@ -124,6 +124,19 @@ func (c *configurator) acceptOutputTrafficToVPN(ctx context.Context,
|
||||
appendOrDelete(remove), connection.IP, defaultInterface, connection.Protocol, connection.Protocol, connection.Port))
|
||||
}
|
||||
|
||||
// Thanks to @npawelek.
|
||||
func (c *configurator) acceptOutputFromIPToSubnet(ctx context.Context,
|
||||
intf string, sourceIP net.IP, destinationSubnet net.IPNet, remove bool) error {
|
||||
interfaceFlag := "-o " + intf
|
||||
if intf == "*" { // all interfaces
|
||||
interfaceFlag = ""
|
||||
}
|
||||
return c.runIptablesInstruction(ctx, fmt.Sprintf(
|
||||
"%s OUTPUT %s -s %s -d %s -j ACCEPT",
|
||||
appendOrDelete(remove), interfaceFlag, sourceIP.String(), destinationSubnet.String(),
|
||||
))
|
||||
}
|
||||
|
||||
// Used for port forwarding, with intf set to tun.
|
||||
func (c *configurator) acceptInputToPort(ctx context.Context, intf string, port uint16, remove bool) error {
|
||||
interfaceFlag := "-i " + intf
|
||||
|
||||
56
internal/firewall/outboundsubnets.go
Normal file
56
internal/firewall/outboundsubnets.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func (c *configurator) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error) {
|
||||
c.stateMutex.Lock()
|
||||
defer c.stateMutex.Unlock()
|
||||
|
||||
if !c.enabled {
|
||||
c.logger.Info("firewall disabled, only updating allowed subnets internal list")
|
||||
c.outboundSubnets = make([]net.IPNet, len(subnets))
|
||||
copy(c.outboundSubnets, subnets)
|
||||
return nil
|
||||
}
|
||||
|
||||
c.logger.Info("setting allowed subnets through firewall...")
|
||||
|
||||
subnetsToAdd := findSubnetsToAdd(c.outboundSubnets, subnets)
|
||||
subnetsToRemove := findSubnetsToRemove(c.outboundSubnets, subnets)
|
||||
if len(subnetsToAdd) == 0 && len(subnetsToRemove) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.removeOutboundSubnets(ctx, subnetsToRemove)
|
||||
if err := c.addOutboundSubnets(ctx, subnetsToAdd); err != nil {
|
||||
return fmt.Errorf("cannot set allowed subnets through firewall: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configurator) removeOutboundSubnets(ctx context.Context, subnets []net.IPNet) {
|
||||
const remove = true
|
||||
for _, subnet := range subnets {
|
||||
if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subnet, remove); err != nil {
|
||||
c.logger.Error("cannot remove outdated outbound subnet through firewall: %s", err)
|
||||
continue
|
||||
}
|
||||
c.outboundSubnets = removeSubnetFromSubnets(c.outboundSubnets, subnet)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configurator) addOutboundSubnets(ctx context.Context, subnets []net.IPNet) error {
|
||||
const remove = false
|
||||
for _, subnet := range subnets {
|
||||
if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subnet, remove); err != nil {
|
||||
return fmt.Errorf("cannot add allowed subnet through firewall: %w", err)
|
||||
}
|
||||
c.outboundSubnets = append(c.outboundSubnets, subnet)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
53
internal/firewall/subnets.go
Normal file
53
internal/firewall/subnets.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
func findSubnetsToAdd(oldSubnets, newSubnets []net.IPNet) (subnetsToAdd []net.IPNet) {
|
||||
for _, newSubnet := range newSubnets {
|
||||
found := false
|
||||
for _, oldSubnet := range oldSubnets {
|
||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
subnetsToAdd = append(subnetsToAdd, newSubnet)
|
||||
}
|
||||
}
|
||||
return subnetsToAdd
|
||||
}
|
||||
|
||||
func findSubnetsToRemove(oldSubnets, newSubnets []net.IPNet) (subnetsToRemove []net.IPNet) {
|
||||
for _, oldSubnet := range oldSubnets {
|
||||
found := false
|
||||
for _, newSubnet := range newSubnets {
|
||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
subnetsToRemove = append(subnetsToRemove, oldSubnet)
|
||||
}
|
||||
}
|
||||
return subnetsToRemove
|
||||
}
|
||||
|
||||
func subnetsAreEqual(a, b net.IPNet) bool {
|
||||
return a.IP.Equal(b.IP) && a.Mask.String() == b.Mask.String()
|
||||
}
|
||||
|
||||
func removeSubnetFromSubnets(subnets []net.IPNet, subnet net.IPNet) []net.IPNet {
|
||||
L := len(subnets)
|
||||
for i := range subnets {
|
||||
if subnetsAreEqual(subnet, subnets[i]) {
|
||||
subnets[i] = subnets[L-1]
|
||||
subnets = subnets[:L-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
return subnets
|
||||
}
|
||||
@@ -43,6 +43,7 @@ type Reader interface {
|
||||
GetFirewall() (enabled bool, err error)
|
||||
GetVPNInputPorts() (ports []uint16, err error)
|
||||
GetInputPorts() (ports []uint16, err error)
|
||||
GetOutboundSubnets() (outboundSubnets []net.IPNet, err error)
|
||||
GetFirewallDebug() (debug bool, err error)
|
||||
|
||||
// VPN getters
|
||||
|
||||
31
internal/params/routing.go
Normal file
31
internal/params/routing.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetOutboundSubnets obtains the CIDR subnets from the comma separated list of the
|
||||
// environment variable FIREWALL_OUTBOUND_SUBNETS.
|
||||
func (r *reader) GetOutboundSubnets() (outboundSubnets []net.IPNet, err error) {
|
||||
const key = "FIREWALL_OUTBOUND_SUBNETS"
|
||||
s, err := r.envParams.GetEnv(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if s == "" {
|
||||
return nil, nil
|
||||
}
|
||||
subnets := strings.Split(s, ",")
|
||||
for _, subnet := range subnets {
|
||||
_, cidr, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse outbound subnet %q from environment variable with key %s: %w", subnet, key, err)
|
||||
} else if cidr == nil {
|
||||
return nil, fmt.Errorf("cannot parse outbound subnet %q from environment variable with key %s: subnet is nil",
|
||||
subnet, key)
|
||||
}
|
||||
outboundSubnets = append(outboundSubnets, *cidr)
|
||||
}
|
||||
return outboundSubnets, nil
|
||||
}
|
||||
@@ -16,7 +16,7 @@ const (
|
||||
)
|
||||
|
||||
func (r *routing) Setup() (err error) {
|
||||
defaultIP, err := r.defaultIP()
|
||||
defaultIP, err := r.DefaultIP()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrSetup, err)
|
||||
}
|
||||
@@ -40,11 +40,19 @@ func (r *routing) Setup() (err error) {
|
||||
if err := r.addRouteVia(defaultDestination, defaultGateway, defaultInterfaceName, table); err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrSetup, err)
|
||||
}
|
||||
|
||||
r.stateMutex.RLock()
|
||||
outboundSubnets := r.outboundSubnets
|
||||
r.stateMutex.RUnlock()
|
||||
if err := r.setOutboundRoutes(outboundSubnets, defaultInterfaceName, defaultGateway); err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrSetup, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *routing) TearDown() error {
|
||||
defaultIP, err := r.defaultIP()
|
||||
defaultIP, err := r.DefaultIP()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrTeardown, err)
|
||||
}
|
||||
@@ -60,5 +68,10 @@ func (r *routing) TearDown() error {
|
||||
if err := r.deleteIPRule(defaultIP, table, priority); err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrTeardown, err)
|
||||
}
|
||||
|
||||
if err := r.setOutboundRoutes(nil, defaultInterfaceName, defaultGateway); err != nil {
|
||||
return fmt.Errorf("%s: %w", ErrSetup, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
58
internal/routing/outboundsubnets.go
Normal file
58
internal/routing/outboundsubnets.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func (r *routing) SetOutboundRoutes(outboundSubnets []net.IPNet) error {
|
||||
defaultInterface, defaultGateway, err := r.DefaultRoute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot set oubtound subnets in routing: %w", err)
|
||||
}
|
||||
return r.setOutboundRoutes(outboundSubnets, defaultInterface, defaultGateway)
|
||||
}
|
||||
|
||||
func (r *routing) setOutboundRoutes(outboundSubnets []net.IPNet,
|
||||
defaultInterfaceName string, defaultGateway net.IP) error {
|
||||
r.stateMutex.Lock()
|
||||
defer r.stateMutex.Unlock()
|
||||
|
||||
subnetsToRemove := findSubnetsToRemove(r.outboundSubnets, outboundSubnets)
|
||||
subnetsToAdd := findSubnetsToAdd(r.outboundSubnets, outboundSubnets)
|
||||
|
||||
if len(subnetsToAdd) == 0 && len(subnetsToRemove) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
r.removeOutboundSubnets(subnetsToRemove, defaultInterfaceName, defaultGateway)
|
||||
if err := r.addOutboundSubnets(subnetsToAdd, defaultInterfaceName, defaultGateway); err != nil {
|
||||
return fmt.Errorf("cannot set outbound subnets in routing: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *routing) removeOutboundSubnets(subnets []net.IPNet,
|
||||
defaultInterfaceName string, defaultGateway net.IP) {
|
||||
for _, subnet := range subnets {
|
||||
const table = 0
|
||||
if err := r.deleteRouteVia(subnet, defaultGateway, defaultInterfaceName, table); err != nil {
|
||||
r.logger.Error("cannot remove outdated outbound subnet from routing: %s", err)
|
||||
continue
|
||||
}
|
||||
r.outboundSubnets = removeSubnetFromSubnets(r.outboundSubnets, subnet)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *routing) addOutboundSubnets(subnets []net.IPNet,
|
||||
defaultInterfaceName string, defaultGateway net.IP) error {
|
||||
for _, subnet := range subnets {
|
||||
const table = 0
|
||||
if err := r.addRouteVia(subnet, defaultGateway, defaultInterfaceName, table); err != nil {
|
||||
return fmt.Errorf("cannot add outbound subnet %s to routing: %w", subnet, err)
|
||||
}
|
||||
r.outboundSubnets = append(r.outboundSubnets, subnet)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func (r *routing) DefaultRoute() (defaultInterface string, defaultGateway net.IP
|
||||
return "", nil, fmt.Errorf("cannot find default route in %d routes", len(routes))
|
||||
}
|
||||
|
||||
func (r *routing) defaultIP() (ip net.IP, err error) {
|
||||
func (r *routing) DefaultIP() (ip net.IP, err error) {
|
||||
routes, err := netlink.RouteList(nil, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get default IP address: %w", err)
|
||||
|
||||
@@ -2,17 +2,25 @@ package routing
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
type Routing interface {
|
||||
// Mutations
|
||||
Setup() (err error)
|
||||
TearDown() error
|
||||
SetOutboundRoutes(outboundSubnets []net.IPNet) error
|
||||
|
||||
// Read only
|
||||
DefaultRoute() (defaultInterface string, defaultGateway net.IP, err error)
|
||||
LocalSubnet() (defaultSubnet net.IPNet, err error)
|
||||
DefaultIP() (defaultIP net.IP, err error)
|
||||
VPNDestinationIP() (ip net.IP, err error)
|
||||
VPNLocalGatewayIP() (ip net.IP, err error)
|
||||
|
||||
// Internal state
|
||||
SetVerbose(verbose bool)
|
||||
SetDebug()
|
||||
}
|
||||
@@ -21,6 +29,8 @@ type routing struct {
|
||||
logger logging.Logger
|
||||
verbose bool
|
||||
debug bool
|
||||
outboundSubnets []net.IPNet
|
||||
stateMutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewConfigurator creates a new Configurator instance.
|
||||
|
||||
53
internal/routing/subnets.go
Normal file
53
internal/routing/subnets.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
func findSubnetsToAdd(oldSubnets, newSubnets []net.IPNet) (subnetsToAdd []net.IPNet) {
|
||||
for _, newSubnet := range newSubnets {
|
||||
found := false
|
||||
for _, oldSubnet := range oldSubnets {
|
||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
subnetsToAdd = append(subnetsToAdd, newSubnet)
|
||||
}
|
||||
}
|
||||
return subnetsToAdd
|
||||
}
|
||||
|
||||
func findSubnetsToRemove(oldSubnets, newSubnets []net.IPNet) (subnetsToRemove []net.IPNet) {
|
||||
for _, oldSubnet := range oldSubnets {
|
||||
found := false
|
||||
for _, newSubnet := range newSubnets {
|
||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
subnetsToRemove = append(subnetsToRemove, oldSubnet)
|
||||
}
|
||||
}
|
||||
return subnetsToRemove
|
||||
}
|
||||
|
||||
func subnetsAreEqual(a, b net.IPNet) bool {
|
||||
return a.IP.Equal(b.IP) && a.Mask.String() == b.Mask.String()
|
||||
}
|
||||
|
||||
func removeSubnetFromSubnets(subnets []net.IPNet, subnet net.IPNet) []net.IPNet {
|
||||
L := len(subnets)
|
||||
for i := range subnets {
|
||||
if subnetsAreEqual(subnet, subnets[i]) {
|
||||
subnets[i] = subnets[L-1]
|
||||
subnets = subnets[:L-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
return subnets
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/params"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
type Firewall struct {
|
||||
VPNInputPorts []uint16
|
||||
InputPorts []uint16
|
||||
OutboundSubnets []net.IPNet
|
||||
Enabled bool
|
||||
Debug bool
|
||||
}
|
||||
@@ -27,11 +29,16 @@ func (f *Firewall) String() string {
|
||||
for i, port := range f.InputPorts {
|
||||
inputPorts[i] = fmt.Sprintf("%d", port)
|
||||
}
|
||||
outboundSubnets := make([]string, len(f.OutboundSubnets))
|
||||
for i := range f.OutboundSubnets {
|
||||
outboundSubnets[i] = f.OutboundSubnets[i].String()
|
||||
}
|
||||
|
||||
settingsList := []string{
|
||||
"Firewall settings:",
|
||||
"VPN input ports: " + strings.Join(vpnInputPorts, ", "),
|
||||
"Input ports: " + strings.Join(inputPorts, ", "),
|
||||
"Outbound subnets: " + strings.Join(outboundSubnets, ", "),
|
||||
}
|
||||
if f.Debug {
|
||||
settingsList = append(settingsList, "Debug: on")
|
||||
@@ -49,6 +56,10 @@ func GetFirewallSettings(paramsReader params.Reader) (settings Firewall, err err
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.OutboundSubnets, err = paramsReader.GetOutboundSubnets()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.Enabled, err = paramsReader.GetFirewall()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
|
||||
Reference in New Issue
Block a user