Add FIREWALL variable, refers to #171
This commit is contained in:
@@ -74,6 +74,7 @@ ENV VPNSP=pia \
|
|||||||
UNBLOCK= \
|
UNBLOCK= \
|
||||||
DNS_UPDATE_PERIOD=24h \
|
DNS_UPDATE_PERIOD=24h \
|
||||||
# Firewall
|
# Firewall
|
||||||
|
FIREWALL=on \
|
||||||
EXTRA_SUBNETS= \
|
EXTRA_SUBNETS= \
|
||||||
# Tinyproxy
|
# Tinyproxy
|
||||||
TINYPROXY=off \
|
TINYPROXY=off \
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ That one is important if you want to connect to the container from your LAN for
|
|||||||
|
|
||||||
| Variable | Default | Choices | Description |
|
| Variable | Default | Choices | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
|
| `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 |
|
| `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 |
|
||||||
|
|
||||||
### Shadowsocks
|
### Shadowsocks
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ func _main(background context.Context, args []string) int {
|
|||||||
fatalOnError(err)
|
fatalOnError(err)
|
||||||
logger.Info(allSettings.String())
|
logger.Info(allSettings.String())
|
||||||
|
|
||||||
|
if !allSettings.Firewall.Enabled {
|
||||||
|
firewallConf.Disable()
|
||||||
|
}
|
||||||
|
|
||||||
err = alpineConf.CreateUser("nonrootuser", allSettings.System.UID)
|
err = alpineConf.CreateUser("nonrootuser", allSettings.System.UID)
|
||||||
fatalOnError(err)
|
fatalOnError(err)
|
||||||
err = fileManager.SetOwnership("/etc/unbound", allSettings.System.UID, allSettings.System.GID)
|
err = fileManager.SetOwnership("/etc/unbound", allSettings.System.UID, allSettings.System.GID)
|
||||||
|
|||||||
@@ -22,11 +22,13 @@ type Configurator interface {
|
|||||||
AllowInputTrafficOnPort(ctx context.Context, device models.VPNDevice, port uint16) error
|
AllowInputTrafficOnPort(ctx context.Context, device models.VPNDevice, port uint16) error
|
||||||
AllowAnyIncomingOnPort(ctx context.Context, port uint16) error
|
AllowAnyIncomingOnPort(ctx context.Context, port uint16) error
|
||||||
RunUserPostRules(ctx context.Context, fileManager files.FileManager, filepath string) error
|
RunUserPostRules(ctx context.Context, fileManager files.FileManager, filepath string) error
|
||||||
|
Disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
type configurator struct {
|
type configurator struct {
|
||||||
commander command.Commander
|
commander command.Commander
|
||||||
logger logging.Logger
|
logger logging.Logger
|
||||||
|
disabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigurator creates a new Configurator instance
|
// NewConfigurator creates a new Configurator instance
|
||||||
@@ -36,3 +38,7 @@ func NewConfigurator(logger logging.Logger) Configurator {
|
|||||||
logger: logger.WithPrefix("firewall configurator: "),
|
logger: logger.WithPrefix("firewall configurator: "),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *configurator) Disable() {
|
||||||
|
c.disabled = true
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ func (c *configurator) runIptablesInstruction(ctx context.Context, instruction s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) Clear(ctx context.Context) error {
|
func (c *configurator) Clear(ctx context.Context) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("clearing all rules")
|
c.logger.Info("clearing all rules")
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
"--flush",
|
"--flush",
|
||||||
@@ -51,6 +54,9 @@ func (c *configurator) Clear(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) AcceptAll(ctx context.Context) error {
|
func (c *configurator) AcceptAll(ctx context.Context) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("accepting all traffic")
|
c.logger.Info("accepting all traffic")
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
"-P INPUT ACCEPT",
|
"-P INPUT ACCEPT",
|
||||||
@@ -60,6 +66,9 @@ func (c *configurator) AcceptAll(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) BlockAll(ctx context.Context) error {
|
func (c *configurator) BlockAll(ctx context.Context) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("blocking all traffic")
|
c.logger.Info("blocking all traffic")
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
"-P INPUT DROP",
|
"-P INPUT DROP",
|
||||||
@@ -70,6 +79,9 @@ func (c *configurator) BlockAll(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) CreateGeneralRules(ctx context.Context) error {
|
func (c *configurator) CreateGeneralRules(ctx context.Context) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("creating general rules")
|
c.logger.Info("creating general rules")
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
"-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT",
|
"-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT",
|
||||||
@@ -80,6 +92,9 @@ func (c *configurator) CreateGeneralRules(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) CreateVPNRules(ctx context.Context, dev models.VPNDevice, defaultInterface string, connections []models.OpenVPNConnection) error {
|
func (c *configurator) CreateVPNRules(ctx context.Context, dev models.VPNDevice, defaultInterface string, connections []models.OpenVPNConnection) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
for _, connection := range connections {
|
for _, connection := range connections {
|
||||||
c.logger.Info("allowing output traffic to VPN server %s through %s on port %s %d",
|
c.logger.Info("allowing output traffic to VPN server %s through %s on port %s %d",
|
||||||
connection.IP, defaultInterface, connection.Protocol, connection.Port)
|
connection.IP, defaultInterface, connection.Protocol, connection.Port)
|
||||||
@@ -96,6 +111,9 @@ func (c *configurator) CreateVPNRules(ctx context.Context, dev models.VPNDevice,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) CreateLocalSubnetsRules(ctx context.Context, subnet net.IPNet, extraSubnets []net.IPNet, defaultInterface string) error {
|
func (c *configurator) CreateLocalSubnetsRules(ctx context.Context, subnet net.IPNet, extraSubnets []net.IPNet, defaultInterface string) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
subnetStr := subnet.String()
|
subnetStr := subnet.String()
|
||||||
c.logger.Info("accepting input and output traffic for %s", subnetStr)
|
c.logger.Info("accepting input and output traffic for %s", subnetStr)
|
||||||
if err := c.runIptablesInstructions(ctx, []string{
|
if err := c.runIptablesInstructions(ctx, []string{
|
||||||
@@ -123,6 +141,9 @@ func (c *configurator) CreateLocalSubnetsRules(ctx context.Context, subnet net.I
|
|||||||
|
|
||||||
// Used for port forwarding
|
// Used for port forwarding
|
||||||
func (c *configurator) AllowInputTrafficOnPort(ctx context.Context, device models.VPNDevice, port uint16) error {
|
func (c *configurator) AllowInputTrafficOnPort(ctx context.Context, device models.VPNDevice, port uint16) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("accepting input traffic through %s on port %d", device, port)
|
c.logger.Info("accepting input traffic through %s on port %d", device, port)
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
fmt.Sprintf("-A INPUT -i %s -p tcp --dport %d -j ACCEPT", device, port),
|
fmt.Sprintf("-A INPUT -i %s -p tcp --dport %d -j ACCEPT", device, port),
|
||||||
@@ -131,6 +152,9 @@ func (c *configurator) AllowInputTrafficOnPort(ctx context.Context, device model
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configurator) AllowAnyIncomingOnPort(ctx context.Context, port uint16) error {
|
func (c *configurator) AllowAnyIncomingOnPort(ctx context.Context, port uint16) error {
|
||||||
|
if c.disabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
c.logger.Info("accepting any input traffic on port %d", port)
|
c.logger.Info("accepting any input traffic on port %d", port)
|
||||||
return c.runIptablesInstructions(ctx, []string{
|
return c.runIptablesInstructions(ctx, []string{
|
||||||
fmt.Sprintf("-A INPUT -p tcp --dport %d -j ACCEPT", port),
|
fmt.Sprintf("-A INPUT -p tcp --dport %d -j ACCEPT", port),
|
||||||
|
|||||||
@@ -4,8 +4,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
libparams "github.com/qdm12/golibs/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetFirewall obtains if the firewall should be enabled from the environment variable FIREWALL
|
||||||
|
func (r *reader) GetFirewall() (enabled bool, err error) {
|
||||||
|
return r.envParams.GetOnOff("FIREWALL", libparams.Default("on"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetExtraSubnets obtains the CIDR subnets from the comma separated list of the
|
// GetExtraSubnets obtains the CIDR subnets from the comma separated list of the
|
||||||
// environment variable EXTRA_SUBNETS
|
// environment variable EXTRA_SUBNETS
|
||||||
func (r *reader) GetExtraSubnets() (extraSubnets []net.IPNet, err error) {
|
func (r *reader) GetExtraSubnets() (extraSubnets []net.IPNet, err error) {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ type Reader interface {
|
|||||||
GetIPStatusFilepath() (filepath models.Filepath, err error)
|
GetIPStatusFilepath() (filepath models.Filepath, err error)
|
||||||
|
|
||||||
// Firewall getters
|
// Firewall getters
|
||||||
|
GetFirewall() (enabled bool, err error)
|
||||||
GetExtraSubnets() (extraSubnets []net.IPNet, err error)
|
GetExtraSubnets() (extraSubnets []net.IPNet, err error)
|
||||||
|
|
||||||
// VPN getters
|
// VPN getters
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
// Firewall contains settings to customize the firewall operation
|
// Firewall contains settings to customize the firewall operation
|
||||||
type Firewall struct {
|
type Firewall struct {
|
||||||
AllowedSubnets []net.IPNet
|
AllowedSubnets []net.IPNet
|
||||||
|
Enabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Firewall) String() string {
|
func (f *Firewall) String() string {
|
||||||
@@ -17,6 +18,9 @@ func (f *Firewall) String() string {
|
|||||||
for i := range f.AllowedSubnets {
|
for i := range f.AllowedSubnets {
|
||||||
allowedSubnets[i] = f.AllowedSubnets[i].String()
|
allowedSubnets[i] = f.AllowedSubnets[i].String()
|
||||||
}
|
}
|
||||||
|
if !f.Enabled {
|
||||||
|
return "Firewall settings: disabled"
|
||||||
|
}
|
||||||
settingsList := []string{
|
settingsList := []string{
|
||||||
"Firewall settings:",
|
"Firewall settings:",
|
||||||
"Allowed subnets: " + strings.Join(allowedSubnets, ", "),
|
"Allowed subnets: " + strings.Join(allowedSubnets, ", "),
|
||||||
@@ -30,5 +34,9 @@ func GetFirewallSettings(paramsReader params.Reader) (settings Firewall, err err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
settings.Enabled, err = paramsReader.GetFirewall()
|
||||||
|
if err != nil {
|
||||||
|
return settings, err
|
||||||
|
}
|
||||||
return settings, nil
|
return settings, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user