diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/container.py | 11 | ||||
| -rwxr-xr-x | src/conf_mode/high-availability.py | 16 | ||||
| -rwxr-xr-x | src/conf_mode/interfaces-ethernet.py | 13 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_igmp.py | 2 | ||||
| -rwxr-xr-x | src/op_mode/dhcp.py | 4 | ||||
| -rwxr-xr-x | src/op_mode/firewall.py | 136 | ||||
| -rwxr-xr-x | src/op_mode/vyos-op-cmd-wrapper.sh | 6 | 
7 files changed, 157 insertions, 31 deletions
| diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 79b605ffb..46eb10714 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -178,6 +178,11 @@ def verify(container):                      if 'value' not in cfg:                          raise ConfigError(f'Environment variable {var} has no value assigned!') +            if 'label' in container_config: +                for var, cfg in container_config['label'].items(): +                    if 'value' not in cfg: +                        raise ConfigError(f'Label variable {var} has no value assigned!') +              if 'volume' in container_config:                  for volume, volume_config in container_config['volume'].items():                      if 'source' not in volume_config: @@ -268,6 +273,12 @@ def generate_run_arguments(name, container_config):          for k, v in container_config['environment'].items():              env_opt += f" --env \"{k}={v['value']}\"" +    # Check/set label options "--label foo=bar" +    env_opt = '' +    if 'label' in container_config: +        for k, v in container_config['label'].items(): +            env_opt += f" --label \"{k}={v['value']}\"" +      hostname = ''      if 'host_name' in container_config:          hostname = container_config['host_name'] diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py index 626a3757e..0121df11c 100755 --- a/src/conf_mode/high-availability.py +++ b/src/conf_mode/high-availability.py @@ -15,6 +15,8 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>. +import time +  from sys import exit  from ipaddress import ip_interface  from ipaddress import IPv4Interface @@ -26,11 +28,13 @@ from vyos.ifconfig.vrrp import VRRP  from vyos.template import render  from vyos.template import is_ipv4  from vyos.template import is_ipv6 +from vyos.utils.network import is_ipv6_tentative  from vyos.utils.process import call  from vyos import ConfigError  from vyos import airbag  airbag.enable() +  def get_config(config=None):      if config:          conf = config @@ -171,6 +175,18 @@ def apply(ha):          call(f'systemctl stop {service_name}')          return None +    # Check if IPv6 address is tentative T5533 +    for group, group_config in ha['vrrp']['group'].items(): +        if 'hello_source_address' in group_config: +            if is_ipv6(group_config['hello_source_address']): +                ipv6_address = group_config['hello_source_address'] +                interface = group_config['interface'] +                checks = 20 +                interval = 0.1 +                for _ in range(checks): +                    if is_ipv6_tentative(interface, ipv6_address): +                        time.sleep(interval) +      call(f'systemctl reload-or-restart {service_name}')      return None diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index b015bba88..f3e65ad5e 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -186,14 +186,15 @@ def generate(ethernet):          if 'ca_certificate' in ethernet['eapol']:              ca_cert_file_path = os.path.join(cfg_dir, f'{ifname}_ca.pem') -            ca_cert_name = ethernet['eapol']['ca_certificate'] -            pki_ca_cert = ethernet['pki']['ca'][ca_cert_name] +            ca_chains = [] -            loaded_ca_cert = load_certificate(pki_ca_cert['certificate']) -            ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) +            for ca_cert_name in ethernet['eapol']['ca_certificate']: +                pki_ca_cert = ethernet['pki']['ca'][ca_cert_name] +                loaded_ca_cert = load_certificate(pki_ca_cert['certificate']) +                ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) +                ca_chains.append('\n'.join(encode_certificate(c) for c in ca_full_chain)) -            write_file(ca_cert_file_path, -                       '\n'.join(encode_certificate(c) for c in ca_full_chain)) +            write_file(ca_cert_file_path, '\n'.join(ca_chains))      return None diff --git a/src/conf_mode/protocols_igmp.py b/src/conf_mode/protocols_igmp.py index f6097e282..435189025 100755 --- a/src/conf_mode/protocols_igmp.py +++ b/src/conf_mode/protocols_igmp.py @@ -102,7 +102,7 @@ def verify(igmp):          # Check, is this multicast group          for intfc in igmp['ifaces']:              for gr_addr in igmp['ifaces'][intfc]['gr_join']: -                if IPv4Address(gr_addr) < IPv4Address('224.0.0.0'): +                if not IPv4Address(gr_addr).is_multicast:                      raise ConfigError(gr_addr + " not a multicast group")  def generate(igmp): diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index f558c18b7..77f38992b 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -338,10 +338,12 @@ def _get_formatted_client_leases(lease_data, family):      from time import localtime      from time import strftime -    from vyos.validate import is_intf_addr_assigned +    from vyos.utils.network import is_intf_addr_assigned      data_entries = []      for lease in lease_data: +        if not lease.get('new_ip_address'): +            continue          data_entries.append(["Interface", lease['interface']])          if 'new_ip_address' in lease:              tmp = '[Active]' if is_intf_addr_assigned(lease['interface'], lease['new_ip_address']) else '[Inactive]' diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py index 852a7248a..23b4b8459 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,57 @@ 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 = dict_search_args(rule_conf, 'source', 'fqdn') +                            if not source_addr: +                                source_addr = dict_search_args(rule_conf, 'source', 'geoip', 'country_code') +                                if source_addr: +                                    source_addr = str(source_addr)[1:-1].replace('\'','') +                                    if 'inverse_match' in dict_search_args(rule_conf, 'source', 'geoip'): +                                        source_addr = 'NOT ' + str(source_addr) +                                if not source_addr: +                                    source_addr = 'any' + +            # 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 = dict_search_args(rule_conf, 'destination', 'fqdn') +                            if not dest_addr: +                                dest_addr = dict_search_args(rule_conf, 'destination', 'geoip', 'country_code') +                                if dest_addr: +                                    dest_addr = str(dest_addr)[1:-1].replace('\'','') +                                    if 'inverse_match' in dict_search_args(rule_conf, 'destination', 'geoip'): +                                        dest_addr = 'NOT ' + str(dest_addr) +                                if not dest_addr: +                                    dest_addr = 'any' + +            # 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,9 +181,26 @@ 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: + +    if hook in ['input', 'forward', 'output']: +        row = ['default'] +        row.append('N/A') +        row.append('N/A') +        if 'default_action' in prior_conf: +            row.append(prior_conf['default_action']) +        else: +            row.append('accept') +        row.append('any') +        row.append('any') +        row.append('any') +        row.append('any') +        rows.append(row) + +    elif 'default_action' in prior_conf and not single_rule_id:          row = ['default']          if 'default-action' in details:              rule_details = details['default-action'] @@ -143,12 +210,14 @@ def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_              row.append('0')              row.append('0')          row.append(prior_conf['default_action']) -        row.append('0.0.0.0/0') # Source -        row.append('0.0.0.0/0') # Dest +        row.append('any') # Source +        row.append('any') # Dest +        row.append('any')   # inbound-interface +        row.append('any')   # outbound-interface          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 +273,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 +294,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'] @@ -248,7 +336,7 @@ def show_firewall_group(name=None):                  continue              references = find_references(group_type, group_name) -            row = [group_name, group_type, '\n'.join(references) or 'N/A'] +            row = [group_name, group_type, '\n'.join(references) or 'N/D']              if 'address' in group_conf:                  row.append("\n".join(sorted(group_conf['address'])))              elif 'network' in group_conf: @@ -257,8 +345,10 @@ 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') +                row.append('N/D')              rows.append(row)      if rows: diff --git a/src/op_mode/vyos-op-cmd-wrapper.sh b/src/op_mode/vyos-op-cmd-wrapper.sh new file mode 100755 index 000000000..a89211b2b --- /dev/null +++ b/src/op_mode/vyos-op-cmd-wrapper.sh @@ -0,0 +1,6 @@ +#!/bin/vbash +shopt -s expand_aliases +source /etc/default/vyatta +source /etc/bash_completion.d/vyatta-op +_vyatta_op_init +_vyatta_op_run "$@" | 
