access: limit OIDs exposed over SNMP

Define a custom SNMP group with read access only to fields we need.

For D-Link switches, modifying the group must be handled the same as
user, i.e. the group (and user) must be removed and readded.

Untested for FS S5800.
This commit is contained in:
Timotej Lazar 2025-10-22 13:43:07 +02:00
parent 2c93cab682
commit 7a2223ea71
5 changed files with 61 additions and 16 deletions

View file

@ -13,13 +13,27 @@
set_fact: set_fact:
snmp_hashes: '{{ (snmp_config.stdout | from_yaml).snmpv3.hashes }}' snmp_hashes: '{{ (snmp_config.stdout | from_yaml).snmpv3.hashes }}'
- name: Get SNMP users # check if the SNMP user and group we want to set differ from current switch config
# in this case we have to remove them before trying to chane password or settings
- name: Define SNMP user and group configuration commands
set_fact: set_fact:
snmp_current: "{{ ansible_net_config | split('\n') | select('match', '^snmp-server user '+manager.snmp_user+' public v3') }}" target_user: "snmp-server user {{ manager.snmp_user }} public v3 encrypted auth sha {{ snmp_hashes.auth }} priv {{ snmp_hashes.priv[:32] }} "
snmp_target: "snmp-server user {{ manager.snmp_user }} public v3 encrypted auth sha {{ snmp_hashes.auth }} priv {{ snmp_hashes.priv[:32] }} " target_group: "snmp-server group public v3 priv read public "
- name: Get existing SNMP user and group entries from switch
set_fact:
current_user: "{{ ansible_net_config | split('\n')
| select('match', '^snmp-server user '+manager.snmp_user+' public v3') }}"
current_group: "{{ ansible_net_config | split('\n')
| select('match', '^snmp-server group public v3') }}"
- name: Check if existing SNMP user and/or group should be removed
set_fact:
remove_user: "{{ current_user and target_user is not in current_user }}"
remove_group: "{{ current_group and target_group is not in current_group }}"
- name: Remove existing SNMP user to reset password - name: Remove existing SNMP user to reset password
when: 'snmp_current and snmp_target is not in snmp_current' when: remove_user or remove_group # can’t change group with existing users
block: block:
- name: Remove SNMP user - name: Remove SNMP user
ansible.netcommon.cli_config: ansible.netcommon.cli_config:
@ -27,10 +41,28 @@
notify: write config notify: write config
- set_fact: - set_fact:
snmp_current: false current_user: false
- name: Remove existing SNMP group to change parameters
when: remove_group
block:
- name: Remove existing SNMP group
ansible.netcommon.cli_config:
config: 'no snmp-server group public v3 priv'
notify: write config
- set_fact:
current_group: false
# create new SNMP user and group
- name: Create SNMP group and user
when: not current_group
ansible.netcommon.cli_config:
config: '{{ target_group }}'
notify: write config
- name: Create SNMP user - name: Create SNMP user
when: 'not snmp_current' when: not current_user
ansible.netcommon.cli_config: ansible.netcommon.cli_config:
config: '{{ snmp_target }}' config: '{{ target_user }}'
notify: write config notify: write config

View file

@ -4,11 +4,11 @@
- name: Get existing SNMP users - name: Get existing SNMP users
set_fact: set_fact:
snmp_current: "{{ ansible_net_config | split('\n') | select('match', '^snmp-server usm-user '+manager.snmp_user) }}" current_user: "{{ ansible_net_config | split('\n') | select('match', '^snmp-server usm-user '+manager.snmp_user) }}"
snmp_target: "snmp-server usm-user {{ manager.snmp_user }} authentication sha {{ manager.snmp_pass }} privacy des {{ manager.snmp_pass }} " target_user: "snmp-server usm-user {{ manager.snmp_user }} authentication sha {{ manager.snmp_pass }} privacy des {{ manager.snmp_pass }} "
- name: Remove existing SNMP user to reset password - name: Remove existing SNMP user to reset password
when: "snmp_current and snmp_target is not in snmp_current" when: "current_user and target_user is not in current_user"
block: block:
- name: Remove SNMP user - name: Remove SNMP user
ansible.netcommon.cli_config: ansible.netcommon.cli_config:
@ -19,14 +19,14 @@
notify: write config notify: write config
- set_fact: - set_fact:
snmp_current: false current_user: false
- name: Create SNMP user - name: Create SNMP user
when: "not snmp_current" when: "not current_user"
ansible.netcommon.cli_config: ansible.netcommon.cli_config:
config: "{{ item }}" config: "{{ item }}"
loop: loop:
- "{{ snmp_target }}" - "{{ target_user }}"
- "snmp-server group public user {{ manager.snmp_user }} security-model usm" - "snmp-server group public user {{ manager.snmp_user }} security-model usm"
no_log: true no_log: true
notify: write config notify: write config

View file

@ -112,7 +112,11 @@ snmp-server name {{ inventory_hostname }}
snmp-server location {{ rack }} snmp-server location {{ rack }}
{# SNMP engine ID must be exactly 24 hex digits #} {# SNMP engine ID must be exactly 24 hex digits #}
snmp-server engineID local {{ snmp_engine_id }} snmp-server engineID local {{ snmp_engine_id }}
snmp-server group public v3 priv read CommunityView {# limit MIBs exposed over SNMP #}
snmp-server view public 1.3.6.1.2.1.1 included {# system +#}
snmp-server view public 1.3.6.1.2.1.2 included {# interfaces +#}
snmp-server view public 1.3.6.1.2.1.17.7 included {# qBridgeMIB +#}
snmp-server view public 1.3.6.1.2.1.31 included {# ifMIB +#}
sntp enable sntp enable
{% for address in ntp %} {% for address in ntp %}

View file

@ -17,7 +17,11 @@ vlan database
snmp-server enable snmp-server enable
snmp-server system-location {{ rack }} snmp-server system-location {{ rack }}
snmp-server engineID {{ snmp_engine_id }} snmp-server engineID {{ snmp_engine_id }}
snmp-server access public security-model usm priv read _all_ snmp-server view public included 1.3.6.1.2.1.1 {# system +#}
snmp-server view public included 1.3.6.1.2.1.2 {# interfaces +#}
snmp-server view public included 1.3.6.1.2.1.17.7 {# qBridgeMIB +#}
snmp-server view public included 1.3.6.1.2.1.31 {# ifMIB +#}
snmp-server access public security-model usm priv read public
{# sort to ensure LAG interfaces are added last #} {# sort to ensure LAG interfaces are added last #}
{% for iface in interfaces | sort(attribute="type.value") | sort(attribute="mgmt_only") %} {% for iface in interfaces | sort(attribute="type.value") | sort(attribute="mgmt_only") %}

View file

@ -58,4 +58,9 @@ interface {{ iface.name }}
enable service snmp-agent enable service snmp-agent
snmp-server location {{ rack }} snmp-server location {{ rack }}
snmp-server group public v3 priv read default {# limit MIBs exposed over SNMP #}
snmp-server view public 1.3.6.1.2.1.1 include {# system +#}
snmp-server view public 1.3.6.1.2.1.2 include {# interfaces +#}
snmp-server view public 1.3.6.1.2.1.17.7 include {# qBridgeMIB +#}
snmp-server view public 1.3.6.1.2.1.31 include {# ifMIB +#}
snmp-server group public v3 priv read public