summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/vyos-1x.postinst24
-rw-r--r--op-mode-definitions/firewall.xml.in1
-rw-r--r--python/vyos/utils/process.py2
-rwxr-xr-xsrc/op_mode/firewall.py93
4 files changed, 92 insertions, 28 deletions
diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst
index f3dc00b46..b43416152 100644
--- a/debian/vyos-1x.postinst
+++ b/debian/vyos-1x.postinst
@@ -1,4 +1,4 @@
-#!/bin/sh -e
+#!/bin/bash
# Turn off Debian default for %sudo
sed -i -e '/^%sudo/d' /etc/sudoers || true
@@ -29,6 +29,16 @@ do
sed -i "/^# Standard Un\*x authentication\./i${PAM_CONFIG}" $file
done
+# We do not make use of a TACACS UNIX group - drop it
+if grep -q '^tacacs' /etc/group; then
+ delgroup tacacs
+fi
+
+# Both RADIUS and TACACS users belong to aaa group - this must be added first
+if ! grep -q '^aaa' /etc/group; then
+ addgroup --firstgid 1000 --quiet aaa
+fi
+
# Remove TACACS user added by base package - we use our own UID range and group
# assignments - see below
if grep -q '^tacacs' /etc/passwd; then
@@ -37,6 +47,7 @@ if grep -q '^tacacs' /etc/passwd; then
vyos_group=vyattaop
while [ $level -lt 16 ]; do
userdel tacacs${level} || true
+ rm -rf /home/tacacs${level} || true
level=$(( level+1 ))
done 2>&1
fi
@@ -53,7 +64,7 @@ if ! grep -q '^tacacs' /etc/passwd; then
level=0
vyos_group=vyattaop
while [ $level -lt 16 ]; do
- adduser --quiet --system --firstuid 900 --disabled-login --ingroup ${vyos_group} \
+ adduser --quiet --system --firstuid 900 --disabled-login --ingroup users \
--no-create-home --gecos "TACACS+ mapped user at privilege level ${level}" \
--shell /bin/vbash tacacs${level}
adduser --quiet tacacs${level} frrvty
@@ -74,14 +85,9 @@ if ! grep -q '^tacacs' /etc/passwd; then
done 2>&1 | grep -v 'User tacacs${level} already exists'
fi
-
-if ! grep -q '^aaa' /etc/group; then
- addgroup --firstgid 1000 --quiet aaa
-fi
-
# Add RADIUS operator user for RADIUS authenticated users to map to
if ! grep -q '^radius_user' /etc/passwd; then
- adduser --quiet --firstuid 1000 --disabled-login --ingroup vyattaop \
+ adduser --quiet --firstuid 1000 --disabled-login --ingroup users \
--no-create-home --gecos "RADIUS mapped user at privilege level operator" \
--shell /sbin/radius_shell radius_user
adduser --quiet radius_user frrvty
@@ -95,7 +101,7 @@ fi
# Add RADIUS admin user for RADIUS authenticated users to map to
if ! grep -q '^radius_priv_user' /etc/passwd; then
- adduser --quiet --firstuid 1000 --disabled-login --ingroup vyattacfg \
+ adduser --quiet --firstuid 1000 --disabled-login --ingroup users \
--no-create-home --gecos "RADIUS mapped user at privilege level admin" \
--shell /sbin/radius_shell radius_priv_user
adduser --quiet radius_priv_user frrvty
diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in
index 164ce6b60..0f296c272 100644
--- a/op-mode-definitions/firewall.xml.in
+++ b/op-mode-definitions/firewall.xml.in
@@ -119,6 +119,7 @@
<path>firewall group address-group</path>
<path>firewall group network-group</path>
<path>firewall group port-group</path>
+ <path>firewall group interface-group</path>
<path>firewall group ipv6-address-group</path>
<path>firewall group ipv6-network-group</path>
</completionHelp>
diff --git a/python/vyos/utils/process.py b/python/vyos/utils/process.py
index 911547995..e09c7d86d 100644
--- a/python/vyos/utils/process.py
+++ b/python/vyos/utils/process.py
@@ -179,7 +179,7 @@ def rc_cmd(command, flag='', shell=None, input=None, timeout=None, env=None,
return code, out
def call(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=PIPE, stderr=PIPE, decode='utf-8'):
+ stdout=None, stderr=None, decode='utf-8'):
"""
A wrapper around popen, which print the stdout and
will return the error code of a command
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 852a7248a..581710b31 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -24,7 +24,7 @@ from vyos.config import Config
from vyos.utils.process import cmd
from vyos.utils.dict import dict_search_args
-def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=True):
+def get_config_firewall(conf, hook=None, priority=None, ipv6=False):
config_path = ['firewall']
if hook:
config_path += ['ipv6' if ipv6 else 'ipv4', hook]
@@ -38,12 +38,13 @@ def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=T
def get_nftables_details(hook, priority, ipv6=False):
suffix = '6' if ipv6 else ''
+ aux = 'IPV6_' if ipv6 else ''
name_prefix = 'NAME6_' if ipv6 else 'NAME_'
if hook == 'name' or hook == 'ipv6-name':
command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{priority}'
else:
up_hook = hook.upper()
- command = f'sudo nft list chain ip{suffix} vyos_filter VYOS_{up_hook}_{priority}'
+ command = f'sudo nft list chain ip{suffix} vyos_filter VYOS_{aux}{up_hook}_{priority}'
try:
results = cmd(command)
@@ -106,7 +107,7 @@ def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_
ip_str = 'IPv6' if ipv6 else 'IPv4'
print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {prior}"\n')
- details = get_nftables_details(prior, ipv6)
+ details = get_nftables_details(hook, prior, ipv6)
rows = []
if 'rule' in prior_conf:
@@ -117,8 +118,41 @@ def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_
if 'disable' in rule_conf:
continue
- source_addr = dict_search_args(rule_conf, 'source', 'address') or '0.0.0.0/0'
- dest_addr = dict_search_args(rule_conf, 'destination', 'address') or '0.0.0.0/0'
+ # Get source
+ source_addr = dict_search_args(rule_conf, 'source', 'address')
+ if not source_addr:
+ source_addr = dict_search_args(rule_conf, 'source', 'group', 'address_group')
+ if not source_addr:
+ source_addr = dict_search_args(rule_conf, 'source', 'group', 'network_group')
+ if not source_addr:
+ source_addr = dict_search_args(rule_conf, 'source', 'group', 'domain_group')
+ if not source_addr:
+ source_addr = '::/0' if ipv6 else '0.0.0.0/0'
+
+ # Get destination
+ dest_addr = dict_search_args(rule_conf, 'destination', 'address')
+ if not dest_addr:
+ dest_addr = dict_search_args(rule_conf, 'destination', 'group', 'address_group')
+ if not dest_addr:
+ dest_addr = dict_search_args(rule_conf, 'destination', 'group', 'network_group')
+ if not dest_addr:
+ dest_addr = dict_search_args(rule_conf, 'destination', 'group', 'domain_group')
+ if not dest_addr:
+ dest_addr = '::/0' if ipv6 else '0.0.0.0/0'
+
+ # Get inbound interface
+ iiface = dict_search_args(rule_conf, 'inbound_interface', 'interface_name')
+ if not iiface:
+ iiface = dict_search_args(rule_conf, 'inbound_interface', 'interface_group')
+ if not iiface:
+ iiface = 'any'
+
+ # Get outbound interface
+ oiface = dict_search_args(rule_conf, 'outbound_interface', 'interface_name')
+ if not oiface:
+ oiface = dict_search_args(rule_conf, 'outbound_interface', 'interface_group')
+ if not oiface:
+ oiface = 'any'
row = [rule_id]
if rule_id in details:
@@ -131,6 +165,8 @@ def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_
row.append(rule_conf['action'])
row.append(source_addr)
row.append(dest_addr)
+ row.append(iiface)
+ row.append(oiface)
rows.append(row)
if 'default_action' in prior_conf and not single_rule_id:
@@ -148,7 +184,7 @@ def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_
rows.append(row)
if rows:
- header = ['Rule', 'Packets', 'Bytes', 'Action', 'Source', 'Destination']
+ header = ['Rule', 'Packets', 'Bytes', 'Action', 'Source', 'Destination', 'Inbound-Interface', 'Outbound-interface']
print(tabulate.tabulate(rows, header) + '\n')
def show_firewall():
@@ -204,7 +240,7 @@ def show_firewall_rule(hook, priority, rule_id, ipv6=False):
def show_firewall_group(name=None):
conf = Config()
- firewall = get_config_firewall(conf, interfaces=False)
+ firewall = get_config_firewall(conf)
if 'group' not in firewall:
return
@@ -225,18 +261,37 @@ def show_firewall_group(name=None):
for item in family:
for name_type in ['name', 'ipv6_name', 'forward', 'input', 'output']:
- if name_type not in firewall[item]:
- continue
- for name, name_conf in firewall[item][name_type].items():
- if 'rule' not in name_conf:
+ if item in firewall:
+ if name_type not in firewall[item]:
continue
- for rule_id, rule_conf in name_conf['rule'].items():
- source_group = dict_search_args(rule_conf, 'source', 'group', group_type)
- dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
- if source_group and group_name == source_group:
- out.append(f'{name}-{rule_id}')
- elif dest_group and group_name == dest_group:
- out.append(f'{name}-{rule_id}')
+ for priority, priority_conf in firewall[item][name_type].items():
+ if priority not in firewall[item][name_type]:
+ continue
+ for rule_id, rule_conf in priority_conf['rule'].items():
+ source_group = dict_search_args(rule_conf, 'source', 'group', group_type)
+ dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
+ in_interface = dict_search_args(rule_conf, 'inbound_interface', 'interface_group')
+ out_interface = dict_search_args(rule_conf, 'outbound_interface', 'interface_group')
+ if source_group:
+ if source_group[0] == "!":
+ source_group = source_group[1:]
+ if group_name == source_group:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+ if dest_group:
+ if dest_group[0] == "!":
+ dest_group = dest_group[1:]
+ if group_name == dest_group:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+ if in_interface:
+ if in_interface[0] == "!":
+ in_interface = in_interface[1:]
+ if group_name == in_interface:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+ if out_interface:
+ if out_interface[0] == "!":
+ out_interface = out_interface[1:]
+ if group_name == out_interface:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
return out
header = ['Name', 'Type', 'References', 'Members']
@@ -257,6 +312,8 @@ def show_firewall_group(name=None):
row.append("\n".join(sorted(group_conf['mac_address'])))
elif 'port' in group_conf:
row.append("\n".join(sorted(group_conf['port'])))
+ elif 'interface' in group_conf:
+ row.append("\n".join(sorted(group_conf['interface'])))
else:
row.append('N/A')
rows.append(row)