Page MenuHomeVyOS Platform

No OneTemporary

Size
46 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/snmp/etc.snmpd.conf.j2 b/data/templates/snmp/etc.snmpd.conf.j2
index b1ceb0451..9d91192fc 100644
--- a/data/templates/snmp/etc.snmpd.conf.j2
+++ b/data/templates/snmp/etc.snmpd.conf.j2
@@ -1,211 +1,216 @@
### Autogenerated by service_snmp.py ###
# non configurable defaults
sysObjectID 1.3.6.1.4.1.44641
sysServices 14
master agentx
agentXPerms 0777 0777
pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias
smuxpeer .1.3.6.1.2.1.83
smuxpeer .1.3.6.1.2.1.157
smuxsocket localhost
# linkUp/Down configure the Event MIB tables to monitor
# the ifTable for network interfaces being taken up or down
# for making internal queries to retrieve any necessary information
iquerySecName {{ vyos_user }}
# Modified from the default linkUpDownNotification
# to include more OIDs and poll more frequently
notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus
notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus
monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2
monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2
# Remove all old ifTable entries with the same ifName as newly appeared
# interface (with different ifIndex) - this is the case on e.g. ppp interfaces
interface_replace_old yes
# T4902: exclude container storage from monitoring
ignoreDisk /usr/lib/live/mount/persistence/container
########################
# configurable section #
########################
# Default system description is VyOS version
sysDescr VyOS {{ version }}
{% if description is vyos_defined %}
# Description
SysDescr {{ description }}
{% endif %}
# Listen
{% set options = [] %}
{% if listen_address is vyos_defined %}
{% for address, address_options in listen_address.items() %}
{% if address | is_ipv6 %}
{% set protocol = protocol ~ '6' %}
{% endif %}
{% set _ = options.append(protocol ~ ':' ~ address | bracketize_ipv6 ~ ':' ~ address_options.port) %}
{% endfor %}
{% else %}
{% set _ = options.append(protocol ~ ':161') %}
{% set _ = options.append(protocol ~ '6:161') %}
{% endif %}
agentaddress unix:/run/snmpd.socket{{ ',' ~ options | join(',') if options is vyos_defined }}
{% if mib is vyos_defined %}
# Interface MIB limits
{% if mib.interface_max is vyos_defined %}
ifmib_max_num_ifaces {{ mib.interface_max }}
{% endif %}
{% if mib.interface is vyos_defined %}
include_ifmib_iface_prefix {{ mib.interface | join(' ') }}
{% endif %}
{% endif %}
# SNMP communities
{% if community is vyos_defined %}
{% for comm, comm_config in community.items() %}
{% if comm_config.client is vyos_defined %}
{% for client in comm_config.client %}
{% if client | is_ipv4 %}
{{ comm_config.authorization }}community {{ comm }} {{ client }} -V RESTRICTED
{% elif client | is_ipv6 %}
{{ comm_config.authorization }}community6 {{ comm }} {{ client }} -V RESTRICTED
{% endif %}
{% endfor %}
{% endif %}
{% if comm_config.network is vyos_defined %}
{% for network in comm_config.network %}
{% if network | is_ipv4 %}
{{ comm_config.authorization }}community {{ comm }} {{ network }} -V RESTRICTED
{% elif network | is_ipv6 %}
{{ comm_config.authorization }}community6 {{ comm }} {{ network }} -V RESTRICTED
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
# Default RESTRICTED view
view RESTRICTED included .1 80
{% if 'ip-route-table' not in oid_enable %}
# ipRouteTable oid: excluded
view RESTRICTED excluded .1.3.6.1.2.1.4.21
{% endif %}
{% if 'ip-net-to-media-table' not in oid_enable %}
# ipNetToMediaTable oid: excluded
view RESTRICTED excluded .1.3.6.1.2.1.4.22
{% endif %}
{% if 'ip-net-to-physical-phys-address' not in oid_enable %}
# ipNetToPhysicalPhysAddress oid: excluded
view RESTRICTED excluded .1.3.6.1.2.1.4.35
{% endif %}
{% if 'ip-forward' not in oid_enable %}
# ipForward oid: excluded
view RESTRICTED excluded .1.3.6.1.2.1.4.24
{% endif %}
{% if contact is vyos_defined %}
# system contact information
SysContact {{ contact }}
{% endif %}
{% if location is vyos_defined %}
# system location information
SysLocation {{ location }}
{% endif %}
{% if smux_peer is vyos_defined %}
# additional smux peers
{% for peer in smux_peer %}
smuxpeer {{ peer }}
{% endfor %}
{% endif %}
{% if trap_target is vyos_defined %}
# if there is a problem - tell someone!
{% for trap, trap_config in trap_target.items() %}
trap2sink {{ trap }}:{{ trap_config.port }} {{ trap_config.community }}
{% endfor %}
{% endif %}
{% if v3 is vyos_defined %}
#
# SNMPv3 stuff goes here
#
{% if v3.view is vyos_defined %}
# views
{% for view, view_config in v3.view.items() %}
{% if view_config.oid is vyos_defined %}
-{% for oid in view_config.oid %}
+{% for oid, oid_config in view_config.oid.items() %}
view {{ view }} included .{{ oid }}
+{% if oid_config.exclude is vyos_defined %}
+{% for excluded in oid_config.exclude %}
+view {{ view }} excluded .{{ excluded }}
+{% endfor %}
+{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
# access
{% if v3.group is vyos_defined %}
# context sec.model sec.level match read write notif
{% for group, group_config in v3.group.items() %}
access {{ group }} "" usm {{ group_config.seclevel }} exact {{ group_config.view }} {{ 'none' if group_config.mode == 'ro' else group_config.view }} none
{% endfor %}
{% endif %}
# trap-target
{% if v3.trap_target is vyos_defined %}
{% for trap, trap_config in v3.trap_target.items() %}
{% set options = '' %}
{% if trap_config.type == 'inform' %}
{% set options = options ~ ' -Ci' %}
{% endif %}
{% if v3.engineid is vyos_defined %}
{% set options = options ~ ' -e "' ~ v3.engineid ~ '"' %}
{% endif %}
{% if trap_config.user is vyos_defined %}
{% set options = options ~ ' -u ' ~ trap_config.user %}
{% endif %}
{% if trap_config.auth.plaintext_password is vyos_defined or trap_config.auth.encrypted_password is vyos_defined %}
{% set options = options ~ ' -a ' ~ trap_config.auth.type %}
{% if trap_config.auth.plaintext_password is vyos_defined %}
{% set options = options ~ ' -A ' ~ trap_config.auth.plaintext_password %}
{% elif trap_config.auth.encrypted_password is vyos_defined %}
{% set options = options ~ ' -3m ' ~ trap_config.auth.encrypted_password %}
{% endif %}
{% if trap_config.privacy.plaintext_password is vyos_defined or trap_config.privacy.encrypted_password is vyos_defined %}
{% set options = options ~ ' -x ' ~ trap_config.privacy.type %}
{% if trap_config.privacy.plaintext_password is vyos_defined %}
{% set options = options ~ ' -X ' ~ trap_config.privacy.plaintext_password %}
{% elif trap_config.privacy.encrypted_password is vyos_defined %}
{% set options = options ~ ' -3M ' ~ trap_config.privacy.encrypted_password %}
{% endif %}
{% set options = options ~ ' -l authPriv' %}
{% else %}
{% set options = options ~ ' -l authNoPriv' %}
{% endif %}
{% else %}
{% set options = options ~ ' -l noAuthNoPriv' %}
{% endif %}
trapsess -v 3 {{ options }} {{ trap }}:{{ trap_config.protocol }}:{{ trap_config.port }}
{% endfor %}
{% endif %}
# group
{% if v3.user is vyos_defined %}
{% for user, user_config in v3.user.items() %}
group {{ user_config.group }} usm {{ user }}
{% endfor %}
{% endif %}
{# SNMPv3 end #}
{% endif %}
{% if script_extensions.extension_name is vyos_defined %}
# extension scripts
{% for script, script_config in script_extensions.extension_name.items() | sort(attribute=script) %}
extend {{ script }} {{ script_config.script }}
{% endfor %}
{% endif %}
diff --git a/interface-definitions/service_snmp.xml.in b/interface-definitions/service_snmp.xml.in
index e16e9daa1..f23151ef9 100644
--- a/interface-definitions/service_snmp.xml.in
+++ b/interface-definitions/service_snmp.xml.in
@@ -1,598 +1,599 @@
<?xml version="1.0"?>
<!-- SNMP forwarder configuration -->
<interfaceDefinition>
<node name="service">
<children>
<node name="snmp" owner="${vyos_conf_scripts_dir}/service_snmp.py">
<properties>
<help>Simple Network Management Protocol (SNMP)</help>
<priority>900</priority>
</properties>
<children>
<tagNode name="community">
<properties>
<help>Community name</help>
<constraint>
<regex>[[:alnum:]-_!@*#]{1,100}</regex>
</constraint>
<constraintErrorMessage>Community string is limited to alphanumerical characters, -, _, !, @, *, and # with a total lenght of 100</constraintErrorMessage>
</properties>
<children>
<leafNode name="authorization">
<properties>
<help>Authorization type</help>
<completionHelp>
<list>ro rw</list>
</completionHelp>
<valueHelp>
<format>ro</format>
<description>Read-Only</description>
</valueHelp>
<valueHelp>
<format>rw</format>
<description>Read-Write</description>
</valueHelp>
<constraint>
<regex>(ro|rw)</regex>
</constraint>
<constraintErrorMessage>Authorization type must be either 'rw' or 'ro'</constraintErrorMessage>
</properties>
<defaultValue>ro</defaultValue>
</leafNode>
<leafNode name="client">
<properties>
<help>IP address of SNMP client allowed to contact system</help>
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6-address"/>
</constraint>
<multi/>
</properties>
</leafNode>
<leafNode name="network">
<properties>
<help>Subnet of SNMP client(s) allowed to contact system</help>
<valueHelp>
<format>ipv4net</format>
<description>IP address and prefix length</description>
</valueHelp>
<valueHelp>
<format>ipv6net</format>
<description>IPv6 address and prefix length</description>
</valueHelp>
<constraint>
<validator name="ip-prefix"/>
</constraint>
<multi/>
</properties>
<defaultValue>0.0.0.0/0 ::/0</defaultValue>
</leafNode>
</children>
</tagNode>
<leafNode name="contact">
<properties>
<help>Contact information</help>
<constraint>
<regex>.{1,255}</regex>
</constraint>
<constraintErrorMessage>Contact information is limited to 255 characters or less</constraintErrorMessage>
</properties>
</leafNode>
#include <include/generic-description.xml.i>
<node name="mib">
<properties>
<help>Management information base (MIB)</help>
</properties>
<children>
<leafNode name="interface-max">
<properties>
<help>Sets the maximum number of interfaces included in IF-MIB data collection</help>
<valueHelp>
<format>u32:1-4294967295</format>
<description>Sets the maximum number of interfaces included in IF-MIB data collection</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-4294967295"/>
</constraint>
</properties>
</leafNode>
<leafNode name="interface">
<properties>
<help>Sets the interface name prefix to include in the IF-MIB data collection</help>
<completionHelp>
<list>br bond dum eth gnv macsec peth sstpc tun veth vti vtun vxlan wg wlan wwan</list>
</completionHelp>
<valueHelp>
<format>br</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>bond</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>dum</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>eth</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>gnv</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>macsec</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>peth</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>sstpc</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>tun</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>veth</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>vti</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>vtun</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>vxlan</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>wg</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>wlan</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<valueHelp>
<format>wwan</format>
<description>Allow prefix for IF-MIB data collection</description>
</valueHelp>
<constraint>
<regex>(br|bond|dum|eth|gnv|macsec|peth|sstpc|tun|veth|vti|vtun|vxlan|wg|wlan|wwan)</regex>
</constraint>
<multi/>
</properties>
</leafNode>
</children>
</node>
<tagNode name="listen-address">
<properties>
<help>IP address to listen for incoming SNMP requests</help>
<completionHelp>
<script>${vyos_completion_dir}/list_local_ips.sh --both</script>
</completionHelp>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address to listen for incoming SNMP requests</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address to listen for incoming SNMP requests</description>
</valueHelp>
<constraint>
<validator name="ip-address"/>
</constraint>
</properties>
<children>
#include <include/port-number.xml.i>
<leafNode name="port">
<defaultValue>161</defaultValue>
</leafNode>
</children>
</tagNode>
<leafNode name="location">
<properties>
<help>Location information</help>
<constraint>
<regex>.{1,255}</regex>
</constraint>
<constraintErrorMessage>Location is limited to 255 characters or less</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="oid-enable">
<properties>
<help>Enable specific OIDs that by default are disable</help>
<completionHelp>
<list>ip-forward ip-route-table ip-net-to-media-table ip-net-to-physical-phys-address</list>
</completionHelp>
<valueHelp>
<format>ip-forward</format>
<description>Enable ipForward: .1.3.6.1.2.1.4.24</description>
</valueHelp>
<valueHelp>
<format>ip-route-table</format>
<description>Enable ipRouteTable: .1.3.6.1.2.1.4.21</description>
</valueHelp>
<valueHelp>
<format>ip-net-to-media-table</format>
<description>Enable ipNetToMediaTable: .1.3.6.1.2.1.4.22</description>
</valueHelp>
<valueHelp>
<format>ip-net-to-physical-phys-address</format>
<description>Enable ipNetToPhysicalPhysAddress: .1.3.6.1.2.1.4.35</description>
</valueHelp>
<constraint>
<regex>(ip-forward|ip-route-table|ip-net-to-media-table|ip-net-to-physical-phys-address)</regex>
</constraint>
<constraintErrorMessage>OID must be one of the liste options</constraintErrorMessage>
<multi/>
</properties>
</leafNode>
#include <include/protocol-tcp-udp.xml.i>
<leafNode name="smux-peer">
<properties>
<help>Register a subtree for SMUX-based processing</help>
<valueHelp>
<format>txt</format>
<description>SNMP Object Identifier</description>
</valueHelp>
<multi/>
</properties>
</leafNode>
<leafNode name="trap-source">
<properties>
<help>SNMP trap source address</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address</description>
</valueHelp>
<constraint>
<validator name="ip-address"/>
</constraint>
</properties>
</leafNode>
<tagNode name="trap-target">
<properties>
<help>Address of trap target</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address</description>
</valueHelp>
<constraint>
<validator name="ip-address"/>
</constraint>
</properties>
<children>
<leafNode name="community">
<properties>
<help>Community used when sending trap information</help>
</properties>
</leafNode>
#include <include/port-number.xml.i>
<leafNode name="port">
<defaultValue>162</defaultValue>
</leafNode>
</children>
</tagNode>
<node name="v3">
<properties>
<help>Simple Network Management Protocol (SNMP) v3</help>
</properties>
<children>
<leafNode name="engineid">
<properties>
<help>Specifies the EngineID that uniquely identify an agent (e.g. 000000000000000000000002)</help>
<constraint>
<regex>([0-9a-f][0-9a-f]){1,18}</regex>
</constraint>
<constraintErrorMessage>ID must contain an even number (from 2 to 36) of hex digits</constraintErrorMessage>
</properties>
<defaultValue></defaultValue>
</leafNode>
<tagNode name="group">
<properties>
<help>Specifies the group with name groupname</help>
</properties>
<children>
#include <include/snmp/access-mode.xml.i>
<leafNode name="seclevel">
<properties>
<help>Security levels</help>
<completionHelp>
<list>noauth auth priv</list>
</completionHelp>
<valueHelp>
<format>noauth</format>
<description>Messages not authenticated and not encrypted (noAuthNoPriv)</description>
</valueHelp>
<valueHelp>
<format>auth</format>
<description>Messages are authenticated but not encrypted (authNoPriv)</description>
</valueHelp>
<valueHelp>
<format>priv</format>
<description>Messages are authenticated and encrypted (authPriv)</description>
</valueHelp>
<constraint>
<regex>(noauth|auth|priv)</regex>
</constraint>
</properties>
<defaultValue>auth</defaultValue>
</leafNode>
<leafNode name="view">
<properties>
<help>Defines the name of view</help>
<completionHelp>
<path>service snmp v3 view</path>
</completionHelp>
</properties>
</leafNode>
</children>
</tagNode>
<tagNode name="trap-target">
<properties>
<help>Defines SNMP target for inform or traps for IP</help>
<valueHelp>
<format>ipv4</format>
<description>IP address of trap target</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address of trap target</description>
</valueHelp>
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6-address"/>
</constraint>
</properties>
<children>
<node name="auth">
<properties>
<help>Defines the privacy</help>
</properties>
<children>
<leafNode name="encrypted-password">
<properties>
<help>Defines the encrypted key for authentication</help>
<constraint>
<regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="plaintext-password">
<properties>
<help>Defines the clear text key for authentication</help>
<constraint>
<regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
#include <include/snmp/authentication-type.xml.i>
</children>
</node>
#include <include/port-number.xml.i>
<leafNode name="port">
<defaultValue>162</defaultValue>
</leafNode>
<node name="privacy">
<properties>
<help>Defines the privacy</help>
</properties>
<children>
<leafNode name="encrypted-password">
<properties>
<help>Defines the encrypted key for privacy protocol</help>
<constraint>
<regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="plaintext-password">
<properties>
<help>Defines the clear text key for privacy protocol</help>
<constraint>
<regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
#include <include/snmp/privacy-type.xml.i>
</children>
</node>
#include <include/protocol-tcp-udp.xml.i>
<leafNode name="type">
<properties>
<help>Specifies the type of notification between inform and trap</help>
<completionHelp>
<list>inform trap</list>
</completionHelp>
<valueHelp>
<format>inform</format>
<description>Use INFORM</description>
</valueHelp>
<valueHelp>
<format>trap</format>
<description>Use TRAP</description>
</valueHelp>
<constraint>
<regex>(inform|trap)</regex>
</constraint>
</properties>
<defaultValue>inform</defaultValue>
</leafNode>
<leafNode name="user">
<properties>
<help>Defines username for authentication</help>
<completionHelp>
<path>service snmp v3 user</path>
</completionHelp>
</properties>
</leafNode>
</children>
</tagNode>
<tagNode name="user">
<properties>
<help>Specifies the user with name username</help>
<constraint>
<regex>[^\(\)\|\-]+</regex>
</constraint>
<constraintErrorMessage>Illegal characters in name</constraintErrorMessage>
</properties>
<children>
<node name="auth">
<properties>
<help>Specifies the auth</help>
</properties>
<children>
<leafNode name="encrypted-password">
<properties>
<help>Defines the encrypted key for authentication</help>
<constraint>
<regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="plaintext-password">
<properties>
<help>Defines the clear text key for authentication</help>
<constraint>
<regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
#include <include/snmp/authentication-type.xml.i>
</children>
</node>
<leafNode name="group">
<properties>
<help>Specifies group for user name</help>
<completionHelp>
<path>service snmp v3 group</path>
</completionHelp>
</properties>
</leafNode>
#include <include/snmp/access-mode.xml.i>
<node name="privacy">
<properties>
<help>Defines the privacy</help>
</properties>
<children>
<leafNode name="encrypted-password">
<properties>
<help>Defines the encrypted key for privacy protocol</help>
<constraint>
<regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="plaintext-password">
<properties>
<help>Defines the clear text key for privacy protocol</help>
<constraint>
<regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
#include <include/snmp/privacy-type.xml.i>
</children>
</node>
</children>
</tagNode>
<tagNode name="view">
<properties>
<help>Specifies the view with name viewname</help>
<constraint>
<regex>[^\(\)\|\-]+</regex>
</constraint>
<constraintErrorMessage>Illegal characters in name</constraintErrorMessage>
</properties>
<children>
<tagNode name="oid">
<properties>
<help>Specifies the oid</help>
<constraint>
<regex>[0-9]+(\.[0-9]+)*</regex>
</constraint>
<constraintErrorMessage>OID must start from a number</constraintErrorMessage>
</properties>
<children>
<leafNode name="exclude">
<properties>
<help>Exclude is an optional argument</help>
+ <multi/>
</properties>
</leafNode>
<leafNode name="mask">
<properties>
<help>Defines a bit-mask that is indicating which subidentifiers of the associated subtree OID should be regarded as significant</help>
<constraint>
<regex>[0-9a-f]{2}([\.:][0-9a-f]{2})*</regex>
</constraint>
<constraintErrorMessage>MASK is a list of hex octets, separated by '.' or ':'</constraintErrorMessage>
</properties>
</leafNode>
</children>
</tagNode>
</children>
</tagNode>
</children>
</node>
<node name="script-extensions">
<properties>
<help>SNMP script extensions</help>
</properties>
<children>
<tagNode name="extension-name">
<properties>
<help>Extension name</help>
<constraint>
<regex>[a-z0-9\.\-\_]+</regex>
</constraint>
<constraintErrorMessage>Script extension contains invalid characters</constraintErrorMessage>
</properties>
<children>
<leafNode name="script">
<properties>
<help>Script location and name</help>
<completionHelp>
<script>ls /config/user-data</script>
</completionHelp>
<constraint>
<regex>[a-z0-9\.\-\_\/]+</regex>
</constraint>
<constraintErrorMessage>Script extension contains invalid characters</constraintErrorMessage>
</properties>
</leafNode>
</children>
</tagNode>
</children>
</node>
#include <include/interface/vrf.xml.i>
</children>
</node>
</children>
</node>
</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_service_snmp.py b/smoketest/scripts/cli/test_service_snmp.py
index 52a72ec4f..b3daa90d0 100755
--- a/smoketest/scripts/cli/test_service_snmp.py
+++ b/smoketest/scripts/cli/test_service_snmp.py
@@ -1,233 +1,250 @@
#!/usr/bin/env python3
#
# Copyright (C) 2019-2021 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 re
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.template import is_ipv4
from vyos.template import address_from_cidr
from vyos.utils.process import call
from vyos.utils.process import DEVNULL
from vyos.utils.file import read_file
from vyos.utils.process import process_named_running
from vyos.version import get_version_data
PROCESS_NAME = 'snmpd'
SNMPD_CONF = '/etc/snmp/snmpd.conf'
base_path = ['service', 'snmp']
snmpv3_group = 'default_group'
snmpv3_view = 'default_view'
snmpv3_view_oid = '1'
snmpv3_user = 'vyos'
snmpv3_auth_pw = 'vyos12345678'
snmpv3_priv_pw = 'vyos87654321'
snmpv3_engine_id = '000000000000000000000002'
def get_config_value(key):
tmp = read_file(SNMPD_CONF)
tmp = re.findall(r'\n?{}\s+(.*)'.format(key), tmp)
return tmp[0]
class TestSNMPService(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
super(TestSNMPService, 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 testing SNMP config
self.cli_delete(base_path)
self.cli_commit()
# Check for running process
self.assertFalse(process_named_running(PROCESS_NAME))
def test_snmp_basic(self):
dummy_if = 'dum7312'
dummy_addr = '100.64.0.1/32'
contact = 'maintainers@vyos.io'
location = 'QEMU'
self.cli_set(['interfaces', 'dummy', dummy_if, 'address', dummy_addr])
# Check if SNMP can be configured and service runs
clients = ['192.0.2.1', '2001:db8::1']
networks = ['192.0.2.128/25', '2001:db8:babe::/48']
listen = ['127.0.0.1', '::1', address_from_cidr(dummy_addr)]
port = '5000'
for auth in ['ro', 'rw']:
community = 'VyOS' + auth
self.cli_set(base_path + ['community', community, 'authorization', auth])
for client in clients:
self.cli_set(base_path + ['community', community, 'client', client])
for network in networks:
self.cli_set(base_path + ['community', community, 'network', network])
for addr in listen:
self.cli_set(base_path + ['listen-address', addr, 'port', port])
self.cli_set(base_path + ['contact', contact])
self.cli_set(base_path + ['location', location])
self.cli_commit()
# verify listen address, it will be returned as
# ['unix:/run/snmpd.socket,udp:127.0.0.1:161,udp6:[::1]:161']
# thus we need to transfor this into a proper list
config = get_config_value('agentaddress')
expected = 'unix:/run/snmpd.socket'
self.assertIn(expected, config)
for addr in listen:
if is_ipv4(addr):
expected = f'udp:{addr}:{port}'
else:
expected = f'udp6:[{addr}]:{port}'
self.assertIn(expected, config)
config = get_config_value('sysDescr')
version_data = get_version_data()
self.assertEqual('VyOS ' + version_data['version'], config)
config = get_config_value('SysContact')
self.assertEqual(contact, config)
config = get_config_value('SysLocation')
self.assertEqual(location, config)
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(['interfaces', 'dummy', dummy_if])
## Check communities and default view RESTRICTED
for auth in ['ro', 'rw']:
community = 'VyOS' + auth
for addr in clients:
if is_ipv4(addr):
entry = auth + 'community ' + community + ' ' + addr + ' -V'
else:
entry = auth + 'community6 ' + community + ' ' + addr + ' -V'
config = get_config_value(entry)
expected = 'RESTRICTED'
self.assertIn(expected, config)
for addr in networks:
if is_ipv4(addr):
entry = auth + 'community ' + community + ' ' + addr + ' -V'
else:
entry = auth + 'community6 ' + community + ' ' + addr + ' -V'
config = get_config_value(entry)
expected = 'RESTRICTED'
self.assertIn(expected, config)
# And finally check global entry for RESTRICTED view
config = get_config_value('view RESTRICTED included .1')
self.assertIn('80', config)
def test_snmpv3_sha(self):
# Check if SNMPv3 can be configured with SHA authentication
# and service runs
self.cli_set(base_path + ['v3', 'engineid', snmpv3_engine_id])
self.cli_set(base_path + ['v3', 'group', 'default', 'mode', 'ro'])
# check validate() - a view must be created before this can be committed
with self.assertRaises(ConfigSessionError):
self.cli_commit()
self.cli_set(base_path + ['v3', 'view', 'default', 'oid', '1'])
self.cli_set(base_path + ['v3', 'group', 'default', 'view', 'default'])
# create user
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'plaintext-password', snmpv3_auth_pw])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'type', 'sha'])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'plaintext-password', snmpv3_priv_pw])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'type', 'aes'])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'group', 'default'])
self.cli_commit()
# commit will alter the CLI values - check if they have been updated:
hashed_password = '4e52fe55fd011c9c51ae2c65f4b78ca93dcafdfe'
tmp = self._session.show_config(base_path + ['v3', 'user', snmpv3_user, 'auth', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
hashed_password = '54705c8de9e81fdf61ad7ac044fa8fe611ddff6b'
tmp = self._session.show_config(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
# TODO: read in config file and check values
# Try SNMPv3 connection
tmp = call(f'snmpwalk -v 3 -u {snmpv3_user} -a SHA -A {snmpv3_auth_pw} -x AES -X {snmpv3_priv_pw} -l authPriv 127.0.0.1', stdout=DEVNULL)
self.assertEqual(tmp, 0)
def test_snmpv3_md5(self):
# Check if SNMPv3 can be configured with MD5 authentication
# and service runs
self.cli_set(base_path + ['v3', 'engineid', snmpv3_engine_id])
# create user
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'plaintext-password', snmpv3_auth_pw])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'type', 'md5'])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'plaintext-password', snmpv3_priv_pw])
self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'type', 'des'])
# check validate() - user requires a group to be created
with self.assertRaises(ConfigSessionError):
self.cli_commit()
self.cli_set(base_path + ['v3', 'user', 'vyos', 'group', snmpv3_group])
self.cli_set(base_path + ['v3', 'group', snmpv3_group, 'mode', 'ro'])
# check validate() - a view must be created before this can be comitted
with self.assertRaises(ConfigSessionError):
self.cli_commit()
self.cli_set(base_path + ['v3', 'view', snmpv3_view, 'oid', snmpv3_view_oid])
self.cli_set(base_path + ['v3', 'group', snmpv3_group, 'view', snmpv3_view])
self.cli_commit()
# commit will alter the CLI values - check if they have been updated:
hashed_password = '4c67690d45d3dfcd33d0d7e308e370ad'
tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'auth', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
hashed_password = 'e11c83f2c510540a3c4de84ee66de440'
tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'privacy', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
tmp = read_file(SNMPD_CONF)
# views
self.assertIn(f'view {snmpv3_view} included .{snmpv3_view_oid}', tmp)
# group
self.assertIn(f'group {snmpv3_group} usm {snmpv3_user}', tmp)
# access
self.assertIn(f'access {snmpv3_group} "" usm auth exact {snmpv3_view} none none', tmp)
# Try SNMPv3 connection
tmp = call(f'snmpwalk -v 3 -u {snmpv3_user} -a MD5 -A {snmpv3_auth_pw} -x DES -X {snmpv3_priv_pw} -l authPriv 127.0.0.1', stdout=DEVNULL)
self.assertEqual(tmp, 0)
+ def test_snmpv3_view_exclude(self):
+ snmpv3_view_oid_exclude = ['1.3.6.1.2.1.4.21', '1.3.6.1.2.1.4.24']
+
+ self.cli_set(base_path + ['v3', 'group', snmpv3_group, 'view', snmpv3_view])
+ self.cli_set(base_path + ['v3', 'view', snmpv3_view, 'oid', snmpv3_view_oid])
+
+ for excluded in snmpv3_view_oid_exclude:
+ self.cli_set(base_path + ['v3', 'view', snmpv3_view, 'oid', snmpv3_view_oid, 'exclude', excluded])
+
+ self.cli_commit()
+
+ tmp = read_file(SNMPD_CONF)
+ # views
+ self.assertIn(f'view {snmpv3_view} included .{snmpv3_view_oid}', tmp)
+ for excluded in snmpv3_view_oid_exclude:
+ self.assertIn(f'view {snmpv3_view} excluded .{excluded}', tmp)
+
if __name__ == '__main__':
unittest.main(verbosity=2)

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 17, 12:46 AM (3 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4412178
Default Alt Text
(46 KB)

Event Timeline