From d7cad8ea121162dd54722f2c4db72c458dfcf02d Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Tue, 7 Jan 2025 23:30:14 +0000 Subject: Add XML CLI for conf and op-mode --- interface-definitions/include/version/vpp-version.xml.i | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 interface-definitions/include/version/vpp-version.xml.i (limited to 'interface-definitions/include/version') diff --git a/interface-definitions/include/version/vpp-version.xml.i b/interface-definitions/include/version/vpp-version.xml.i new file mode 100644 index 000000000..96a69c92f --- /dev/null +++ b/interface-definitions/include/version/vpp-version.xml.i @@ -0,0 +1,3 @@ + + + \ No newline at end of file -- cgit v1.2.3 From cedfce8899cb3dc406922c68afc7e31b8edc01ae Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Wed, 8 Jan 2025 15:56:07 +0000 Subject: Move component version to conflict-components or dynamic --- conflict-components/version/vpp-version.xml.i | 3 +++ conflict-components/xml-component-version.xml.in | 4 ++++ interface-definitions/include/version/vpp-version.xml.i | 3 --- interface-definitions/xml-component-version.xml.in | 4 ---- 4 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 conflict-components/version/vpp-version.xml.i create mode 100644 conflict-components/xml-component-version.xml.in delete mode 100644 interface-definitions/include/version/vpp-version.xml.i delete mode 100644 interface-definitions/xml-component-version.xml.in (limited to 'interface-definitions/include/version') diff --git a/conflict-components/version/vpp-version.xml.i b/conflict-components/version/vpp-version.xml.i new file mode 100644 index 000000000..96a69c92f --- /dev/null +++ b/conflict-components/version/vpp-version.xml.i @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/conflict-components/xml-component-version.xml.in b/conflict-components/xml-component-version.xml.in new file mode 100644 index 000000000..ae137d435 --- /dev/null +++ b/conflict-components/xml-component-version.xml.in @@ -0,0 +1,4 @@ + + + #include + diff --git a/interface-definitions/include/version/vpp-version.xml.i b/interface-definitions/include/version/vpp-version.xml.i deleted file mode 100644 index 96a69c92f..000000000 --- a/interface-definitions/include/version/vpp-version.xml.i +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/interface-definitions/xml-component-version.xml.in b/interface-definitions/xml-component-version.xml.in deleted file mode 100644 index ae137d435..000000000 --- a/interface-definitions/xml-component-version.xml.in +++ /dev/null @@ -1,4 +0,0 @@ - - - #include - -- cgit v1.2.3 From d1d170c20fbec8f10f0eec440edae7655789e923 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Thu, 9 Jan 2025 17:06:19 +0000 Subject: Remove conflict-components --- conflict-components/version/vpp-version.xml.i | 3 --- conflict-components/xml-component-version.xml.in | 4 ---- interface-definitions/include/version/vpp-version.xml.i | 3 +++ 3 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 conflict-components/version/vpp-version.xml.i delete mode 100644 conflict-components/xml-component-version.xml.in create mode 100644 interface-definitions/include/version/vpp-version.xml.i (limited to 'interface-definitions/include/version') diff --git a/conflict-components/version/vpp-version.xml.i b/conflict-components/version/vpp-version.xml.i deleted file mode 100644 index 96a69c92f..000000000 --- a/conflict-components/version/vpp-version.xml.i +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/conflict-components/xml-component-version.xml.in b/conflict-components/xml-component-version.xml.in deleted file mode 100644 index ae137d435..000000000 --- a/conflict-components/xml-component-version.xml.in +++ /dev/null @@ -1,4 +0,0 @@ - - - #include - diff --git a/interface-definitions/include/version/vpp-version.xml.i b/interface-definitions/include/version/vpp-version.xml.i new file mode 100644 index 000000000..96a69c92f --- /dev/null +++ b/interface-definitions/include/version/vpp-version.xml.i @@ -0,0 +1,3 @@ + + + \ No newline at end of file -- cgit v1.2.3 From 395e3cb72c521ea9d62c0efd1620e679fc709cda Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 8 Jan 2025 20:41:03 +0100 Subject: syslog: T6989: remove "file" logging destination --- data/templates/rsyslog/rsyslog.conf.j2 | 14 -------- .../include/version/system-version.xml.i | 2 +- interface-definitions/system_syslog.xml.in | 39 ---------------------- src/migration-scripts/system/28-to-29 | 29 ++++++++++++++++ 4 files changed, 30 insertions(+), 54 deletions(-) create mode 100644 src/migration-scripts/system/28-to-29 (limited to 'interface-definitions/include/version') diff --git a/data/templates/rsyslog/rsyslog.conf.j2 b/data/templates/rsyslog/rsyslog.conf.j2 index 253a4bee2..67c062ab9 100644 --- a/data/templates/rsyslog/rsyslog.conf.j2 +++ b/data/templates/rsyslog/rsyslog.conf.j2 @@ -24,20 +24,6 @@ $outchannel global,/var/log/messages,262144,/usr/sbin/logrotate {{ logrotate }} {{ tmp | join(';') }} :omfile:$global {% endif %} -{% if file is vyos_defined %} -# File based configuration section -{% for file_name, file_options in file.items() %} -{% set tmp = [] %} -$outchannel {{ file_name }},/var/log/user/{{ file_name }},{{ file_options.archive.size }},/usr/sbin/logrotate {{ logrotate }} -{% if file_options.facility is vyos_defined %} -{% for facility, facility_options in file_options.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} -{% endfor %} -{% endif %} -{{ tmp | join(';') }} :omfile:${{ file }} -{% endfor %} -{% endif %} - {% if console.facility is vyos_defined %} # Console logging {% set tmp = [] %} diff --git a/interface-definitions/include/version/system-version.xml.i b/interface-definitions/include/version/system-version.xml.i index 3ecf124c7..5cdece74a 100644 --- a/interface-definitions/include/version/system-version.xml.i +++ b/interface-definitions/include/version/system-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/system_syslog.xml.in b/interface-definitions/system_syslog.xml.in index 0a9a00572..1d5b3635f 100644 --- a/interface-definitions/system_syslog.xml.in +++ b/interface-definitions/system_syslog.xml.in @@ -106,45 +106,6 @@ - - - Logging to a file - - [a-zA-Z0-9\-_.]{1,255} - - illegal characters in filename or filename longer than 255 characters - - - - - Log file size and rotation characteristics - - - - - Number of saved files - - [0-9]+ - - illegal characters in number of files - - 5 - - - - Size of log files in kbytes - - [0-9]+ - - illegal characters in size - - 256 - - - - #include - - logging to serial console diff --git a/src/migration-scripts/system/28-to-29 b/src/migration-scripts/system/28-to-29 new file mode 100644 index 000000000..e12063fc4 --- /dev/null +++ b/src/migration-scripts/system/28-to-29 @@ -0,0 +1,29 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T6989: +# - remove syslog arbitrary file logging +# - remove syslog user console logging + +from vyos.configtree import ConfigTree + +base = ['system', 'syslog'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + return + + if config.exists(base + ['file']): + config.delete(base + ['file']) -- cgit v1.2.3 From 6ab9de170c7a4ad51b60ed0c576db25831ce745a Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Thu, 13 Feb 2025 20:39:14 +0100 Subject: bgp: T7163: add CLI route-map and metric support for "redistribute table" * set protocols bgp address-family redistribute table [metric ] [route-map ] --- data/templates/frr/bgpd.frr.j2 | 4 +- .../bgp/afi-redistribute-common-protocols.xml.i | 8 ++- .../include/version/bgp-version.xml.i | 2 +- smoketest/config-tests/bgp-rpki | 1 + smoketest/configs/bgp-rpki | 7 ++ smoketest/scripts/cli/test_protocols_bgp.py | 76 +++++++++++++++++----- src/migration-scripts/bgp/5-to-6 | 39 +++++++++++ 7 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 src/migration-scripts/bgp/5-to-6 (limited to 'interface-definitions/include/version') diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index 2f3719fdf..3b462b4a9 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -310,8 +310,8 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% if afi_config.redistribute is vyos_defined %} {% for protocol, protocol_config in afi_config.redistribute.items() %} {% if protocol == 'table' %} -{% for table in protocol_config %} - redistribute table-direct {{ table }} +{% for table, table_config in protocol_config.items() %} + redistribute table-direct {{ table }} {{ 'metric ' ~ table_config.metric if table_config.metric is vyos_defined }} {{ 'route-map ' ~ table_config.route_map if table_config.route_map is vyos_defined }} {% endfor %} {% else %} {% set redistribution_protocol = protocol %} diff --git a/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i b/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i index f4d18bc70..141a704c7 100644 --- a/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i +++ b/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i @@ -39,14 +39,16 @@ #include - + Redistribute non-main Kernel Routing Table protocols static table #include - - + + #include + + diff --git a/interface-definitions/include/version/bgp-version.xml.i b/interface-definitions/include/version/bgp-version.xml.i index 6bed7189f..c90276151 100644 --- a/interface-definitions/include/version/bgp-version.xml.i +++ b/interface-definitions/include/version/bgp-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/smoketest/config-tests/bgp-rpki b/smoketest/config-tests/bgp-rpki index 587de67c6..657d4abcc 100644 --- a/smoketest/config-tests/bgp-rpki +++ b/smoketest/config-tests/bgp-rpki @@ -13,6 +13,7 @@ set policy route-map ebgp-transit-rpki rule 30 set local-preference '100' set policy route-map ebgp-transit-rpki rule 40 action 'permit' set policy route-map ebgp-transit-rpki rule 40 set extcommunity rt '192.0.2.100:100' set policy route-map ebgp-transit-rpki rule 40 set extcommunity soo '64500:100' +set protocols bgp address-family ipv4-unicast redistribute table 100 set protocols bgp neighbor 1.2.3.4 address-family ipv4-unicast nexthop-self set protocols bgp neighbor 1.2.3.4 address-family ipv4-unicast route-map import 'ebgp-transit-rpki' set protocols bgp neighbor 1.2.3.4 remote-as '10' diff --git a/smoketest/configs/bgp-rpki b/smoketest/configs/bgp-rpki index 5588f15c9..2d136d545 100644 --- a/smoketest/configs/bgp-rpki +++ b/smoketest/configs/bgp-rpki @@ -46,6 +46,13 @@ policy { } protocols { bgp 64500 { + address-family { + ipv4-unicast { + redistribute { + table 100 + } + } + } neighbor 1.2.3.4 { address-family { ipv4-unicast { diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 0eda52ff6..0c6d36213 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021-2024 VyOS maintainers and contributors +# Copyright (C) 2021-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -685,14 +685,30 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): 'route_map' : 'redistr-ipv4-static', }, 'table' : { - 'number' : ['10', '20', '30', '40'], + '10' : { + 'metric' : '810', + 'route_map' : 'redistr-ipv4-table-10', + }, + '20' : { + 'metric' : '820', + 'route_map' : 'redistr-ipv4-table-20', + }, + '30' : { + 'metric' : '830', + 'route_map' : 'redistr-ipv4-table-30', + }, }, } for proto, proto_config in redistributes.items(): proto_path = base_path + ['address-family', 'ipv4-unicast', 'redistribute', proto] - if proto == 'table' and 'number' in proto_config: - for number in proto_config['number']: - self.cli_set(proto_path, value=number) + if proto == 'table': + for table, table_config in proto_config.items(): + self.cli_set(proto_path + [table]) + if 'metric' in table_config: + self.cli_set(proto_path + [table, 'metric'], value=table_config['metric']) + if 'route_map' in table_config: + self.cli_set(['policy', 'route-map', table_config['route_map'], 'rule', '10', 'action'], value='permit') + self.cli_set(proto_path + [table, 'route-map'], value=table_config['route_map']) else: self.cli_set(proto_path) if 'metric' in proto_config: @@ -723,9 +739,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(' address-family ipv4 unicast', frrconfig) for proto, proto_config in redistributes.items(): - if proto == 'table' and 'number' in proto_config: - for number in proto_config['number']: - self.assertIn(f' redistribute table-direct {number}', frrconfig) + if proto == 'table': + for table, table_config in proto_config.items(): + tmp = f' redistribute table-direct {table}' + if 'metric' in proto_config: + metric = proto_config['metric'] + tmp += f' metric {metric}' + if 'route_map' in proto_config: + route_map = proto_config['route_map'] + tmp += f' route-map {route_map}' + self.assertIn(tmp, frrconfig) else: tmp = f' redistribute {proto}' if 'metric' in proto_config: @@ -794,14 +817,30 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): 'route_map' : 'redistr-ipv6-static', }, 'table' : { - 'number' : ['100', '120', '130', '140'], + '110' : { + 'metric' : '811', + 'route_map' : 'redistr-ipv6-table-110', + }, + '120' : { + 'metric' : '821', + 'route_map' : 'redistr-ipv6-table-120', + }, + '130' : { + 'metric' : '831', + 'route_map' : 'redistr-ipv6-table-130', + }, }, } for proto, proto_config in redistributes.items(): proto_path = base_path + ['address-family', 'ipv6-unicast', 'redistribute', proto] - if proto == 'table' and 'number' in proto_config: - for number in proto_config['number']: - self.cli_set(proto_path, value=number) + if proto == 'table': + for table, table_config in proto_config.items(): + self.cli_set(proto_path + [table]) + if 'metric' in table_config: + self.cli_set(proto_path + [table, 'metric'], value=table_config['metric']) + if 'route_map' in table_config: + self.cli_set(['policy', 'route-map', table_config['route_map'], 'rule', '10', 'action'], value='permit') + self.cli_set(proto_path + [table, 'route-map'], value=table_config['route_map']) else: self.cli_set(proto_path) if 'metric' in proto_config: @@ -829,9 +868,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(' no bgp ebgp-requires-policy', frrconfig) for proto, proto_config in redistributes.items(): - if proto == 'table' and 'number' in proto_config: - for number in proto_config['number']: - self.assertIn(f' redistribute table-direct {number}', frrconfig) + if proto == 'table': + for table, table_config in proto_config.items(): + tmp = f' redistribute table-direct {table}' + if 'metric' in proto_config: + metric = proto_config['metric'] + tmp += f' metric {metric}' + if 'route_map' in proto_config: + route_map = proto_config['route_map'] + tmp += f' route-map {route_map}' + self.assertIn(tmp, frrconfig) else: # FRR calls this OSPF6 if proto == 'ospfv3': diff --git a/src/migration-scripts/bgp/5-to-6 b/src/migration-scripts/bgp/5-to-6 new file mode 100644 index 000000000..e6fea6574 --- /dev/null +++ b/src/migration-scripts/bgp/5-to-6 @@ -0,0 +1,39 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7163: migrate "address-family ipv4|6-unicast redistribute table" from a multi +# leafNode to a tagNode. This is needed to support per table definition of a +# route-map and/or metric + +from vyos.configtree import ConfigTree + +def migrate(config: ConfigTree) -> None: + bgp_base = ['protocols', 'bgp'] + if not config.exists(bgp_base): + return + + for address_family in ['ipv4-unicast', 'ipv6-unicast']: + # there is no non-main routing table beeing redistributed under this addres family + # bail out early and continue with next AFI + table_path = bgp_base + ['address-family', address_family, 'redistribute', 'table'] + if not config.exists(table_path): + continue + + tables = config.return_values(table_path) + config.delete(table_path) + + for table in tables: + config.set(table_path + [table]) + config.set_tag(table_path) -- cgit v1.2.3 From 216e80b61881a13c502f44c5d32fd7603b6ffe60 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Mon, 24 Feb 2025 20:54:25 +0100 Subject: lldp: T7165: add support to enable only rx or tx on specific interface LLDP is a stateless protocol which does not necessitate sending to receive advertisements. There are multiple scenarios such as provider peering links in which it is advantageous to receive LLDP but not disclose internal information to the provider. Add new CLI command: * set service lldp interface mode [disable|rx-tx|rx|tx] The default is unchanged and will be rx-tx. Furthermore if an interface has an explicit LLDP disable configured under "set service lldp interface disable" this will be migrated to "set service lldp interface mode disable" --- data/templates/lldp/vyos.conf.j2 | 11 ++++- .../include/version/lldp-version.xml.i | 2 +- interface-definitions/service_lldp.xml.in | 29 ++++++++++++- smoketest/config-tests/dialup-router-complex | 1 + smoketest/config-tests/nat-basic | 2 +- smoketest/configs/dialup-router-complex | 3 ++ smoketest/scripts/cli/test_service_lldp.py | 49 +++++++++++++++++++++- src/migration-scripts/lldp/2-to-3 | 31 ++++++++++++++ 8 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 src/migration-scripts/lldp/2-to-3 (limited to 'interface-definitions/include/version') diff --git a/data/templates/lldp/vyos.conf.j2 b/data/templates/lldp/vyos.conf.j2 index 4b4228cea..432a7a8e6 100644 --- a/data/templates/lldp/vyos.conf.j2 +++ b/data/templates/lldp/vyos.conf.j2 @@ -4,7 +4,7 @@ configure system platform VyOS configure system description "VyOS {{ version }}" {% if interface is vyos_defined %} {% set tmp = [] %} -{% for iface, iface_options in interface.items() if iface_options.disable is not vyos_defined %} +{% for iface, iface_options in interface.items() %} {% if iface == 'all' %} {% set iface = '*' %} {% endif %} @@ -17,6 +17,15 @@ configure ports {{ iface }} med location elin "{{ iface_options.location.elin }} configure ports {{ iface }} med location coordinate latitude "{{ iface_options.location.coordinate_based.latitude }}" longitude "{{ iface_options.location.coordinate_based.longitude }}" altitude "{{ iface_options.location.coordinate_based.altitude }}m" datum "{{ iface_options.location.coordinate_based.datum }}" {% endif %} {% endif %} +{% set mode = iface_options.mode %} +{% if mode == 'tx' %} +{% set mode = 'tx-only' %} +{% elif mode == 'rx' %} +{% set mode = 'rx-only' %} +{% elif mode == 'rx-tx' %} +{% set mode = 'rx-and-tx' %} +{% endif %} +configure ports {{ iface }} lldp status {{ mode }} {% endfor %} configure system interface pattern "{{ tmp | join(",") }}" {% endif %} diff --git a/interface-definitions/include/version/lldp-version.xml.i b/interface-definitions/include/version/lldp-version.xml.i index b41d80451..a7110691a 100644 --- a/interface-definitions/include/version/lldp-version.xml.i +++ b/interface-definitions/include/version/lldp-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/service_lldp.xml.in b/interface-definitions/service_lldp.xml.in index 51a9f9cce..a189cc13b 100644 --- a/interface-definitions/service_lldp.xml.in +++ b/interface-definitions/service_lldp.xml.in @@ -29,7 +29,34 @@ - #include + + + Set LLDP receive/transmit operation mode of this interface + + disable rx-tx tx rx + + + disable + Do not process or send LLDP messages + + + rx-tx + Send and process LLDP messages + + + rx + Process incoming LLDP messages + + + tx + Send LLDP messages + + + (disable|rx-tx|tx|rx) + + + rx-tx + LLDP-MED location data diff --git a/smoketest/config-tests/dialup-router-complex b/smoketest/config-tests/dialup-router-complex index c356c73c0..12edcfef2 100644 --- a/smoketest/config-tests/dialup-router-complex +++ b/smoketest/config-tests/dialup-router-complex @@ -695,6 +695,7 @@ set service dns forwarding ignore-hosts-file set service dns forwarding listen-address '172.16.254.30' set service dns forwarding listen-address '172.31.0.254' set service dns forwarding negative-ttl '60' +set service lldp interface pppoe0 mode 'disable' set service lldp legacy-protocols cdp set service lldp snmp set service mdns repeater interface 'eth0.35' diff --git a/smoketest/config-tests/nat-basic b/smoketest/config-tests/nat-basic index ba2b1b838..f1cc0121d 100644 --- a/smoketest/config-tests/nat-basic +++ b/smoketest/config-tests/nat-basic @@ -60,7 +60,7 @@ set service dhcp-server shared-network-name LAN subnet 192.168.189.0/24 range 0 set service dhcp-server shared-network-name LAN subnet 192.168.189.0/24 range 0 stop '192.168.189.254' set service dhcp-server shared-network-name LAN subnet 192.168.189.0/24 subnet-id '1' set service lldp interface all -set service lldp interface eth1 disable +set service lldp interface eth1 mode 'disable' set service ntp allow-client address '192.168.189.0/24' set service ntp listen-address '192.168.189.1' set service ntp server time1.vyos.net diff --git a/smoketest/configs/dialup-router-complex b/smoketest/configs/dialup-router-complex index aa9837fe9..018379bcd 100644 --- a/smoketest/configs/dialup-router-complex +++ b/smoketest/configs/dialup-router-complex @@ -1392,6 +1392,9 @@ service { } } lldp { + interface pppoe0 { + disable + } legacy-protocols { cdp } diff --git a/smoketest/scripts/cli/test_service_lldp.py b/smoketest/scripts/cli/test_service_lldp.py index 9d72ef78f..c73707e0d 100755 --- a/smoketest/scripts/cli/test_service_lldp.py +++ b/smoketest/scripts/cli/test_service_lldp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022-2024 VyOS maintainers and contributors +# Copyright (C) 2022-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -117,6 +117,8 @@ class TestServiceLLDP(VyOSUnitTestSHIM.TestCase): config = read_file(LLDPD_CONF) self.assertIn(f'configure ports {interface} med location elin "{elin}"', config) + # This is the CLI default mode + self.assertIn(f'configure ports {interface} lldp status rx-and-tx', config) self.assertIn(f'configure system interface pattern "{interface}"', config) def test_06_lldp_snmp(self): @@ -134,5 +136,50 @@ class TestServiceLLDP(VyOSUnitTestSHIM.TestCase): self.cli_delete(['service', 'snmp']) + def test_07_lldp_interface_mode(self): + interfaces = Section.interfaces('ethernet', vlan=False) + + # set interface mode to 'tx' + self.cli_set(base_path + ['interface', 'all']) + for interface in interfaces: + self.cli_set(base_path + ['interface', interface, 'mode', 'disable']) + # commit changes + self.cli_commit() + + # verify configuration + config = read_file(LLDPD_CONF) + for interface in interfaces: + self.assertIn(f'configure ports {interface} lldp status disable', config) + + # Change configuration to rx-only + for interface in interfaces: + self.cli_set(base_path + ['interface', interface, 'mode', 'rx']) + # commit changes + self.cli_commit() + # verify configuration + config = read_file(LLDPD_CONF) + for interface in interfaces: + self.assertIn(f'configure ports {interface} lldp status rx-only', config) + + # Change configuration to tx-only + for interface in interfaces: + self.cli_set(base_path + ['interface', interface, 'mode', 'tx']) + # commit changes + self.cli_commit() + # verify configuration + config = read_file(LLDPD_CONF) + for interface in interfaces: + self.assertIn(f'configure ports {interface} lldp status tx-only', config) + + # Change configuration to rx-only + for interface in interfaces: + self.cli_set(base_path + ['interface', interface, 'mode', 'rx-tx']) + # commit changes + self.cli_commit() + # verify configuration + config = read_file(LLDPD_CONF) + for interface in interfaces: + self.assertIn(f'configure ports {interface} lldp status rx-and-tx', config) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/migration-scripts/lldp/2-to-3 b/src/migration-scripts/lldp/2-to-3 new file mode 100644 index 000000000..93090756c --- /dev/null +++ b/src/migration-scripts/lldp/2-to-3 @@ -0,0 +1,31 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7165: Migrate LLDP interface disable to 'mode disable' + +from vyos.configtree import ConfigTree + +base = ['service', 'lldp'] + +def migrate(config: ConfigTree) -> None: + interface_base = base + ['interface'] + if not config.exists(interface_base): + # Nothing to do + return + + for interface in config.list_nodes(interface_base): + if config.exists(interface_base + [interface, 'disable']): + config.delete(interface_base + [interface, 'disable']) + config.set(interface_base + [interface, 'mode'], value='disable') -- cgit v1.2.3 From ab9213910aef95161d365e046d13cdf1b79738d9 Mon Sep 17 00:00:00 2001 From: Andrew Topp Date: Wed, 26 Feb 2025 22:20:41 +1000 Subject: policy: T7116: migrate legacy use of "internet" as a well-known community name This has been split into a separate commit in case this is overkill for the fix. 1.2 and 1.3 installs predate the change to FRR that removed support, but "internet" is already broken on 1.4. --- .../include/version/policy-version.xml.i | 2 +- src/migration-scripts/policy/8-to-9 | 49 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/migration-scripts/policy/8-to-9 (limited to 'interface-definitions/include/version') diff --git a/interface-definitions/include/version/policy-version.xml.i b/interface-definitions/include/version/policy-version.xml.i index db727fea9..5c53a4032 100644 --- a/interface-definitions/include/version/policy-version.xml.i +++ b/interface-definitions/include/version/policy-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/src/migration-scripts/policy/8-to-9 b/src/migration-scripts/policy/8-to-9 new file mode 100644 index 000000000..355e48e00 --- /dev/null +++ b/src/migration-scripts/policy/8-to-9 @@ -0,0 +1,49 @@ +# Copyright (C) 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7116: Remove unsupported "internet" community following FRR removal +# From + # set policy route-map rule set community [add | replace] internet + # set policy community-list rule regex internet +# To + # set policy route-map rule set community [add | replace] 0:0 + # set policy community-list rule regex _0:0_ + +# NOTE: In FRR expanded community-lists, without the '_' delimiters, a regex of +# "0:0" will match "65000:0" as well as "0:0". This doesn't line up with what +# we want when replacing "internet". + +from vyos.configtree import ConfigTree + +rm_base = ['policy', 'route-map'] +cl_base = ['policy', 'community-list'] + +def migrate(config: ConfigTree) -> None: + if config.exists(rm_base): + for policy_name in config.list_nodes(rm_base): + for rule_ord in config.list_nodes(rm_base + [policy_name, 'rule'], path_must_exist=False): + tmp_path = rm_base + [policy_name, 'rule', rule_ord, 'set', 'community'] + if config.exists(tmp_path + ['add']) and config.return_value(tmp_path + ['add']) == 'internet': + config.set(tmp_path + ['add'], '0:0') + if config.exists(tmp_path + ['replace']) and config.return_value(tmp_path + ['replace']) == 'internet': + config.set(tmp_path + ['replace'], '0:0') + + if config.exists(cl_base): + for policy_name in config.list_nodes(cl_base): + for rule_ord in config.list_nodes(cl_base + [policy_name, 'rule'], path_must_exist=False): + tmp_path = cl_base + [policy_name, 'rule', rule_ord, 'regex'] + if config.exists(tmp_path) and config.return_value(tmp_path) == 'internet': + config.set(tmp_path, '_0:0_') + -- cgit v1.2.3 From 92ad401f0b7459fa3c50092a1bdd8255946e5661 Mon Sep 17 00:00:00 2001 From: Simon <965089+sarthurdev@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:11:35 +0100 Subject: wlb: T7196: Migrate interface wildcards to nftables format * wlb: T7196: Migrate interface wildcards to nftables format * wlb: T7196: Fix exclude/interface verify check * wlb: T7196: Extra sanity check on ipv4 address function --- .../include/version/wanloadbalance-version.xml.i | 2 +- smoketest/scripts/cli/test_load-balancing_wan.py | 6 +++- src/conf_mode/load-balancing_wan.py | 6 ++-- src/helpers/vyos-load-balancer.py | 4 +-- src/migration-scripts/wanloadbalance/3-to-4 | 33 ++++++++++++++++++++++ 5 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 src/migration-scripts/wanloadbalance/3-to-4 (limited to 'interface-definitions/include/version') diff --git a/interface-definitions/include/version/wanloadbalance-version.xml.i b/interface-definitions/include/version/wanloadbalance-version.xml.i index 59f8729cc..34c3c76ff 100644 --- a/interface-definitions/include/version/wanloadbalance-version.xml.i +++ b/interface-definitions/include/version/wanloadbalance-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/smoketest/scripts/cli/test_load-balancing_wan.py b/smoketest/scripts/cli/test_load-balancing_wan.py index f652988b2..32e5f6915 100755 --- a/smoketest/scripts/cli/test_load-balancing_wan.py +++ b/smoketest/scripts/cli/test_load-balancing_wan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022-2024 VyOS maintainers and contributors +# Copyright (C) 2022-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -272,6 +272,9 @@ echo "$ifname - $state" > {hook_output_path} self.cli_set(base_path + ['wan', 'interface-health', isp2_iface, 'failure-count', '1']) self.cli_set(base_path + ['wan', 'interface-health', isp2_iface, 'nexthop', '192.0.2.2']) self.cli_set(base_path + ['wan', 'interface-health', isp2_iface, 'success-count', '1']) + self.cli_set(base_path + ['wan', 'rule', '5', 'exclude']) + self.cli_set(base_path + ['wan', 'rule', '5', 'inbound-interface', 'eth*']) + self.cli_set(base_path + ['wan', 'rule', '5', 'destination', 'address', '10.0.0.0/8']) self.cli_set(base_path + ['wan', 'rule', '10', 'failover']) self.cli_set(base_path + ['wan', 'rule', '10', 'inbound-interface', lan_iface]) self.cli_set(base_path + ['wan', 'rule', '10', 'protocol', 'udp']) @@ -291,6 +294,7 @@ echo "$ifname - $state" > {hook_output_path} # Verify isp1 + criteria nftables_search = [ + [f'iifname "eth*"', 'ip daddr 10.0.0.0/8', 'return'], [f'iifname "{lan_iface}"', 'ip saddr 198.51.100.0/24', 'udp sport 53', 'ip daddr 192.0.2.0/24', 'udp dport 53', f'jump wlb_mangle_isp_{isp1_iface}'] ] diff --git a/src/conf_mode/load-balancing_wan.py b/src/conf_mode/load-balancing_wan.py index b3dd80a9a..92d9acfba 100755 --- a/src/conf_mode/load-balancing_wan.py +++ b/src/conf_mode/load-balancing_wan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2023-2024 VyOS maintainers and contributors +# Copyright (C) 2023-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -71,8 +71,8 @@ def verify(lb): if 'rule' in lb: for rule_id, rule_conf in lb['rule'].items(): - if 'interface' not in rule_conf: - raise ConfigError(f'Interface not specified on load-balancing wan rule {rule_id}') + if 'interface' not in rule_conf and 'exclude' not in rule_conf: + raise ConfigError(f'Interface or exclude not specified on load-balancing wan rule {rule_id}') if 'failover' in rule_conf and 'exclude' in rule_conf: raise ConfigError(f'Failover cannot be configured with exclude on load-balancing wan rule {rule_id}') diff --git a/src/helpers/vyos-load-balancer.py b/src/helpers/vyos-load-balancer.py index 2f07160b4..30329fd5c 100755 --- a/src/helpers/vyos-load-balancer.py +++ b/src/helpers/vyos-load-balancer.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -# Copyright 2024 VyOS maintainers and contributors +# Copyright 2024-2025 VyOS maintainers and contributors # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -95,7 +95,7 @@ def on_state_change(lb, ifname, state): def get_ipv4_address(ifname): # Get primary ipv4 address on interface (for source nat) addr_json = get_interface_address(ifname) - if 'addr_info' in addr_json and len(addr_json['addr_info']) > 0: + if addr_json and 'addr_info' in addr_json and len(addr_json['addr_info']) > 0: for addr_info in addr_json['addr_info']: if addr_info['family'] == 'inet': if 'local' in addr_info: diff --git a/src/migration-scripts/wanloadbalance/3-to-4 b/src/migration-scripts/wanloadbalance/3-to-4 new file mode 100644 index 000000000..e49f46a5b --- /dev/null +++ b/src/migration-scripts/wanloadbalance/3-to-4 @@ -0,0 +1,33 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from vyos.configtree import ConfigTree + +base = ['load-balancing', 'wan'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + # Nothing to do + return + + if config.exists(base + ['rule']): + for rule in config.list_nodes(base + ['rule']): + rule_base = base + ['rule', rule] + + if config.exists(rule_base + ['inbound-interface']): + ifname = config.return_value(rule_base + ['inbound-interface']) + + if ifname.endswith('+'): + config.set(rule_base + ['inbound-interface'], value=ifname.replace('+', '*')) -- cgit v1.2.3 From 5797e2c0f489272f2ff32b3884ea756f306b50e4 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Mon, 14 Apr 2025 11:56:36 +0100 Subject: ids: T7241: remove Fastnetmon from the base system It will eventually be moved to an addon --- data/templates/ids/fastnetmon.j2 | 121 --------------- .../ids/fastnetmon_excluded_networks_list.j2 | 5 - data/templates/ids/fastnetmon_networks_list.j2 | 5 - debian/control | 1 - debian/vyos-1x.postinst | 2 - .../include/version/ids-version.xml.i | 2 +- .../service_ids_ddos-protection.xml.in | 167 --------------------- op-mode-definitions/monitor-log.xml.in | 13 -- op-mode-definitions/show-log.xml.in | 13 -- .../cli/test_service_ids_ddos-protection.py | 116 -------------- src/conf_mode/service_ids_ddos-protection.py | 104 ------------- .../system/fastnetmon.service.d/override.conf | 12 -- src/migration-scripts/ids/1-to-2 | 30 ++++ 13 files changed, 31 insertions(+), 560 deletions(-) delete mode 100644 data/templates/ids/fastnetmon.j2 delete mode 100644 data/templates/ids/fastnetmon_excluded_networks_list.j2 delete mode 100644 data/templates/ids/fastnetmon_networks_list.j2 delete mode 100644 interface-definitions/service_ids_ddos-protection.xml.in delete mode 100755 smoketest/scripts/cli/test_service_ids_ddos-protection.py delete mode 100755 src/conf_mode/service_ids_ddos-protection.py delete mode 100644 src/etc/systemd/system/fastnetmon.service.d/override.conf create mode 100644 src/migration-scripts/ids/1-to-2 (limited to 'interface-definitions/include/version') diff --git a/data/templates/ids/fastnetmon.j2 b/data/templates/ids/fastnetmon.j2 deleted file mode 100644 index f6f03d0db..000000000 --- a/data/templates/ids/fastnetmon.j2 +++ /dev/null @@ -1,121 +0,0 @@ -# enable this option if you want to send logs to local syslog facility -logging:logging_level = debug -logging:local_syslog_logging = on - -# list of all your networks in CIDR format -networks_list_path = /run/fastnetmon/networks_list - -# list networks in CIDR format which will be not monitored for attacks -white_list_path = /run/fastnetmon/excluded_networks_list - -# Enable/Disable any actions in case of attack -enable_ban = on -enable_ban_ipv6 = on - -## How many packets will be collected from attack traffic -ban_details_records_count = 500 - -## How long (in seconds) we should keep an IP in blocked state -## If you set 0 here it completely disables unban capability -{% if ban_time is vyos_defined %} -ban_time = {{ ban_time }} -{% endif %} - -# Check if the attack is still active, before triggering an unban callback with this option -# If the attack is still active, check each run of the unban watchdog -unban_only_if_attack_finished = on - -# enable per subnet speed meters -# For each subnet, list track speed in bps and pps for both directions -enable_subnet_counters = off - -{% if mode is vyos_defined('mirror') %} -mirror_afpacket = on -{% elif mode is vyos_defined('sflow') %} -sflow = on -{% if sflow.port is vyos_defined %} -sflow_port = {{ sflow.port }} -{% endif %} -{% if sflow.listen_address is vyos_defined %} -sflow_host = {{ sflow.listen_address }} -{% endif %} -{% endif %} - - -process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in direction else 'off' }} -process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }} - -{% if threshold is vyos_defined %} -{% if threshold.general is vyos_defined %} -# General threshold -{% for thr, thr_value in threshold.general.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_flows = on -threshold_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_bandwidth = on -threshold_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_pps = on -threshold_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.tcp is vyos_defined %} -# TCP threshold -{% for thr, thr_value in threshold.tcp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_tcp_flows = on -threshold_tcp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_tcp_bandwidth = on -threshold_tcp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_tcp_pps = on -threshold_tcp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.udp is vyos_defined %} -# UDP threshold -{% for thr, thr_value in threshold.udp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_udp_flows = on -threshold_udp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_udp_bandwidth = on -threshold_udp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_udp_pps = on -threshold_udp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.icmp is vyos_defined %} -# ICMP threshold -{% for thr, thr_value in threshold.icmp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_icmp_flows = on -threshold_icmp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_icmp_bandwidth = on -threshold_icmp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_icmp_pps = on -threshold_icmp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% endif %} - -{% if listen_interface is vyos_defined %} -interfaces = {{ listen_interface | join(',') }} -{% endif %} - -{% if alert_script is vyos_defined %} -notify_script_path = {{ alert_script }} -{% endif %} diff --git a/data/templates/ids/fastnetmon_excluded_networks_list.j2 b/data/templates/ids/fastnetmon_excluded_networks_list.j2 deleted file mode 100644 index c88a1c527..000000000 --- a/data/templates/ids/fastnetmon_excluded_networks_list.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% if excluded_network is vyos_defined %} -{% for net in excluded_network %} -{{ net }} -{% endfor %} -{% endif %} diff --git a/data/templates/ids/fastnetmon_networks_list.j2 b/data/templates/ids/fastnetmon_networks_list.j2 deleted file mode 100644 index 0a0576d2a..000000000 --- a/data/templates/ids/fastnetmon_networks_list.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% if network is vyos_defined %} -{% for net in network %} -{{ net }} -{% endfor %} -{% endif %} diff --git a/debian/control b/debian/control index a19461412..c1d2b2f96 100644 --- a/debian/control +++ b/debian/control @@ -192,7 +192,6 @@ Depends: ddclient (>= 3.11.1), # End "service dns dynamic" # # For "service ids" - fastnetmon [amd64], suricata, suricata-update, # End "service ids" diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst index d83634cfc..ee2748969 100644 --- a/debian/vyos-1x.postinst +++ b/debian/vyos-1x.postinst @@ -221,11 +221,9 @@ fi # Remove unwanted daemon files from /etc # conntackd # pmacct -# fastnetmon # ntp DELETE="/etc/logrotate.d/conntrackd.distrib /etc/init.d/conntrackd /etc/default/conntrackd /etc/default/pmacctd /etc/pmacct - /etc/networks_list /etc/networks_whitelist /etc/fastnetmon.conf /etc/ntp.conf /etc/default/ssh /etc/avahi/avahi-daemon.conf /etc/avahi/hosts /etc/powerdns /etc/default/pdns-recursor /etc/ppp/ip-up.d/0000usepeerdns /etc/ppp/ip-down.d/0000usepeerdns" diff --git a/interface-definitions/include/version/ids-version.xml.i b/interface-definitions/include/version/ids-version.xml.i index 9133be02b..6d4e92c21 100644 --- a/interface-definitions/include/version/ids-version.xml.i +++ b/interface-definitions/include/version/ids-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/service_ids_ddos-protection.xml.in b/interface-definitions/service_ids_ddos-protection.xml.in deleted file mode 100644 index 3ef2640b3..000000000 --- a/interface-definitions/service_ids_ddos-protection.xml.in +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - Intrusion Detection System - - - - - FastNetMon detection and protection parameters - 731 - - - - - Path to fastnetmon alert script - - - - - How long we should keep an IP in blocked state - - u32:1-4294967294 - Time in seconds - - - - - - 1900 - - - - Direction for processing traffic - - in out - - - (in|out) - - - - - - - Specify IPv4 and IPv6 networks which are going to be excluded from protection - - ipv4net - IPv4 prefix(es) to exclude - - - ipv6net - IPv6 prefix(es) to exclude - - - - - - - - - - - Listen interface for mirroring traffic - - - - - - - - - Traffic capture mode - - mirror sflow - - - mirror - Listen to mirrored traffic - - - sflow - Capture sFlow flows - - - (mirror|sflow) - - - - - - Sflow settings - - - #include - #include - - 6343 - - - - - - Specify IPv4 and IPv6 networks which belong to you - - ipv4net - Your IPv4 prefix(es) - - - ipv6net - Your IPv6 prefix(es) - - - - - - - - - - - Attack limits thresholds - - - - - General threshold - - - #include - - - - - TCP threshold - - - #include - - - - - UDP threshold - - - #include - - - - - ICMP threshold - - - #include - - - - - - - - - - - diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in index 6a2b7e53b..cde28f284 100644 --- a/op-mode-definitions/monitor-log.xml.in +++ b/op-mode-definitions/monitor-log.xml.in @@ -17,19 +17,6 @@ SYSTEMD_LOG_COLOR=false grc journalctl --no-hostname --follow --boot - - - Monitor Intrusion Detection System log - - - - - Monitor last lines of DDOS protection - - journalctl --no-hostname --follow --boot --unit fastnetmon.service - - - Monitor last lines of certbot log diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in index c2504686d..e792ace0e 100755 --- a/op-mode-definitions/show-log.xml.in +++ b/op-mode-definitions/show-log.xml.in @@ -62,19 +62,6 @@ journalctl --no-hostname --boot --unit conserver-server.service - - - Show log for for Intrusion Detection System - - - - - Show log for DDOS protection - - journalctl --no-hostname --boot --unit fastnetmon.service - - - Show log for Dynamic Host Control Protocol (DHCP) diff --git a/smoketest/scripts/cli/test_service_ids_ddos-protection.py b/smoketest/scripts/cli/test_service_ids_ddos-protection.py deleted file mode 100755 index 91b056eea..000000000 --- a/smoketest/scripts/cli/test_service_ids_ddos-protection.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2022 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os -import unittest - -from base_vyostest_shim import VyOSUnitTestSHIM - -from vyos.configsession import ConfigSessionError -from vyos.utils.process import process_named_running -from vyos.utils.file import read_file - -PROCESS_NAME = 'fastnetmon' -FASTNETMON_CONF = '/run/fastnetmon/fastnetmon.conf' -NETWORKS_CONF = '/run/fastnetmon/networks_list' -EXCLUDED_NETWORKS_CONF = '/run/fastnetmon/excluded_networks_list' -base_path = ['service', 'ids', 'ddos-protection'] - -class TestServiceIDS(VyOSUnitTestSHIM.TestCase): - @classmethod - def setUpClass(cls): - super(TestServiceIDS, cls).setUpClass() - - # ensure we can also run this test on a live system - so lets clean - # out the current configuration :) - cls.cli_delete(cls, base_path) - - def tearDown(self): - # Check for running process - self.assertTrue(process_named_running(PROCESS_NAME)) - - # delete test config - self.cli_delete(base_path) - self.cli_commit() - - self.assertFalse(os.path.exists(FASTNETMON_CONF)) - self.assertFalse(process_named_running(PROCESS_NAME)) - - def test_fastnetmon(self): - networks = ['10.0.0.0/24', '10.5.5.0/24', '2001:db8:10::/64', '2001:db8:20::/64'] - excluded_networks = ['10.0.0.1/32', '2001:db8:10::1/128'] - interfaces = ['eth0', 'eth1'] - fps = '3500' - mbps = '300' - pps = '60000' - - self.cli_set(base_path + ['mode', 'mirror']) - # Required network! - with self.assertRaises(ConfigSessionError): - self.cli_commit() - for tmp in networks: - self.cli_set(base_path + ['network', tmp]) - - # optional excluded-network! - with self.assertRaises(ConfigSessionError): - self.cli_commit() - for tmp in excluded_networks: - self.cli_set(base_path + ['excluded-network', tmp]) - - # Required interface(s)! - with self.assertRaises(ConfigSessionError): - self.cli_commit() - for tmp in interfaces: - self.cli_set(base_path + ['listen-interface', tmp]) - - self.cli_set(base_path + ['direction', 'in']) - self.cli_set(base_path + ['threshold', 'general', 'fps', fps]) - self.cli_set(base_path + ['threshold', 'general', 'pps', pps]) - self.cli_set(base_path + ['threshold', 'general', 'mbps', mbps]) - - # commit changes - self.cli_commit() - - # Check configured port - config = read_file(FASTNETMON_CONF) - self.assertIn(f'mirror_afpacket = on', config) - self.assertIn(f'process_incoming_traffic = on', config) - self.assertIn(f'process_outgoing_traffic = off', config) - self.assertIn(f'ban_for_flows = on', config) - self.assertIn(f'threshold_flows = {fps}', config) - self.assertIn(f'ban_for_bandwidth = on', config) - self.assertIn(f'threshold_mbps = {mbps}', config) - self.assertIn(f'ban_for_pps = on', config) - self.assertIn(f'threshold_pps = {pps}', config) - # default - self.assertIn(f'enable_ban = on', config) - self.assertIn(f'enable_ban_ipv6 = on', config) - self.assertIn(f'ban_time = 1900', config) - - tmp = ','.join(interfaces) - self.assertIn(f'interfaces = {tmp}', config) - - - network_config = read_file(NETWORKS_CONF) - for tmp in networks: - self.assertIn(f'{tmp}', network_config) - - excluded_network_config = read_file(EXCLUDED_NETWORKS_CONF) - for tmp in excluded_networks: - self.assertIn(f'{tmp}', excluded_network_config) - -if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/src/conf_mode/service_ids_ddos-protection.py b/src/conf_mode/service_ids_ddos-protection.py deleted file mode 100755 index 276a71fcb..000000000 --- a/src/conf_mode/service_ids_ddos-protection.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2018-2023 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os - -from sys import exit - -from vyos.config import Config -from vyos.template import render -from vyos.utils.process import call -from vyos import ConfigError -from vyos import airbag -airbag.enable() - -config_file = r'/run/fastnetmon/fastnetmon.conf' -networks_list = r'/run/fastnetmon/networks_list' -excluded_networks_list = r'/run/fastnetmon/excluded_networks_list' -attack_dir = '/var/log/fastnetmon_attacks' - -def get_config(config=None): - if config: - conf = config - else: - conf = Config() - base = ['service', 'ids', 'ddos-protection'] - if not conf.exists(base): - return None - - fastnetmon = conf.get_config_dict(base, key_mangling=('-', '_'), - get_first_key=True, - with_recursive_defaults=True) - - return fastnetmon - -def verify(fastnetmon): - if not fastnetmon: - return None - - if 'mode' not in fastnetmon: - raise ConfigError('Specify operating mode!') - - if fastnetmon.get('mode') == 'mirror' and 'listen_interface' not in fastnetmon: - raise ConfigError("Incorrect settings for 'mode mirror': must specify interface(s) for traffic mirroring") - - if fastnetmon.get('mode') == 'sflow' and 'listen_address' not in fastnetmon.get('sflow', {}): - raise ConfigError("Incorrect settings for 'mode sflow': must specify sFlow 'listen-address'") - - if 'alert_script' in fastnetmon: - if os.path.isfile(fastnetmon['alert_script']): - # Check script permissions - if not os.access(fastnetmon['alert_script'], os.X_OK): - raise ConfigError('Script "{alert_script}" is not executable!'.format(fastnetmon['alert_script'])) - else: - raise ConfigError('File "{alert_script}" does not exists!'.format(fastnetmon)) - -def generate(fastnetmon): - if not fastnetmon: - for file in [config_file, networks_list]: - if os.path.isfile(file): - os.unlink(file) - - return None - - # Create dir for log attack details - if not os.path.exists(attack_dir): - os.mkdir(attack_dir) - - render(config_file, 'ids/fastnetmon.j2', fastnetmon) - render(networks_list, 'ids/fastnetmon_networks_list.j2', fastnetmon) - render(excluded_networks_list, 'ids/fastnetmon_excluded_networks_list.j2', fastnetmon) - return None - -def apply(fastnetmon): - systemd_service = 'fastnetmon.service' - if not fastnetmon: - # Stop fastnetmon service if removed - call(f'systemctl stop {systemd_service}') - else: - call(f'systemctl reload-or-restart {systemd_service}') - - return None - -if __name__ == '__main__': - try: - c = get_config() - verify(c) - generate(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) diff --git a/src/etc/systemd/system/fastnetmon.service.d/override.conf b/src/etc/systemd/system/fastnetmon.service.d/override.conf deleted file mode 100644 index 841666070..000000000 --- a/src/etc/systemd/system/fastnetmon.service.d/override.conf +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -RequiresMountsFor=/run -ConditionPathExists=/run/fastnetmon/fastnetmon.conf -After= -After=vyos-router.service - -[Service] -Type=simple -WorkingDirectory=/run/fastnetmon -PIDFile=/run/fastnetmon.pid -ExecStart= -ExecStart=/usr/sbin/fastnetmon --configuration_file /run/fastnetmon/fastnetmon.conf diff --git a/src/migration-scripts/ids/1-to-2 b/src/migration-scripts/ids/1-to-2 new file mode 100644 index 000000000..4c0333c88 --- /dev/null +++ b/src/migration-scripts/ids/1-to-2 @@ -0,0 +1,30 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T: Migrate threshold and add new threshold types + +from vyos.configtree import ConfigTree + +# The old 'service ids' path was only used for FastNetMon +# Suricata is in 'service suricata', +# so this isn't an overreach +base = ['service', 'ids'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + # Nothing to do + return + else: + config.delete(base) -- cgit v1.2.3 From 876786654552b40180a34b73c6eb327722d09e15 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Mon, 5 May 2025 20:52:57 +0200 Subject: haproxy: T7429: remove unsupported logging facility and log level VyOS 1.4.1 implemented support for logging facilities for HAProxy. The facilities got included from the syslog XML definition, which also added "virtual" or non existing facilities in HAProxy, namely: all, authpriv and mark. If any of the above facilities is set, HAProxy will not start. The XML definition for syslog also came with an arbitrary log-level "all" that is also unsupported in HAProxy. This commit adds a migration script removing the illegal CLI nodes. --- .../include/haproxy/logging.xml.i | 132 +++++++++++++++++- .../include/version/reverseproxy-version.xml.i | 2 +- smoketest/config-tests/basic-haproxy | 46 +++++++ smoketest/configs/basic-haproxy | 153 +++++++++++++++++++++ src/migration-scripts/reverse-proxy/2-to-3 | 66 +++++++++ 5 files changed, 397 insertions(+), 2 deletions(-) create mode 100644 smoketest/config-tests/basic-haproxy create mode 100644 smoketest/configs/basic-haproxy create mode 100755 src/migration-scripts/reverse-proxy/2-to-3 (limited to 'interface-definitions/include/version') diff --git a/interface-definitions/include/haproxy/logging.xml.i b/interface-definitions/include/haproxy/logging.xml.i index e0af54fa4..315c959bf 100644 --- a/interface-definitions/include/haproxy/logging.xml.i +++ b/interface-definitions/include/haproxy/logging.xml.i @@ -4,7 +4,137 @@ Logging parameters - #include + + + Facility for logging + + auth cron daemon kern lpr mail news syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 + + + (auth|cron|daemon|kern|lpr|mail|news|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7) + + Invalid facility type + + auth + Authentication and authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + news + USENET subsystem + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + Logging level + + emerg alert crit err warning notice info debug + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + (emerg|alert|crit|err|warning|notice|info|debug) + + Invalid loglevel + + err + + + diff --git a/interface-definitions/include/version/reverseproxy-version.xml.i b/interface-definitions/include/version/reverseproxy-version.xml.i index 4f09f2848..71f7def1a 100644 --- a/interface-definitions/include/version/reverseproxy-version.xml.i +++ b/interface-definitions/include/version/reverseproxy-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/smoketest/config-tests/basic-haproxy b/smoketest/config-tests/basic-haproxy new file mode 100644 index 000000000..7755fc4ea --- /dev/null +++ b/smoketest/config-tests/basic-haproxy @@ -0,0 +1,46 @@ +set interfaces dummy dum0 address '172.18.254.203/32' +set interfaces ethernet eth0 duplex 'auto' +set interfaces ethernet eth0 speed 'auto' +set interfaces ethernet eth0 vif 203 address '172.18.203.10/24' +set interfaces ethernet eth1 duplex 'auto' +set interfaces ethernet eth1 speed 'auto' +set interfaces ethernet eth2 duplex 'auto' +set interfaces ethernet eth2 speed 'auto' +set load-balancing haproxy backend webserver logging facility daemon +set load-balancing haproxy backend webserver logging facility user level 'info' +set load-balancing haproxy backend webserver server web01 address '192.0.2.1' +set load-balancing haproxy backend webserver server web01 port '443' +set load-balancing haproxy backend webserver ssl no-verify +set load-balancing haproxy global-parameters logging facility daemon +set load-balancing haproxy global-parameters logging facility user level 'info' +set load-balancing haproxy service frontend backend 'webserver' +set load-balancing haproxy service frontend logging facility daemon +set load-balancing haproxy service frontend logging facility user level 'info' +set load-balancing haproxy service frontend port '443' +set load-balancing haproxy service frontend ssl certificate 'dummy' +set pki certificate dummy certificate 'MIIDsTCCApmgAwIBAgIUegVgO1wIN2v44trXZ+Kb1t48uL0wDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yNTA1MDUxODIzMTdaFw0yNjA1MDUxODIzMTdaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBSr4OYIWkb8UGuQnEFnjSbmvR+4vDAfBgNVHSMEGDAWgBSr4OYIWkb8UGuQnEFnjSbmvR+4vDANBgkqhkiG9w0BAQsFAAOCAQEAUmRWRPGXsvfuRT+53id3EufH1IJAdowrt6yBZsHobvqCXO2+YhG7oG6/UqUYiv5bHN5xEMQyWd7nyrLOUeFo2bpcMIOlpl6AoUIY65Gm2BqQ7FuPxLLO25RdpZ5WkMGX5kJsKY0/PcpamRKNz1khgFcRyxf9WGhCAIjDCWIWs8lkvPN3m75SFCW7MTuzzQOrzvI6nqqcHO4k8hRBznp26WLUW1rQKpNN09nZGOkeNYK5QbzKN/RUmtEHQZhlgLAIr09jUaA4RDLI1SdD6LR5nvpa9RJBTyS/kISF8BXKMgvUbDHN2nP+VUUrut2ZwoU+pxV4RVT2pS760HuYj4+sYQ==' +set pki certificate dummy private key 'MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAECgf9plqCMg2pKEWRFl183bqWAm7lnLnsUOfABFNPYa3U+uKQUKZpboTBfzDfZqNak3XNQV0mTAR8pFfoMhQjQU9hUxH7ivjw1RUCHjixCF0vLBkTB34gL7FUbiEIFhR1NW3pCJY73OXOkIZG1Obh6Syb8KubDeu4bTmb90/TnDDAs6OYXJ5yo7ZDZLvLu5a3Dli+H4K5Qb5VJ74o/vtodBo3wmKBgy2Ey6JqF+y7/3HeE66rVhYNft5pURgemWnNYqh3oDTJASqpA/8n90o8ceYPVJugQ7029UiyTp0xgBRXFszgiYPkBlsNWB+9+ospopOmYU0owBykH+RtD/bQ0mwECgYEA4gxPdYbHg/GLihHrkv0t5V0pSEhBeBeTBdWG+P/6K90vXofpp7qISdOeYMGkh8mY+PfZNHksdu67d2ks5on5/dNf5YXWCm+LMMRiSsfOo11NISNdNHS6afqs18Wq1aKawv/rwotfxrakM4Gar692+jgz/l/X+FdOQwmE6uEus8ECgYEA3oW4eGtzGq28TiqyhTHduTkas0ckPWX8ulasyPnLxBKDNNohbXXpFIJIcrnl24QFJw3MJbo+R+OxZHgzPK8r64gIGVa7vLCR2fiU/RFoUa1Jo1pPOqXXWqf/Mvdokm2p0atrjRUX9VhjoFsDLcqTgAmfSCsVSqGucX6ER7Gy60UCgYAvmhoNjNFtFquk6rsqHAjTOTgdUaH/0S8T1nBy9SzQmeaEyKhKuvxCV78NbxnfwnNlUoQ6CZ50eTefINXkwn+TlTSnl/SIBA9SuLheOQ9p1ZcNeG4DQuWStcg6NBUSoghnMg+Ky2Di7slLU2qovpGWhcllMve/A1umwFVuRPdZwQKBgHS7mYYyd/Oq6HnpFDWjbzlXp5Yc3/oFooruJT5ZLHfzbjkvpRGTJW7I2dC1jMuXekx+hHXWOg3keI7IL7jJ/DRW7Ei+o0XdKuY57Y7ErwEJ8vNq0N1nWo4IS2wlNgp61PdVAdrFEgh3EexxUj2XY8FrSs/FKio4nxaS1Dn4EnAxAoGBAKqLvuPpmCMVwlIu57WGxL5d9i7EjIGY65l6HTKQYoHCzE51rkowH1La2fuUYz0IpExq2lcrLbOUtSyhXH7Zlktiz//Gu/P90SUfR/ZGcLeZi+EDyK2OctpnWBjs2Dmfg4D6vxk39yV8AB97pYG073GcJ/P54qRUuEitbpJwH+fB' +set service ntp allow-client address '0.0.0.0/0' +set service ntp allow-client address '::/0' +set service ntp server 172.16.100.10 +set service ntp server 172.16.100.20 +set service ntp server 172.16.110.30 +set service ssh disable-host-validation +set service ssh port '22' +set system config-management commit-revisions '200' +set system conntrack modules ftp +set system conntrack modules h323 +set system conntrack modules nfs +set system conntrack modules pptp +set system conntrack modules sip +set system conntrack modules sqlnet +set system conntrack modules tftp +set system console device ttyS0 speed '115200' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0' +set system login user vyos authentication plaintext-password '' +set system name-server '172.16.254.30' +set system option kernel disable-mitigations +set system syslog local facility all level 'info' +set system syslog local facility local7 level 'debug' +set system time-zone 'Europe/Berlin' diff --git a/smoketest/configs/basic-haproxy b/smoketest/configs/basic-haproxy new file mode 100644 index 000000000..83fffbac6 --- /dev/null +++ b/smoketest/configs/basic-haproxy @@ -0,0 +1,153 @@ +interfaces { + dummy dum0 { + address "172.18.254.203/32" + } + ethernet eth0 { + duplex "auto" + speed "auto" + vif 203 { + address "172.18.203.10/24" + } + } + ethernet eth1 { + duplex "auto" + speed "auto" + } + ethernet eth2 { + duplex "auto" + speed "auto" + } +} +load-balancing { + reverse-proxy { + backend webserver { + logging { + facility all { + level "all" + } + facility daemon { + level "all" + } + facility user { + level "info" + } + } + server web01 { + address "192.0.2.1" + port "443" + } + ssl { + no-verify + } + } + global-parameters { + logging { + facility all { + level "all" + } + facility daemon { + level "all" + } + facility user { + level "info" + } + } + } + service frontend { + backend "webserver" + logging { + facility all { + level "all" + } + facility daemon { + level "all" + } + facility user { + level "info" + } + } + port "443" + ssl { + certificate "dummy" + } + } + } +} +pki { + certificate dummy { + certificate "MIIDsTCCApmgAwIBAgIUegVgO1wIN2v44trXZ+Kb1t48uL0wDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yNTA1MDUxODIzMTdaFw0yNjA1MDUxODIzMTdaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBSr4OYIWkb8UGuQnEFnjSbmvR+4vDAfBgNVHSMEGDAWgBSr4OYIWkb8UGuQnEFnjSbmvR+4vDANBgkqhkiG9w0BAQsFAAOCAQEAUmRWRPGXsvfuRT+53id3EufH1IJAdowrt6yBZsHobvqCXO2+YhG7oG6/UqUYiv5bHN5xEMQyWd7nyrLOUeFo2bpcMIOlpl6AoUIY65Gm2BqQ7FuPxLLO25RdpZ5WkMGX5kJsKY0/PcpamRKNz1khgFcRyxf9WGhCAIjDCWIWs8lkvPN3m75SFCW7MTuzzQOrzvI6nqqcHO4k8hRBznp26WLUW1rQKpNN09nZGOkeNYK5QbzKN/RUmtEHQZhlgLAIr09jUaA4RDLI1SdD6LR5nvpa9RJBTyS/kISF8BXKMgvUbDHN2nP+VUUrut2ZwoU+pxV4RVT2pS760HuYj4+sYQ==" + private { + key "MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAECgf9plqCMg2pKEWRFl183bqWAm7lnLnsUOfABFNPYa3U+uKQUKZpboTBfzDfZqNak3XNQV0mTAR8pFfoMhQjQU9hUxH7ivjw1RUCHjixCF0vLBkTB34gL7FUbiEIFhR1NW3pCJY73OXOkIZG1Obh6Syb8KubDeu4bTmb90/TnDDAs6OYXJ5yo7ZDZLvLu5a3Dli+H4K5Qb5VJ74o/vtodBo3wmKBgy2Ey6JqF+y7/3HeE66rVhYNft5pURgemWnNYqh3oDTJASqpA/8n90o8ceYPVJugQ7029UiyTp0xgBRXFszgiYPkBlsNWB+9+ospopOmYU0owBykH+RtD/bQ0mwECgYEA4gxPdYbHg/GLihHrkv0t5V0pSEhBeBeTBdWG+P/6K90vXofpp7qISdOeYMGkh8mY+PfZNHksdu67d2ks5on5/dNf5YXWCm+LMMRiSsfOo11NISNdNHS6afqs18Wq1aKawv/rwotfxrakM4Gar692+jgz/l/X+FdOQwmE6uEus8ECgYEA3oW4eGtzGq28TiqyhTHduTkas0ckPWX8ulasyPnLxBKDNNohbXXpFIJIcrnl24QFJw3MJbo+R+OxZHgzPK8r64gIGVa7vLCR2fiU/RFoUa1Jo1pPOqXXWqf/Mvdokm2p0atrjRUX9VhjoFsDLcqTgAmfSCsVSqGucX6ER7Gy60UCgYAvmhoNjNFtFquk6rsqHAjTOTgdUaH/0S8T1nBy9SzQmeaEyKhKuvxCV78NbxnfwnNlUoQ6CZ50eTefINXkwn+TlTSnl/SIBA9SuLheOQ9p1ZcNeG4DQuWStcg6NBUSoghnMg+Ky2Di7slLU2qovpGWhcllMve/A1umwFVuRPdZwQKBgHS7mYYyd/Oq6HnpFDWjbzlXp5Yc3/oFooruJT5ZLHfzbjkvpRGTJW7I2dC1jMuXekx+hHXWOg3keI7IL7jJ/DRW7Ei+o0XdKuY57Y7ErwEJ8vNq0N1nWo4IS2wlNgp61PdVAdrFEgh3EexxUj2XY8FrSs/FKio4nxaS1Dn4EnAxAoGBAKqLvuPpmCMVwlIu57WGxL5d9i7EjIGY65l6HTKQYoHCzE51rkowH1La2fuUYz0IpExq2lcrLbOUtSyhXH7Zlktiz//Gu/P90SUfR/ZGcLeZi+EDyK2OctpnWBjs2Dmfg4D6vxk39yV8AB97pYG073GcJ/P54qRUuEitbpJwH+fB" + } + } +} +service { + ntp { + allow-client { + address "0.0.0.0/0" + address "::/0" + } + server 172.16.100.10 { + } + server 172.16.100.20 { + } + server 172.16.110.30 { + } + } + ssh { + disable-host-validation + port "22" + } +} +system { + config-management { + commit-revisions "200" + } + console { + device ttyS0 { + speed 115200 + } + } + conntrack { + modules { + ftp + h323 + nfs + pptp + sip + sqlnet + tftp + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } + name-server "172.16.254.30" + option { + kernel { + disable-mitigations + } + } + syslog { + global { + facility all { + level "info" + } + facility local7 { + level "debug" + } + } + } + time-zone "Europe/Berlin" +} + + +// Warning: Do not remove the following line. +// vyos-config-version: "bgp@5:broadcast-relay@1:cluster@2:config-management@1:conntrack@5:conntrack-sync@2:container@2:dhcp-relay@2:dhcp-server@8:dhcpv6-server@1:dns-dynamic@4:dns-forwarding@4:firewall@15:flow-accounting@1:https@6:ids@1:interfaces@32:ipoe-server@3:ipsec@13:isis@3:l2tp@9:lldp@2:mdns@1:monitoring@1:nat@8:nat66@3:ntp@3:openconnect@3:ospf@2:pim@1:policy@8:pppoe-server@10:pptp@5:qos@2:quagga@11:reverse-proxy@1:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@27:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2" +// Release version: 1.4.1 diff --git a/src/migration-scripts/reverse-proxy/2-to-3 b/src/migration-scripts/reverse-proxy/2-to-3 new file mode 100755 index 000000000..ac539618e --- /dev/null +++ b/src/migration-scripts/reverse-proxy/2-to-3 @@ -0,0 +1,66 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7429: logging facility "all" unavailable in code + +from vyos.configtree import ConfigTree + +base = ['load-balancing', 'haproxy'] +unsupported_facilities = ['all', 'authpriv', 'mark'] + +def config_migrator(config, config_path: list) -> None: + if not config.exists(config_path): + return + # Remove unsupported backend HAProxy syslog facilities form CLI + # Works for both backend and service CLI nodes + for service_backend in config.list_nodes(config_path): + log_path = config_path + [service_backend, 'logging', 'facility'] + if not config.exists(log_path): + continue + # Remove unsupported syslog facilities form CLI + for facility in config.list_nodes(log_path): + if facility in unsupported_facilities: + config.delete(log_path + [facility]) + continue + # Remove unsupported facility log level form CLI. VyOS will fallback + # to default log level if not set + if config.exists(log_path + [facility, 'level']): + tmp = config.return_value(log_path + [facility, 'level']) + if tmp == 'all': + config.delete(log_path + [facility, 'level']) + +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + # Nothing to do + return + + # Remove unsupported syslog facilities form CLI + global_path = base + ['global-parameters', 'logging', 'facility'] + if config.exists(global_path): + for facility in config.list_nodes(global_path): + if facility in unsupported_facilities: + config.delete(global_path + [facility]) + continue + # Remove unsupported facility log level form CLI. VyOS will fallback + # to default log level if not set + if config.exists(global_path + [facility, 'level']): + tmp = config.return_value(global_path + [facility, 'level']) + if tmp == 'all': + config.delete(global_path + [facility, 'level']) + + # Remove unsupported backend HAProxy syslog facilities from CLI + config_migrator(config, base + ['backend']) + # Remove unsupported service HAProxy syslog facilities from CLI + config_migrator(config, base + ['service']) -- cgit v1.2.3 From 08421b277b1f460ebc51673571bab975aece2215 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 7 Jun 2025 09:15:30 +0200 Subject: conntrack: T7208: nf_conntrack_buckets defaults and behavior Previously, we used a lower limit of 1 and a default value of 32768 for the nf_conntrack_buckets (conntrack hash-size) sysctl option. However, the Linux kernel enforces an internal minimum of 1024. A configuration migrator will now adjust the lower limit to 1024 if necessary. The former default value of 32768 was passed as a kernel module option, which only took effect after the second system reboot. This was due to the option being rendered but not applied during the first boot. This behavior has been changed so that the value is now configurable at runtime and takes effect immediately. Additionally, since VyOS 1.4 increased the hardware requirements to 4GB of RAM, we now align the default value of nf_conntrack_buckets with the kernel's default for systems with more than 1GB of RAM to 65536 entries. Previously, we only supported half that amount. --- data/templates/conntrack/sysctl.conf.j2 | 3 +- data/templates/conntrack/vyos_nf_conntrack.conf.j2 | 2 - .../include/version/conntrack-version.xml.i | 2 +- interface-definitions/system_conntrack.xml.in | 6 +- smoketest/config-tests/conntrack-basic | 35 ++++++++ smoketest/configs/conntrack-basic | 92 ++++++++++++++++++++++ smoketest/scripts/cli/test_system_conntrack.py | 13 +-- src/conf_mode/system_conntrack.py | 2 - src/migration-scripts/conntrack/5-to-6 | 30 +++++++ 9 files changed, 171 insertions(+), 14 deletions(-) delete mode 100644 data/templates/conntrack/vyos_nf_conntrack.conf.j2 create mode 100644 smoketest/config-tests/conntrack-basic create mode 100644 smoketest/configs/conntrack-basic create mode 100644 src/migration-scripts/conntrack/5-to-6 (limited to 'interface-definitions/include/version') diff --git a/data/templates/conntrack/sysctl.conf.j2 b/data/templates/conntrack/sysctl.conf.j2 index cd6c34ede..8d934db9c 100644 --- a/data/templates/conntrack/sysctl.conf.j2 +++ b/data/templates/conntrack/sysctl.conf.j2 @@ -1,10 +1,11 @@ # Autogenerated by system_conntrack.py {# all values have defaults - thus no checking required #} +net.netfilter.nf_conntrack_buckets = {{ hash_size }} net.netfilter.nf_conntrack_expect_max = {{ expect_table_size }} net.netfilter.nf_conntrack_max = {{ table_size }} net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }} net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }} net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }} net.netfilter.nf_conntrack_acct = {{ '1' if flow_accounting is vyos_defined else '0' }} -net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }} \ No newline at end of file +net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }} diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.j2 b/data/templates/conntrack/vyos_nf_conntrack.conf.j2 deleted file mode 100644 index 1b12fec5f..000000000 --- a/data/templates/conntrack/vyos_nf_conntrack.conf.j2 +++ /dev/null @@ -1,2 +0,0 @@ -# Autogenerated by system_conntrack.py -options nf_conntrack hashsize={{ hash_size }} diff --git a/interface-definitions/include/version/conntrack-version.xml.i b/interface-definitions/include/version/conntrack-version.xml.i index 6995ce119..517424034 100644 --- a/interface-definitions/include/version/conntrack-version.xml.i +++ b/interface-definitions/include/version/conntrack-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/system_conntrack.xml.in b/interface-definitions/system_conntrack.xml.in index 54610b625..92c4d24cf 100644 --- a/interface-definitions/system_conntrack.xml.in +++ b/interface-definitions/system_conntrack.xml.in @@ -32,14 +32,14 @@ Hash size for connection tracking table - u32:1-50000000 + u32:1024-50000000 Size of hash to use for connection tracking table - + - 32768 + 65536 diff --git a/smoketest/config-tests/conntrack-basic b/smoketest/config-tests/conntrack-basic new file mode 100644 index 000000000..8c375d244 --- /dev/null +++ b/smoketest/config-tests/conntrack-basic @@ -0,0 +1,35 @@ +set firewall global-options timeout icmp '30' +set firewall global-options timeout other '600' +set firewall global-options timeout udp other '300' +set firewall global-options timeout udp stream '300' +set interfaces ethernet eth0 vif 5 address '192.0.2.1/24' +set interfaces ethernet eth1 vif 7 description 'FTTH-PPPoE' +set nat source rule 100 log +set nat source rule 100 outbound-interface name 'pppoe0' +set nat source rule 100 source address '192.0.2.0/24' +set nat source rule 100 translation address 'masquerade' +set service ntp allow-client address '172.16.0.0/12' +set service ntp server 0.pool.ntp.org +set service ntp server 1.pool.ntp.org +set service ntp server 2.pool.ntp.org +set system config-management commit-revisions '200' +set system conntrack expect-table-size '2048' +set system conntrack hash-size '1024' +set system conntrack modules ftp +set system conntrack modules h323 +set system conntrack modules nfs +set system conntrack modules pptp +set system conntrack modules sip +set system conntrack modules sqlnet +set system conntrack modules tftp +set system conntrack table-size '262144' +set system conntrack timeout +set system console device ttyS0 speed '115200' +set system domain-name 'vyos.net' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/' +set system login user vyos authentication plaintext-password '' +set system name-server '172.16.254.30' +set system syslog local facility all level 'debug' +set system syslog local facility local7 level 'debug' +set system syslog remote 172.16.100.1 facility all level 'warning' diff --git a/smoketest/configs/conntrack-basic b/smoketest/configs/conntrack-basic new file mode 100644 index 000000000..8ecb78aeb --- /dev/null +++ b/smoketest/configs/conntrack-basic @@ -0,0 +1,92 @@ +interfaces { + ethernet eth0 { + duplex auto + speed auto + vif 5 { + address 192.0.2.1/24 + } + } + ethernet eth1 { + vif 7 { + description FTTH-PPPoE + } + } +} +nat { + source { + rule 100 { + log + outbound-interface pppoe0 + source { + address 192.0.2.0/24 + } + translation { + address masquerade + } + } + } +} +system { + config-management { + commit-revisions 200 + } + conntrack { + expect-table-size 2048 + hash-size 1023 + table-size 262144 + timeout { + icmp 30 + other 600 + udp { + other 300 + stream 300 + } + } + } + console { + device ttyS0 { + speed 115200 + } + } + domain-name vyos.net + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + } + } + name-server 172.16.254.30 + ntp { + allow-clients { + address 172.16.0.0/12 + } + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level debug + } + facility protocols { + level debug + } + } + host 172.16.100.1 { + facility all { + level warning + } + } + } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@6:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3-beta-202101091250 diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py index f6bb3cf7c..27ca28298 100755 --- a/smoketest/scripts/cli/test_system_conntrack.py +++ b/smoketest/scripts/cli/test_system_conntrack.py @@ -20,7 +20,10 @@ import unittest from base_vyostest_shim import VyOSUnitTestSHIM from vyos.firewall import find_nftables_rule -from vyos.utils.file import read_file, read_json +from vyos.utils.file import read_file +from vyos.utils.file import read_json +from vyos.utils.system import sysctl_read +from vyos.xml_ref import default_value base_path = ['system', 'conntrack'] @@ -168,8 +171,8 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): self.assertTrue(find_nftables_rule('ip vyos_conntrack', 'VYOS_CT_HELPER', [rule]) == None) def test_conntrack_hash_size(self): - hash_size = '65536' - hash_size_default = '32768' + hash_size = '8192' + hash_size_default = default_value(base_path + ['hash-size']) self.cli_set(base_path + ['hash-size', hash_size]) @@ -178,7 +181,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): # verify new configuration - only effective after reboot, but # a valid config file is sufficient - tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf') + tmp = sysctl_read('net.netfilter.nf_conntrack_buckets') self.assertIn(hash_size, tmp) # Test default value by deleting the configuration @@ -189,7 +192,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): # verify new configuration - only effective after reboot, but # a valid config file is sufficient - tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf') + tmp = sysctl_read('net.netfilter.nf_conntrack_buckets') self.assertIn(hash_size_default, tmp) def test_conntrack_ignore(self): diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py index f25ed8d10..8909d9cba 100755 --- a/src/conf_mode/system_conntrack.py +++ b/src/conf_mode/system_conntrack.py @@ -32,7 +32,6 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -conntrack_config = r'/etc/modprobe.d/vyatta_nf_conntrack.conf' sysctl_file = r'/run/sysctl/10-vyos-conntrack.conf' nftables_ct_file = r'/run/nftables-ct.conf' vyos_conntrack_logger_config = r'/run/vyos-conntrack-logger.conf' @@ -204,7 +203,6 @@ def generate(conntrack): elif path[0] == 'ipv6': conntrack['ipv6_firewall_action'] = 'accept' - render(conntrack_config, 'conntrack/vyos_nf_conntrack.conf.j2', conntrack) render(sysctl_file, 'conntrack/sysctl.conf.j2', conntrack) render(nftables_ct_file, 'conntrack/nftables-ct.j2', conntrack) diff --git a/src/migration-scripts/conntrack/5-to-6 b/src/migration-scripts/conntrack/5-to-6 new file mode 100644 index 000000000..1db2e78b4 --- /dev/null +++ b/src/migration-scripts/conntrack/5-to-6 @@ -0,0 +1,30 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7202: fix lower limit of supported conntrack hash-size to match Kernel +# lower limit. + +from vyos.configtree import ConfigTree + +base = ['system', 'conntrack'] +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + # Nothing to do + return + + if config.exists(base + ['hash-size']): + tmp = config.return_value(base + ['hash-size']) + if int(tmp) < 1024: + config.set(base + ['hash-size'], value=1024) -- cgit v1.2.3 From 5ae3924234f9ffaa2ffda7e9fc52c2b3518a85e2 Mon Sep 17 00:00:00 2001 From: opswill Date: Tue, 17 Jun 2025 23:02:07 +0800 Subject: container: T7473: fix show/monitor container log failed when log-driver is journald --- data/templates/container/containers.conf.j2 | 8 ---- interface-definitions/container.xml.in | 43 ++++++++++++---------- .../include/version/container-version.xml.i | 2 +- op-mode-definitions/container.xml.in | 7 ++-- smoketest/scripts/cli/test_container.py | 10 ++--- src/conf_mode/container.py | 3 +- src/migration-scripts/container/2-to-3 | 31 ++++++++++++++++ src/op_mode/container.py | 42 +++++++++++++++++++++ 8 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 src/migration-scripts/container/2-to-3 (limited to 'interface-definitions/include/version') diff --git a/data/templates/container/containers.conf.j2 b/data/templates/container/containers.conf.j2 index 65436801e..414c3e849 100644 --- a/data/templates/container/containers.conf.j2 +++ b/data/templates/container/containers.conf.j2 @@ -170,14 +170,6 @@ default_sysctls = [ # #label = true -# Logging driver for the container. Available options: k8s-file and journald. -# -{% if log_driver is vyos_defined %} -log_driver = "{{ log_driver }}" -{% else %} -#log_driver = "k8s-file" -{% endif %} - # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If positive, it must be >= 8192 to match or # exceed conmon's read buffer. The file is truncated and re-opened so the diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 434bf7528..f20fd7690 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -532,6 +532,30 @@ + + + Configure container log driver + + k8s-file journald none + + + k8s-file + Logs to plain-text file + + + journald + Logs to systemd's journal + + + none + Disable logging for the container + + + (k8s-file|journald|none) + + + journald + @@ -627,25 +651,6 @@ - - - Configure container log driver - - k8s-file journald - - - k8s-file - Logs to plain-text json file - - - journald - Logs to systemd's journal - - - (k8s-file|journald) - - - diff --git a/interface-definitions/include/version/container-version.xml.i b/interface-definitions/include/version/container-version.xml.i index ed6e942cd..046bacfdc 100644 --- a/interface-definitions/include/version/container-version.xml.i +++ b/interface-definitions/include/version/container-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/op-mode-definitions/container.xml.in b/op-mode-definitions/container.xml.in index df28a792c..70ab4b6e5 100644 --- a/op-mode-definitions/container.xml.in +++ b/op-mode-definitions/container.xml.in @@ -89,7 +89,7 @@ container name - podman logs --follow --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --follow --name "$4" @@ -132,8 +132,7 @@ container name - - podman logs --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --name "$4" @@ -162,7 +161,7 @@ container name - podman logs --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --name "$4" diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py index daad3a909..892d7ae0b 100755 --- a/smoketest/scripts/cli/test_container.py +++ b/smoketest/scripts/cli/test_container.py @@ -95,7 +95,7 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): '4096', ] ) - + self.cli_set(base_path + ['name', cont_name, 'log-driver', 'journald']) # commit changes self.cli_commit() @@ -110,13 +110,9 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): tmp = cmd(f'sudo podman exec -it {cont_name} sysctl kernel.msgmax') self.assertEqual(tmp, 'kernel.msgmax = 4096') - def test_log_driver(self): - self.cli_set(base_path + ['log-driver', 'journald']) - - self.cli_commit() + l = cmd_to_json(f'sudo podman container inspect {cont_name}') + self.assertEqual(l['HostConfig']['LogConfig']['Type'], 'journald') - tmp = cmd('podman info --format "{{ .Host.LogDriver }}"') - self.assertEqual(tmp, 'journald') def test_name_server(self): cont_name = 'dns-test' diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 83e6dee11..a381ace5c 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -310,6 +310,7 @@ def generate_run_arguments(name, container_config): memory = container_config['memory'] shared_memory = container_config['shared_memory'] restart = container_config['restart'] + log_driver = container_config['log_driver'] # Add sysctl options sysctl_opt = '' @@ -408,7 +409,7 @@ def generate_run_arguments(name, container_config): name_server += f'--dns {ns}' container_base_cmd = f'--detach --interactive --tty --replace {capabilities} {privileged} --cpus {cpu_quota} {sysctl_opt} ' \ - f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ + f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} --log-driver={log_driver} ' \ f'--name {name} {hostname} {device} {port} {name_server} {volume} {tmpfs} {env_opt} {label} {uid} {host_pid}' entrypoint = '' diff --git a/src/migration-scripts/container/2-to-3 b/src/migration-scripts/container/2-to-3 new file mode 100644 index 000000000..54c6ec4c8 --- /dev/null +++ b/src/migration-scripts/container/2-to-3 @@ -0,0 +1,31 @@ +# Copyright 2024 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7473: container: allow log-driver to be set per container + +from vyos.configtree import ConfigTree + +def migrate(config: ConfigTree) -> None: + log_base = ['container', 'log-driver'] + container_base = ['container', 'name'] + + if not config.exists(log_base): + return + else: + log_driver = config.return_value(log_base) + for container in config.list_nodes(container_base): + # Set the log-driver for each container + config.set(container_base + [container, 'log-driver'], value=log_driver) + config.delete(log_base) diff --git a/src/op_mode/container.py b/src/op_mode/container.py index 05f65df1f..f93df0fc4 100755 --- a/src/op_mode/container.py +++ b/src/op_mode/container.py @@ -16,6 +16,7 @@ import json import sys +import subprocess from vyos.utils.process import cmd from vyos.utils.process import rc_cmd @@ -109,6 +110,47 @@ def restart(name: str): print(f'Container "{name}" restarted!') return output +def show_log(name: str, follow: bool = False, raw: bool = False): + """ + Show or monitor logs for a specific container. + Use --follow to continuously stream logs. + """ + from vyos.configquery import ConfigTreeQuery + conf = ConfigTreeQuery() + container = conf.get_config_dict(['container', 'name', name], get_first_key=True, with_recursive_defaults=True) + log_type = container.get('log-driver') + if log_type == 'k8s-file': + if follow: + log_command_list = ['sudo', 'podman', 'logs', '--follow', '--names', name] + else: + log_command_list = ['sudo', 'podman', 'logs', '--names', name] + elif log_type == 'journald': + if follow: + log_command_list = ['journalctl', '--follow', '--unit', f'vyos-container-{name}.service'] + else: + log_command_list = ['journalctl', '-e', '--no-pager', '--unit', f'vyos-container-{name}.service'] + elif log_type == 'none': + print(f'Container "{name}" has disabled logs.') + return None + else: + raise vyos.opmode.InternalError(f'Unknown log type "{log_type}" for container "{name}".') + + process = None + try: + process = subprocess.Popen(log_command_list, + stdout=sys.stdout, + stderr=sys.stderr) + process.wait() + except KeyboardInterrupt: + if process: + process.terminate() + process.wait() + return None + except Exception as e: + raise vyos.opmode.InternalError(f"Error starting logging command: {e} ") + return None + + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) -- cgit v1.2.3 From 8dbc3c5e67cc1fd043a78dd3446a1a733ebd814f Mon Sep 17 00:00:00 2001 From: Nataliia Solomko Date: Fri, 13 Jun 2025 12:20:40 +0300 Subject: firewall: T6951: Add a configuration command for ethertypes that bridge firewalls should always accept --- data/templates/firewall/nftables.j2 | 14 ++--- .../include/firewall/global-options.xml.i | 49 ++++++++++++++++-- .../include/version/firewall-version.xml.i | 2 +- python/vyos/template.py | 23 +++++++++ .../config-tests/firewall-bridged-global-options | 21 ++++++++ smoketest/configs/firewall-bridged-global-options | 60 ++++++++++++++++++++++ smoketest/scripts/cli/test_firewall.py | 8 ++- src/migration-scripts/firewall/18-to-19 | 35 +++++++++++++ src/tests/test_template.py | 4 ++ 9 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 smoketest/config-tests/firewall-bridged-global-options create mode 100644 smoketest/configs/firewall-bridged-global-options create mode 100644 src/migration-scripts/firewall/18-to-19 (limited to 'interface-definitions/include/version') diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index bf051bb57..39ef72059 100755 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -410,15 +410,11 @@ table bridge vyos_filter { {% for prior, conf in bridge.output.items() %} chain VYOS_OUTPUT_{{ prior }} { type filter hook output priority {{ prior }}; policy accept; -{% if global_options.apply_to_bridged_traffic is vyos_defined %} -{% if 'invalid_connections' in global_options.apply_to_bridged_traffic %} - ct state invalid udp sport 67 udp dport 68 counter accept - ct state invalid ether type arp counter accept - ct state invalid ether type 8021q counter accept - ct state invalid ether type 8021ad counter accept - ct state invalid ether type 0x8863 counter accept - ct state invalid ether type 0x8864 counter accept - ct state invalid ether type 0x0842 counter accept +{% if global_options.apply_to_bridged_traffic.accept_invalid is vyos_defined %} +{% if 'ethernet_type' in global_options.apply_to_bridged_traffic.accept_invalid %} +{% for ether_type in global_options.apply_to_bridged_traffic.accept_invalid.ethernet_type %} + {{ ether_type | nft_accept_invalid() }} +{% endfor %} {% endif %} {% endif %} {% if global_options.state_policy is vyos_defined %} diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i index 794da4f9d..e19f3a7c5 100644 --- a/interface-definitions/include/firewall/global-options.xml.i +++ b/interface-definitions/include/firewall/global-options.xml.i @@ -49,12 +49,53 @@ Apply configured firewall rules to traffic switched by bridges - + - Accept ARP, 802.1q, 802.1ad, DHCP, PPPoE and WoL despite being marked as invalid connections - + Accept connections despite they are marked as invalid - + + + + Ethernet type + + arp dhcp pppoe 802.1q 802.1ad pppoe-discovery wol + + + arp + Adress Resolution Protocol (ARP) + + + dhcp + Dynamic Host Configuration Protocol (DHCP) + + + pppoe + Point to Point over Ethernet (PPPoE) Session + + + pppoe-discovery + PPPoE Discovery + + + 802.1q + Customer VLAN tag type (802.1Q) + + + 802.1ad + Service VLAN tag type (802.1ad) + + + wol + Wake-on-LAN magic packet + + + (arp|dhcp|pppoe|pppoe-discovery|802.1q|802.1ad|wol) + + + + + + Apply configured IPv4 firewall rules diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i index 1a8098297..1f3b779d5 100644 --- a/interface-definitions/include/version/firewall-version.xml.i +++ b/interface-definitions/include/version/firewall-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/python/vyos/template.py b/python/vyos/template.py index bf7928914..bf2f13183 100755 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -674,6 +674,29 @@ def nft_nested_group(out_list, includes, groups, key): add_includes(name) return out_list +@register_filter('nft_accept_invalid') +def nft_accept_invalid(ether_type): + ether_type_mapping = { + 'dhcp': 'udp sport 67 udp dport 68', + 'arp': 'arp', + 'pppoe-discovery': '0x8863', + 'pppoe': '0x8864', + '802.1q': '8021q', + '802.1ad': '8021ad', + 'wol': '0x0842', + } + if ether_type not in ether_type_mapping: + raise RuntimeError(f'Ethernet type "{ether_type}" not found in ' \ + 'available ethernet types!') + out = 'ct state invalid ' + + if ether_type != 'dhcp': + out += 'ether type ' + + out += f'{ether_type_mapping[ether_type]} counter accept' + + return out + @register_filter('nat_rule') def nat_rule(rule_conf, rule_id, nat_type, ipv6=False): from vyos.nat import parse_nat_rule diff --git a/smoketest/config-tests/firewall-bridged-global-options b/smoketest/config-tests/firewall-bridged-global-options new file mode 100644 index 000000000..1d960d6c1 --- /dev/null +++ b/smoketest/config-tests/firewall-bridged-global-options @@ -0,0 +1,21 @@ +set firewall bridge prerouting filter rule 10 action 'accept' +set firewall bridge prerouting filter rule 10 ethernet-type 'arp' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'dhcp' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'arp' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'pppoe-discovery' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'pppoe' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type '802.1q' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type '802.1ad' +set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'wol' +set firewall global-options state-policy established action 'accept' +set firewall global-options state-policy invalid action 'drop' +set firewall global-options state-policy related action 'accept' +set interfaces ethernet eth0 duplex 'auto' +set interfaces ethernet eth0 speed 'auto' +set interfaces ethernet eth1 duplex 'auto' +set interfaces ethernet eth1 speed 'auto' +set system console device ttyS0 speed '115200' +set system domain-name 'vyos-ci-test.net' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0' +set system login user vyos authentication plaintext-password '' diff --git a/smoketest/configs/firewall-bridged-global-options b/smoketest/configs/firewall-bridged-global-options new file mode 100644 index 000000000..a7e1428d8 --- /dev/null +++ b/smoketest/configs/firewall-bridged-global-options @@ -0,0 +1,60 @@ +firewall { + bridge { + prerouting { + filter { + rule 10 { + action "accept" + ethernet-type "arp" + } + } + } + } + global-options { + apply-to-bridged-traffic { + invalid-connections { + } + } + state-policy { + established { + action "accept" + } + invalid { + action "drop" + } + related { + action "accept" + } + } + } +} +interfaces { + ethernet eth0 { + duplex "auto" + speed "auto" + } + ethernet eth1 { + duplex auto + speed auto + } +} +system { + console { + device ttyS0 { + speed 115200 + } + } + domain-name vyos-ci-test.net + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "bgp@6:broadcast-relay@1:cluster@2:config-management@1:conntrack@6:conntrack-sync@2:container@2:dhcp-relay@2:dhcp-server@11:dhcpv6-server@6:dns-dynamic@4:dns-forwarding@4:firewall@18:flow-accounting@2:https@7:ids@2:interfaces@33:ipoe-server@4:ipsec@13:isis@3:l2tp@9:lldp@3:mdns@1:monitoring@2:nat@8:nat66@3:nhrp@1:ntp@3:openconnect@3:openvpn@4:ospf@2:pim@1:policy@9:pppoe-server@11:pptp@5:qos@3:quagga@12:reverse-proxy@3:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@29:vpp@1:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@4:webproxy@2" +// Release version: 2025.06.17-0020-rolling diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 2d850dfdf..455c704d0 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -728,7 +728,13 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'ipv6-address-group', 'AGV6', 'address', '2001:db1::1']) self.cli_set(['firewall', 'global-options', 'state-policy', 'established', 'action', 'accept']) self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'ipv4']) - self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'invalid-connections']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'dhcp']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'arp']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'pppoe']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'pppoe-discovery']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', '802.1q']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', '802.1ad']) + self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'wol']) self.cli_set(['firewall', 'bridge', 'name', name, 'default-action', 'accept']) self.cli_set(['firewall', 'bridge', 'name', name, 'default-log']) diff --git a/src/migration-scripts/firewall/18-to-19 b/src/migration-scripts/firewall/18-to-19 new file mode 100644 index 000000000..3564e0e01 --- /dev/null +++ b/src/migration-scripts/firewall/18-to-19 @@ -0,0 +1,35 @@ +# Copyright (C) 2024-2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# From +# set firewall global-options apply-to-bridged-traffic invalid-connections +# To +# set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type + +from vyos.configtree import ConfigTree + +base = ['firewall', 'global-options', 'apply-to-bridged-traffic'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base + ['invalid-connections']): + # Nothing to do + return + + ether_types = ['dhcp', 'arp', 'pppoe-discovery', 'pppoe', '802.1q', '802.1ad', 'wol'] + + for ether_type in ether_types: + config.set(base + ['accept-invalid', 'ethernet-type'], value=ether_type, replace=False) + + config.delete(base + ['invalid-connections']) diff --git a/src/tests/test_template.py b/src/tests/test_template.py index 4660c0038..09315d398 100644 --- a/src/tests/test_template.py +++ b/src/tests/test_template.py @@ -199,8 +199,12 @@ class TestVyOSTemplate(TestCase): vyos.template.get_default_config_file('UNKNOWN') with self.assertRaises(RuntimeError): vyos.template.get_default_port('UNKNOWN') + with self.assertRaises(RuntimeError): + vyos.template.nft_accept_invalid('UNKNOWN') self.assertEqual(vyos.template.get_default_config_file('sshd_user_ca'), config_files['sshd_user_ca']) self.assertEqual(vyos.template.get_default_port('certbot_haproxy'), internal_ports['certbot_haproxy']) + self.assertEqual(vyos.template.nft_accept_invalid('arp'), + 'ct state invalid ether type arp counter accept') -- cgit v1.2.3