diff options
-rw-r--r-- | data/configd-include.json | 1 | ||||
-rw-r--r-- | data/templates/firewall/upnpd.conf.j2 | 227 | ||||
-rw-r--r-- | debian/control | 3 | ||||
-rw-r--r-- | interface-definitions/service_upnp.xml.in | 229 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_ospf.py | 3 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_upnp.py | 103 | ||||
-rwxr-xr-x | src/conf_mode/service_upnp.py | 157 | ||||
-rwxr-xr-x | src/op_mode/version.py | 6 | ||||
-rw-r--r-- | src/systemd/miniupnpd.service | 13 |
9 files changed, 8 insertions, 734 deletions
diff --git a/data/configd-include.json b/data/configd-include.json index 0c767f987..dcee50306 100644 --- a/data/configd-include.json +++ b/data/configd-include.json @@ -81,7 +81,6 @@ "service_sla.py", "service_ssh.py", "service_tftp-server.py", -"service_upnp.py", "service_webproxy.py", "system_acceleration.py", "system_config-management.py", diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2 deleted file mode 100644 index 616e8869f..000000000 --- a/data/templates/firewall/upnpd.conf.j2 +++ /dev/null @@ -1,227 +0,0 @@ -# This is the UPNP configuration file - -# WAN network interface -ext_ifname={{ wan_interface }} -{% if wan_ip is vyos_defined %} - -# if the WAN network interface for IPv6 is different than for IPv4, -# set ext_ifname6 -#ext_ifname6=eth2 - -# If the WAN interface has several IP addresses, you -# can specify the one to use below. -# Setting ext_ip is also useful in double NAT setup, you can declare here -# the public IP address. -{% for addr in wan_ip %} -ext_ip={{ addr }} -{% endfor %} -{% endif %} - -{% if stun is vyos_defined %} -# WAN interface must have public IP address. Otherwise it is behind NAT -# and port forwarding is impossible. In some cases WAN interface can be -# behind unrestricted full-cone NAT 1:1 when all incoming traffic is NAT-ed and -# routed to WAN interfaces without any filtering. In this cases miniupnpd -# needs to know public IP address and it can be learnt by asking external -# server via STUN protocol. Following option enable retrieving external -# public IP address from STUN server and detection of NAT type. You need -# to specify also external STUN server in stun_host option below. -# This option is disabled by default. -ext_perform_stun=yes -# Specify STUN server, either hostname or IP address -# Some public STUN servers: -# stun.stunprotocol.org -# stun.sipgate.net -# stun.xten.com -# stun.l.google.com (on non standard port 19302) -ext_stun_host={{ stun.host }} -# Specify STUN UDP port, by default it is standard port 3478. -ext_stun_port={{ stun.port }} -{% endif %} - -# LAN network interfaces IPs / networks -{% if listen is vyos_defined %} -# There can be multiple listening IPs for SSDP traffic, in that case -# use multiple 'listening_ip=...' lines, one for each network interface. -# It can be IP address or network interface name (ie. "eth0") -# It is mandatory to use the network interface name in order to enable IPv6 -# HTTP is available on all interfaces. -# When MULTIPLE_EXTERNAL_IP is enabled, the external IP -# address associated with the subnet follows. For example: -# listening_ip=192.168.0.1/24 88.22.44.13 -# When MULTIPLE_EXTERNAL_IP is disabled, you can list associated network -# interfaces (for bridges) -# listening_ip=bridge0 em0 wlan0 -{% for addr in listen %} -{% if addr | is_ipv4 %} -listening_ip={{ addr }} -{% elif addr | is_ipv6 %} -ipv6_listening_ip={{ addr }} -{% else %} -listening_ip={{ addr }} -{% endif %} -{% endfor %} -{% endif %} - -# CAUTION: mixing up WAN and LAN interfaces may introduce security risks! -# Be sure to assign the correct interfaces to LAN and WAN and consider -# implementing UPnP permission rules at the bottom of this configuration file - -# Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect. -#http_port=0 -# Port for HTTPS. Set to 0 for autoselect (default) -#https_port=0 - -# Path to the UNIX socket used to communicate with MiniSSDPd -# If running, MiniSSDPd will manage M-SEARCH answering. -# default is /var/run/minissdpd.sock -#minissdpdsocket=/var/run/minissdpd.sock - -{% if nat_pmp is vyos_defined %} -# Enable NAT-PMP support (default is no) -enable_natpmp=yes -{% endif %} - -# Enable UPNP support (default is yes) -enable_upnp=yes - -{% if pcp_lifetime is vyos_defined %} -# PCP -# Configure the minimum and maximum lifetime of a port mapping in seconds -# 120s and 86400s (24h) are suggested values from PCP-base -{% if pcp_lifetime.max is vyos_defined %} -max_lifetime={{ pcp_lifetime.max }} -{% endif %} -{% if pcp_lifetime.min is vyos_defined %} -min_lifetime={{ pcp_lifetime.min }} -{% endif %} -{% endif %} - -# table names for netfilter nft. Default is "filter" for both -#upnp_table_name= -#upnp_nat_table_name= -# chain names for netfilter and netfilter nft -# netfilter : default are MINIUPNPD, MINIUPNPD, MINIUPNPD-POSTROUTING -# netfilter nft : default are miniupnpd, prerouting_miniupnpd, postrouting_miniupnpd -#upnp_forward_chain=forwardUPnP -#upnp_nat_chain=UPnP -#upnp_nat_postrouting_chain=UPnP-Postrouting - -# Lease file location -lease_file=/config/upnp.leases - -# To enable the next few runtime options, see compile time -# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h) - -{% if friendly_name is vyos_defined %} -# Name of this service, default is "`uname -s` router" -friendly_name={{ friendly_name }} -{% endif %} - -# Manufacturer name, default is "`uname -s`" -manufacturer_name=VyOS - -# Manufacturer URL, default is URL of OS vendor -manufacturer_url=https://vyos.io/ - -# Model name, default is "`uname -s` router" -model_name=VyOS Router Model - -# Model description, default is "`uname -s` router" -model_description=Vyos open source enterprise router/firewall operating system - -# Model URL, default is URL of OS vendor -model_url=https://vyos.io/ - -# Bitrates reported by daemon in bits per second -# by default miniupnpd tries to get WAN interface speed -#bitrate_up=1000000 -#bitrate_down=10000000 - -{% if secure_mode is vyos_defined %} -# Secure Mode, UPnP clients can only add mappings to their own IP -secure_mode=yes -{% else %} -# Secure Mode, UPnP clients can only add mappings to their own IP -secure_mode=no -{% endif %} - -{% if presentation_url is vyos_defined %} -# Default presentation URL is HTTP address on port 80 -# If set to an empty string, no presentationURL element will appear -# in the XML description of the device, which prevents MS Windows -# from displaying an icon in the "Network Connections" panel. -#presentation_url= {{ presentation_url }} -{% endif %} - -# Report system uptime instead of daemon uptime -system_uptime=yes - -# Notify interval in seconds. default is 30 seconds. -#notify_interval=240 -notify_interval=60 - -# Unused rules cleaning. -# never remove any rule before this threshold for the number -# of redirections is exceeded. default to 20 -clean_ruleset_threshold=10 -# Clean process work interval in seconds. default to 0 (disabled). -# a 600 seconds (10 minutes) interval makes sense -clean_ruleset_interval=600 - -############################################################################ -## The next 5 config parameters (packet_log, anchor, queue, tag, quickrules) -## are specific to BSD's pf(4) packet filter and hence cannot be enabled in -## VyOS. -# Log packets in pf (default is no) -#packet_log=no - -# Anchor name in pf (default is miniupnpd) -#anchor=miniupnpd - -# ALTQ queue in pf -# Filter rules must be used for this to be used. -# compile with PF_ENABLE_FILTER_RULES (see config.h file) -#queue=queue_name1 - -# Tag name in pf -#tag=tag_name1 - -# Make filter rules in pf quick or not. default is yes -# active when compiled with PF_ENABLE_FILTER_RULES (see config.h file) -#quickrules=no -## -## End of pf(4)-specific configuration not to be set in VyOS. -############################################################################ - -# UUID, generate your own UUID with "make genuuid" -uuid={{ uuid }} - -# Daemon's serial and model number when reporting to clients -# (in XML description) -#serial=12345678 -#model_number=1 - -# If compiled with IGD_V2 defined, force reporting IGDv1 in rootDesc (default -# is no) -#force_igd_desc_v1=no - -{% if rule is vyos_defined %} -# UPnP permission rules (also enforced for NAT-PMP and PCP) -# (allow|deny) (external port range) IP/mask (internal port range) (optional regex filter) -# A port range is <min port>-<max port> or <port> if there is only -# one port in the range. -# IP/mask format must be nnn.nnn.nnn.nnn/nn -# It is advised to only allow redirection of port >= 1024 -# and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535" -# The following default ruleset allows specific LAN side IP addresses -# to request only ephemeral ports. It is recommended that users -# modify the IP ranges to match their own internal networks, and -# also consider implementing network-specific restrictions -# CAUTION: failure to enforce any rules may permit insecure requests to be made! -{% for rule, config in rule.items() %} -{% if config.disable is not vyos_defined %} -{{ config.action }} {{ config.external_port_range }} {{ config.ip }}{{ '/32' if '/' not in config.ip else '' }} {{ config.internal_port_range }} -{% endif %} -{% endfor %} -{% endif %} diff --git a/debian/control b/debian/control index 594e9e8d8..329ed09eb 100644 --- a/debian/control +++ b/debian/control @@ -196,9 +196,6 @@ Depends: snmp, snmpd, # End "service snmp" -# For "service upnp" - miniupnpd-nftables, -# End "service upnp" # For "service webproxy" squid, squidclient, diff --git a/interface-definitions/service_upnp.xml.in b/interface-definitions/service_upnp.xml.in deleted file mode 100644 index 064386ee5..000000000 --- a/interface-definitions/service_upnp.xml.in +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0"?> -<interfaceDefinition> - <node name="service"> - <children> - <node name="upnp" owner="${vyos_conf_scripts_dir}/service_upnp.py"> - <properties> - <help>Universal Plug and Play (UPnP) service</help> - <priority>900</priority> - </properties> - <children> - <leafNode name="friendly-name"> - <properties> - <help>Name of this service</help> - <valueHelp> - <format>txt</format> - <description>Friendly name</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="wan-interface"> - <properties> - <help>WAN network interface</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces</script> - </completionHelp> - <constraint> - #include <include/constraint/interface-name.xml.i> - </constraint> - </properties> - </leafNode> - <leafNode name="wan-ip"> - <properties> - <help>WAN network IP</help> - <valueHelp> - <format>ipv4</format> - <description>IPv4 address</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>IPv6 address</description> - </valueHelp> - <constraint> - <validator name="ipv4-address" /> - <validator name="ipv6-address" /> - </constraint> - <multi/> - </properties> - </leafNode> - <leafNode name="nat-pmp"> - <properties> - <help>Enable NAT-PMP support</help> - <valueless /> - </properties> - </leafNode> - <leafNode name="secure-mode"> - <properties> - <help>Enable Secure Mode</help> - <valueless /> - </properties> - </leafNode> - <leafNode name="presentation-url"> - <properties> - <help>Presentation Url</help> - <valueHelp> - <format>txt</format> - <description>Presentation Url</description> - </valueHelp> - </properties> - </leafNode> - <node name="pcp-lifetime"> - <properties> - <help>PCP-base lifetime Option</help> - </properties> - <children> - <leafNode name="max"> - <properties> - <help>Max lifetime time</help> - <constraint> - <validator name="numeric" /> - </constraint> - </properties> - </leafNode> - <leafNode name="min"> - <properties> - <help>Min lifetime time</help> - <constraint> - <validator name="numeric" /> - </constraint> - </properties> - </leafNode> - </children> - </node> - <leafNode name="listen"> - <properties> - <help>Local IP addresses for service to listen on</help> - <completionHelp> - <script>${vyos_completion_dir}/list_local_ips.sh --both</script> - <script>${vyos_completion_dir}/list_interfaces</script> - </completionHelp> - <valueHelp> - <format><interface></format> - <description>Monitor interface address</description> - </valueHelp> - <valueHelp> - <format>ipv4</format> - <description>IPv4 address to listen for incoming connections</description> - </valueHelp> - <valueHelp> - <format>ipv4net</format> - <description>IPv4 prefix to listen for incoming connections</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>IPv6 address to listen for incoming connections</description> - </valueHelp> - <valueHelp> - <format>ipv6net</format> - <description>IPv6 prefix to listen for incoming connections</description> - </valueHelp> - <multi/> - <constraint> - #include <include/constraint/interface-name.xml.i> - <validator name="ip-address"/> - <validator name="ipv4-prefix"/> - <validator name="ipv6-prefix"/> - </constraint> - </properties> - </leafNode> - <node name="stun"> - <properties> - <help>Enable STUN probe support (can be used with NAT 1:1 support for WAN interfaces)</help> - </properties> - <children> - <leafNode name="host"> - <properties> - <help>The STUN server address</help> - <valueHelp> - <format>txt</format> - <description>The STUN server host address</description> - </valueHelp> - <constraint> - <validator name="fqdn"/> - </constraint> - </properties> - </leafNode> - #include <include/port-number.xml.i> - </children> - </node> - <tagNode name="rule"> - <properties> - <help>UPnP Rule</help> - <valueHelp> - <format>u32:0-65535</format> - <description>Rule number</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-65535"/> - </constraint> - </properties> - <children> - #include <include/generic-disable-node.xml.i> - <leafNode name="external-port-range"> - <properties> - <help>Port range (REQUIRE)</help> - <valueHelp> - <format><port></format> - <description>single port</description> - </valueHelp> - <valueHelp> - <format><portN>-<portM></format> - <description>Port range (use '-' as delimiter)</description> - </valueHelp> - <constraint> - <validator name="port-range"/> - </constraint> - </properties> - </leafNode> - <leafNode name="internal-port-range"> - <properties> - <help>Port range (REQUIRE)</help> - <valueHelp> - <format><port></format> - <description>single port</description> - </valueHelp> - <valueHelp> - <format><portN>-<portM></format> - <description>Port range (use '-' as delimiter)</description> - </valueHelp> - <constraint> - <validator name="port-range"/> - </constraint> - </properties> - </leafNode> - <leafNode name="ip"> - <properties> - <help>The IP to which this rule applies (REQUIRE)</help> - <valueHelp> - <format>ipv4</format> - <description>The IPv4 address to which this rule applies</description> - </valueHelp> - <valueHelp> - <format>ipv4net</format> - <description>The IPv4 to which this rule applies</description> - </valueHelp> - <constraint> - <validator name="ipv4-address"/> - <validator name="ipv4-host"/> - <validator name="ipv4-prefix"/> - </constraint> - </properties> - </leafNode> - <leafNode name="action"> - <properties> - <help>Actions against the rule (REQUIRE)</help> - <completionHelp> - <list>allow deny</list> - </completionHelp> - <constraint> - <regex>(allow|deny)</regex> - </constraint> - </properties> - </leafNode> - </children> - </tagNode> - </children> - </node> - </children> - </node> -</interfaceDefinition> diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py index 1b9cc50fe..585c1dc89 100755 --- a/smoketest/scripts/cli/test_protocols_ospf.py +++ b/smoketest/scripts/cli/test_protocols_ospf.py @@ -16,6 +16,7 @@ import unittest +from time import sleep from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError @@ -480,6 +481,8 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): # Commit main OSPF changes self.cli_commit() + sleep(10) + # Verify main OSPF changes frrconfig = self.getFRRconfig('router ospf', daemon=PROCESS_NAME) self.assertIn(f'router ospf', frrconfig) diff --git a/smoketest/scripts/cli/test_service_upnp.py b/smoketest/scripts/cli/test_service_upnp.py deleted file mode 100755 index fd67b0ced..000000000 --- a/smoketest/scripts/cli/test_service_upnp.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>. - -import unittest - -from base_vyostest_shim import VyOSUnitTestSHIM - -from vyos.configsession import ConfigSessionError -from vyos.template import ip_from_cidr -from vyos.utils.file import read_file -from vyos.utils.process import process_named_running - -UPNP_CONF = '/run/upnp/miniupnp.conf' -DAEMON = 'miniupnpd' -interface = 'eth0' -base_path = ['service', 'upnp'] -address_base = ['interfaces', 'ethernet', interface, 'address'] - -ipv4_addr = '100.64.0.1/24' -ipv6_addr = '2001:db8::1/64' - -class TestServiceUPnP(VyOSUnitTestSHIM.TestCase): - @classmethod - def setUpClass(cls): - super(TestServiceUPnP, 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) - - cls.cli_set(cls, address_base + [ipv4_addr]) - cls.cli_set(cls, address_base + [ipv6_addr]) - - @classmethod - def tearDownClass(cls): - cls.cli_delete(cls, address_base) - cls._session.commit() - - super(TestServiceUPnP, cls).tearDownClass() - - def tearDown(self): - # Check for running process - self.assertTrue(process_named_running(DAEMON)) - - self.cli_delete(base_path) - self.cli_commit() - - # Check for running process - self.assertFalse(process_named_running(DAEMON)) - - def test_ipv4_base(self): - self.cli_set(base_path + ['nat-pmp']) - self.cli_set(base_path + ['listen', interface]) - - # check validate() - WAN interface is mandatory - with self.assertRaises(ConfigSessionError): - self.cli_commit() - self.cli_set(base_path + ['wan-interface', interface]) - - self.cli_commit() - - config = read_file(UPNP_CONF) - self.assertIn(f'ext_ifname={interface}', config) - self.assertIn(f'listening_ip={interface}', config) - self.assertIn(f'enable_natpmp=yes', config) - self.assertIn(f'enable_upnp=yes', config) - - def test_ipv6_base(self): - v6_addr = ip_from_cidr(ipv6_addr) - - self.cli_set(base_path + ['nat-pmp']) - self.cli_set(base_path + ['listen', interface]) - self.cli_set(base_path + ['listen', v6_addr]) - - # check validate() - WAN interface is mandatory - with self.assertRaises(ConfigSessionError): - self.cli_commit() - self.cli_set(base_path + ['wan-interface', interface]) - - self.cli_commit() - - config = read_file(UPNP_CONF) - self.assertIn(f'ext_ifname={interface}', config) - self.assertIn(f'listening_ip={interface}', config) - self.assertIn(f'ipv6_listening_ip={v6_addr}', config) - self.assertIn(f'enable_natpmp=yes', config) - self.assertIn(f'enable_upnp=yes', config) - -if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/src/conf_mode/service_upnp.py b/src/conf_mode/service_upnp.py deleted file mode 100755 index 0df8dc09e..000000000 --- a/src/conf_mode/service_upnp.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021-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 <http://www.gnu.org/licenses/>. - -import os - -from sys import exit -import uuid -import netifaces -from ipaddress import IPv4Network -from ipaddress import IPv6Network - -from vyos.config import Config -from vyos.utils.process import call -from vyos.template import render -from vyos.template import is_ipv4 -from vyos.template import is_ipv6 -from vyos import ConfigError -from vyos import airbag -airbag.enable() - -config_file = r'/run/upnp/miniupnp.conf' - -def get_config(config=None): - if config: - conf = config - else: - conf = Config() - - base = ['service', 'upnp'] - upnpd = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - - if not upnpd: - return None - - upnpd = conf.merge_defaults(upnpd, recursive=True) - - uuidgen = uuid.uuid1() - upnpd.update({'uuid': uuidgen}) - - return upnpd - -def get_all_interface_addr(prefix, filter_dev, filter_family): - list_addr = [] - for interface in netifaces.interfaces(): - if filter_dev and interface in filter_dev: - continue - addrs = netifaces.ifaddresses(interface) - if netifaces.AF_INET in addrs.keys(): - if netifaces.AF_INET in filter_family: - for addr in addrs[netifaces.AF_INET]: - if prefix: - # we need to manually assemble a list of IPv4 address/prefix - prefix = '/' + \ - str(IPv4Network('0.0.0.0/' + addr['netmask']).prefixlen) - list_addr.append(addr['addr'] + prefix) - else: - list_addr.append(addr['addr']) - if netifaces.AF_INET6 in addrs.keys(): - if netifaces.AF_INET6 in filter_family: - for addr in addrs[netifaces.AF_INET6]: - if prefix: - # we need to manually assemble a list of IPv4 address/prefix - bits = bin(int(addr['netmask'].replace(':', '').split('/')[0], 16)).count('1') - prefix = '/' + str(bits) - list_addr.append(addr['addr'] + prefix) - else: - list_addr.append(addr['addr']) - - return list_addr - -def verify(upnpd): - if not upnpd: - return None - - if 'wan_interface' not in upnpd: - raise ConfigError('To enable UPNP, you must have the "wan-interface" option!') - - if 'rule' in upnpd: - for rule, rule_config in upnpd['rule'].items(): - for option in ['external_port_range', 'internal_port_range', 'ip', 'action']: - if option not in rule_config: - tmp = option.replace('_', '-') - raise ConfigError(f'Every UPNP rule requires "{tmp}" to be set!') - - if 'stun' in upnpd: - for option in ['host', 'port']: - if option not in upnpd['stun']: - raise ConfigError(f'A UPNP stun support must have an "{option}" option!') - - # Check the validity of the IP address - listen_dev = [] - system_addrs_cidr = get_all_interface_addr(True, [], [netifaces.AF_INET, netifaces.AF_INET6]) - system_addrs = get_all_interface_addr(False, [], [netifaces.AF_INET, netifaces.AF_INET6]) - if 'listen' not in upnpd: - raise ConfigError(f'Listen address or interface is required!') - for listen_if_or_addr in upnpd['listen']: - if listen_if_or_addr not in netifaces.interfaces(): - listen_dev.append(listen_if_or_addr) - if (listen_if_or_addr not in system_addrs) and (listen_if_or_addr not in system_addrs_cidr) and \ - (listen_if_or_addr not in netifaces.interfaces()): - if is_ipv4(listen_if_or_addr) and IPv4Network(listen_if_or_addr).is_multicast: - raise ConfigError(f'The address "{listen_if_or_addr}" is an address that is not allowed' - f'to listen on. It is not an interface address nor a multicast address!') - if is_ipv6(listen_if_or_addr) and IPv6Network(listen_if_or_addr).is_multicast: - raise ConfigError(f'The address "{listen_if_or_addr}" is an address that is not allowed' - f'to listen on. It is not an interface address nor a multicast address!') - - system_listening_dev_addrs_cidr = get_all_interface_addr(True, listen_dev, [netifaces.AF_INET6]) - system_listening_dev_addrs = get_all_interface_addr(False, listen_dev, [netifaces.AF_INET6]) - for listen_if_or_addr in upnpd['listen']: - if listen_if_or_addr not in netifaces.interfaces() and \ - (listen_if_or_addr not in system_listening_dev_addrs_cidr) and \ - (listen_if_or_addr not in system_listening_dev_addrs) and \ - is_ipv6(listen_if_or_addr) and \ - (not IPv6Network(listen_if_or_addr).is_multicast): - raise ConfigError(f'{listen_if_or_addr} must listen on the interface of the network card') - -def generate(upnpd): - if not upnpd: - return None - - if os.path.isfile(config_file): - os.unlink(config_file) - - render(config_file, 'firewall/upnpd.conf.j2', upnpd) - -def apply(upnpd): - systemd_service_name = 'miniupnpd.service' - if not upnpd: - # Stop the UPNP service - call(f'systemctl stop {systemd_service_name}') - else: - # Start the UPNP service - call(f'systemctl restart {systemd_service_name}') - -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/op_mode/version.py b/src/op_mode/version.py index ad0293aca..09d69ad1d 100755 --- a/src/op_mode/version.py +++ b/src/op_mode/version.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2016-2022 VyOS maintainers and contributors +# Copyright (C) 2016-2024 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 @@ -30,11 +30,15 @@ from jinja2 import Template version_output_tmpl = """ Version: VyOS {{version}} Release train: {{release_train}} +Release flavor: {{flavor}} Built by: {{built_by}} Built on: {{built_on}} Build UUID: {{build_uuid}} Build commit ID: {{build_git}} +{%- if build_comment %} +Build comment: {{build_comment}} +{% endif %} Architecture: {{system_arch}} Boot via: {{boot_via}} diff --git a/src/systemd/miniupnpd.service b/src/systemd/miniupnpd.service deleted file mode 100644 index 51cb2eed8..000000000 --- a/src/systemd/miniupnpd.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=UPnP service -ConditionPathExists=/run/upnp/miniupnp.conf -After=vyos-router.service -StartLimitIntervalSec=0 - -[Service] -WorkingDirectory=/run/upnp -Type=simple -ExecStart=/usr/sbin/miniupnpd -d -f /run/upnp/miniupnp.conf -PrivateTmp=yes -PIDFile=/run/miniupnpd.pid -Restart=on-failure |