From 374ccdb80af5f9e6c7994cbea07d59f6263c7bdc Mon Sep 17 00:00:00 2001 From: Ycarus Date: Tue, 27 Nov 2018 15:16:42 +0100 Subject: [PATCH] Simplify SNMPd interface --- luci-app-snmpd/luasrc/model/cbi/snmpd.lua | 80 ++-- luci-app-snmpd/luasrc/view/snmpd.htm | 132 +++++++ luci-app-snmpd/root/etc/config/snmpd | 91 +++++ luci-app-snmpd/root/etc/init.d/snmpd | 348 ++++++++++++++++++ .../root/etc/uci-defaults/4400-snmpd | 9 + 5 files changed, 618 insertions(+), 42 deletions(-) create mode 100644 luci-app-snmpd/luasrc/view/snmpd.htm create mode 100644 luci-app-snmpd/root/etc/config/snmpd create mode 100755 luci-app-snmpd/root/etc/init.d/snmpd diff --git a/luci-app-snmpd/luasrc/model/cbi/snmpd.lua b/luci-app-snmpd/luasrc/model/cbi/snmpd.lua index 4c8cdea5a..132b3a1d2 100644 --- a/luci-app-snmpd/luasrc/model/cbi/snmpd.lua +++ b/luci-app-snmpd/luasrc/model/cbi/snmpd.lua @@ -16,7 +16,17 @@ network.rmempty = true network.cast = "string" network.nocreate = true -s = m:section(TypedSection, "com2sec", translate("com2sec")) +s = m:section(TypedSection, "system", translate("System")) +s.addremove = false + +sysLocation = s:option(Value, "sysLocation", translate("Location")) +sysContact = s:option(Value, "sysContact", translate("Contact")) +sysName = s:option(Value, "sysName", translate("Name")) +--sysServices = s:option(Value, "sysServices", translate("Services")) +--sysDescr = s:option(Value, "sysDescr", translate("Description")) +--sysObjectID = s:option(Value, "sysObjectID", translate("ObjectID")) + +s = m:section(TypedSection, "com2sec", translate("com2sec security")) s.addremove = true secname = s:option(ListValue, "secname", translate("Server")) @@ -33,24 +43,24 @@ community = s:option(Value, "community", translate("Community")) community.optional = false community.rmempty = false -s = m:section(TypedSection, "com2sec6", translate("com2sec6")) -s.addremove = true +--s = m:section(TypedSection, "com2sec6", translate("com2sec6")) +--s.addremove = true -secname = s:option(ListValue, "secname", translate("secname")) -secname.optional = false -secname:value("ro",translate("Read-only")) -secname:value("rw",translate("Read-write")) +--secname = s:option(ListValue, "secname", translate("secname")) +--secname.optional = false +--secname:value("ro",translate("Read-only")) +--secname:value("rw",translate("Read-write")) -source = s:option(Value, "source", translate("Source")) -source.datatype = "host" -source.optional = false -source.rmempty = false +--source = s:option(Value, "source", translate("Source")) +--source.datatype = "host" +--source.optional = false +--source.rmempty = false -community = s:option(Value, "community", translate("Community")) -community.optional = false -community.rmempty = false +--community = s:option(Value, "community", translate("Community")) +--community.optional = false +--community.rmempty = false -s = m:section(TypedSection, "group", translate("Group")) +s = m:section(TypedSection, "group", translate("Group"), translate("Groups help define access methods")) s.addremove = true s.anonymous = false @@ -59,10 +69,9 @@ secname.optional = false secname:value("ro",translate("Read-only")) secname:value("rw",translate("Read-write")) -group = s:option(ListValue, "group", translate("Group")) +group = s:option(Value, "group", translate("Group")) group.optional = false -group:value("public","public") -group:value("private","private") +group.rmempty = false version = s:option(ListValue, "version", translate("version")) version.optional = false @@ -74,10 +83,9 @@ s = m:section(TypedSection, "access", translate("Access")) s.addremove = true s.anonymous = false -group = s:option(ListValue, "group", translate("Group")) +group = s:option(Value, "group", translate("Group")) group.optional = false -group:value("public","public") -group:value("private","private") +group.rmempty = false version = s:option(ListValue, "version", translate("version")) version.optional = false @@ -110,28 +118,16 @@ notify.optional = false notify:value("all","all") notify:value("none","none") -s = m:section(TypedSection, "engineid", translate("engineid")) -s.addremove = false -s.anonymous = true +--s = m:section(TypedSection, "engineid", translate("engineid")) +--s.addremove = false +--s.anonymous = true -engineid = s:option(Value, "engineid", translate("engineid")) -engineidtype = s:option(ListValue, "engineidtype", translate("engineidtype")) -engineidtype:value("1",translate("IPv4")) -engineidtype:value("2",translate("IPv6")) -engineidtype:value("3",translate("MAC")) - -engineidnic = s:option(Value, "engineidnic", translate("engineidnic")) - -s = m:section(TypedSection, "system", translate("System")) -s.addremove = true -s.anonymous = true - -sysLocation = s:option(Value, "sysLocation", translate("Location")) -sysContact = s:option(Value, "sysContact", translate("Contact")) -sysName = s:option(Value, "sysName", translate("Name")) -sysServices = s:option(Value, "sysServices", translate("Services")) -sysDescr = s:option(Value, "sysDescr", translate("Description")) -sysObjectID = s:option(Value, "sysObjectID", translate("ObjectID")) +--engineid = s:option(Value, "engineid", translate("engineid")) +--engineidtype = s:option(ListValue, "engineidtype", translate("engineidtype")) +--engineidtype:value("1",translate("IPv4")) +--engineidtype:value("2",translate("IPv6")) +--engineidtype:value("3",translate("MAC")) +--engineidnic = s:option(Value, "engineidnic", translate("engineidnic")) s = m:section(TypedSection, "exec", translate("Exec")) s.addremove = true diff --git a/luci-app-snmpd/luasrc/view/snmpd.htm b/luci-app-snmpd/luasrc/view/snmpd.htm new file mode 100644 index 000000000..74e60ca9a --- /dev/null +++ b/luci-app-snmpd/luasrc/view/snmpd.htm @@ -0,0 +1,132 @@ +<%+header%> + + + +<% + local uci = require("luci.model.uci").cursor() + local hosts = uci:get_list("dhcp", uci:get_first("dhcp","dnsmasq"), "ipset") + local ips = uci:get_list("omr-bypass", "ips", "ip") + local dpi = uci:get_list("omr-bypass", "dpi", "proto") + local tmpfile = os.tmpname() + local dpi_available_proto = luci.util.execi("cat /proc/net/xt_ndpi/proto | awk '{print $3}' | sort -u | head -n -1") + local sys = require "luci.sys" + local ifaces = sys.net:devices() + local bypassif = uci:get("omr-bypass","defaults","ifname") or "" +%> +<% if stderr and #stderr > 0 then %>
<%=pcdata(stderr)%>
<% end %> +
+
+

<%:SNMPd%>

+
+ <%:General%> +
+
+ +
+ checked<% end %>> +
+
+
+ network +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +

<%:General%>

+ +
+
+
+
+
<%:Domain, IP or network%>
+
<%:Output interface%>
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+

<%:Protocols%>

+
+
+
+
<%:Protocols%>
+
<%:Output interface%>
+
+
+
+
+<% + local allprt="""" + local protos = {} + for l in io.lines("/proc/net/xt_ndpi/proto") do + local a,b,c,d = l:match('(%w+) (%w+)') + if b ~= "2" and not string.match(b,"custom") then + table.insert(protos,b) + end + end + table.sort(protos) + for _,b in ipairs(protos) do + allprt=allprt .. ","" .. b .. """ + end +%> +
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ + +
+ + +<%+footer%> diff --git a/luci-app-snmpd/root/etc/config/snmpd b/luci-app-snmpd/root/etc/config/snmpd new file mode 100644 index 000000000..09a89474f --- /dev/null +++ b/luci-app-snmpd/root/etc/config/snmpd @@ -0,0 +1,91 @@ + +config agent + option agentaddress 'UDP:161,UDP6:161' + +config agentx + option agentxsocket '/var/run/agentx.sock' + +config com2sec 'public' + option secname 'ro' + option source 'default' + option community 'public' + +config com2sec 'private' + option secname 'rw' + option source 'localhost' + option community 'private' + +config group 'public_v1' + option group 'public' + option version 'v1' + option secname 'ro' + +config group 'public_v2c' + option group 'public' + option version 'v2c' + option secname 'ro' + +config group 'public_usm' + option group 'public' + option version 'usm' + option secname 'ro' + +config group 'private_v1' + option group 'private' + option version 'v1' + option secname 'rw' + +config group 'private_v2c' + option group 'private' + option version 'v2c' + option secname 'rw' + +config group 'private_usm' + option group 'private' + option version 'usm' + option secname 'rw' + +config view 'all' + option viewname 'all' + option type 'included' + option oid '.1' + +config access 'public_access' + option group 'public' + option context 'none' + option version 'any' + option level 'noauth' + option prefix 'exact' + option read 'all' + option write 'none' + option notify 'none' + +config access 'private_access' + option group 'private' + option context 'none' + option version 'any' + option level 'noauth' + option prefix 'exact' + option read 'all' + option write 'all' + option notify 'all' + +config system + option sysLocation 'office' + option sysContact 'bofh@example.com' + option sysName 'OpenMPTCProuter' + +config exec + option name 'filedescriptors' + option prog '/bin/cat' + option args '/proc/sys/fs/file-nr' + +config engineid + option engineidtype '3' + option engineidnic 'eth0' + +config snmpd 'general' + list network 'lan' + option enabled '0' + option ipv6cpipv4 '1' + diff --git a/luci-app-snmpd/root/etc/init.d/snmpd b/luci-app-snmpd/root/etc/init.d/snmpd new file mode 100755 index 000000000..238a0f34d --- /dev/null +++ b/luci-app-snmpd/root/etc/init.d/snmpd @@ -0,0 +1,348 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008 OpenWrt.org +START=50 + +USE_PROCD=1 +PROG="/usr/sbin/snmpd" + +CONFIGFILE="/var/run/snmpd.conf" + +snmpd_agent_add() { + local cfg="$1" + + config_get agentaddress "$cfg" agentaddress + [ -n "$agentaddress" ] || return 0 + echo "agentaddress $agentaddress" >> $CONFIGFILE +} + +snmpd_agentx_add() { + local cfg="$1" + echo "master agentx" >> $CONFIGFILE + config_get agentxsocket "$cfg" agentxsocket + [ -n "$agentxsocket" ] && echo "agentXSocket $agentxsocket" >> $CONFIGFILE +} + +snmpd_system_add() { + local cfg="$1" + config_get syslocation "$cfg" sysLocation + [ -n "$syslocation" ] && echo "sysLocation $syslocation" >> $CONFIGFILE + config_get syscontact "$cfg" sysContact + [ -n "$syscontact" ] && echo "sysContact $syscontact" >> $CONFIGFILE + config_get sysname "$cfg" sysName + [ -n "$sysname" ] && echo "sysName $sysname" >> $CONFIGFILE + config_get sysservice "$cfg" sysService + [ -n "$sysservice" ] && echo "sysService $sysservice" >> $CONFIGFILE + config_get sysdescr "$cfg" sysDescr + [ -n "$sysdescr" ] && echo "sysDescr $sysdescr" >> $CONFIGFILE + config_get sysobjectid "$cfg" sysObjectID + [ -n "$sysobjectid" ] && echo "sysObjectID $sysobjectid" >> $CONFIGFILE +} + +snmpd_com2sec_add() { + local cfg="$1" + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + config_get source "$cfg" source + [ -n "$source" ] || return 0 + config_get community "$cfg" community + [ -n "$community" ] || return 0 + echo "com2sec $secname $source $community" >> $CONFIGFILE +} + +snmpd_com2sec6_add() { + local cfg="$1" + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + config_get source "$cfg" source + [ -n "$source" ] || return 0 + config_get community "$cfg" community + [ -n "$community" ] || return 0 + echo "com2sec6 $secname $source $community" >> $CONFIGFILE +} + +snmpd_group_add() { + local cfg="$1" + config_get group "$cfg" group + [ -n "$group" ] || return 0 + config_get version "$cfg" version + [ -n "$version" ] || return 0 + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + echo "group $group $version $secname" >> $CONFIGFILE +} + +snmpd_view_add() { + local cfg="$1" + config_get viewname "$cfg" viewname + [ -n "$viewname" ] || return 0 + config_get type "$cfg" type + [ -n "$type" ] || return 0 + config_get oid "$cfg" oid + [ -n "$oid" ] || return 0 + # optional mask + config_get mask "$cfg" mask + echo "view $viewname $type $oid $mask" >> $CONFIGFILE +} + +snmpd_access_add() { + local cfg="$1" + config_get group "$cfg" group + [ -n "$group" ] || return 0 + config_get context "$cfg" context + [ -n $context ] || return 0 + [ "$context" == "none" ] && context='""' + config_get version "$cfg" version + [ -n "$version" ] || return 0 + config_get level "$cfg" level + [ -n "$level" ] || return 0 + config_get prefix "$cfg" prefix + [ -n "$prefix" ] || return 0 + config_get read "$cfg" read + [ -n "$read" ] || return 0 + config_get write "$cfg" write + [ -n "$write" ] || return 0 + config_get notify "$cfg" notify + [ -n "$notify" ] || return 0 + echo "access $group $context $version $level $prefix $read $write $notify" >> $CONFIGFILE +} + +snmpd_trap_hostname_add() { + local cfg="$1" + config_get hostname "$cfg" HostName + config_get port "$cfg" Port + config_get community "$cfg" Community + config_get type "$cfg" Type + echo "$type $hostname $community $port" >> $CONFIGFILE +} + +snmpd_trap_ip_add() { + local cfg="$1" + config_get host_ip "$cfg" HostIP + config_get port "$cfg" Port + config_get community "$cfg" Community + config_get type "$cfg" Type + echo "$type $host_ip $community $port" >> $CONFIGFILE +} + +snmpd_access_default_add() { + local cfg="$1" + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community default" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_access_HostName_add() { + local cfg="$1" + config_get hostname "$cfg" HostName + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community $hostname" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_access_HostIP_add() { + local cfg="$1" + config_get host_ip "$cfg" HostIP + config_get ip_mask "$cfg" IPMask + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community $host_ip/$ip_mask" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_pass_add() { + local cfg="$1" + local pass='pass' + + config_get miboid "$cfg" miboid + [ -n "$miboid" ] || return 0 + config_get prog "$cfg" prog + [ -n "$prog" ] || return 0 + config_get_bool persist "$cfg" persist 0 + [ $persist -ne 0 ] && pass='pass_persist' + config_get priority "$cfg" priority + priority=${priority:+-p $priority} + echo "$pass $priority $miboid $prog" >> $CONFIGFILE +} + +snmpd_exec_add() { + local cfg="$1" + + config_get name "$cfg" name + [ -n "$name" ] || return 0 + config_get prog "$cfg" prog + [ -n "$prog" ] || return 0 + config_get args "$cfg" args + config_get miboid "$cfg" miboid + echo "exec $miboid $name $prog $args" >> $CONFIGFILE +} + +snmpd_disk_add() { + local cfg="$1" + local disk='disk' + + config_get partition "$cfg" partition + [ -n "$partition" ] || return 0 + config_get size "$cfg" size + [ -n "$size" ] || return 0 + echo "$disk $partition $size" >> $CONFIGFILE +} + +snmpd_engineid_add() { + local cfg="$1" + + config_get engineid "$cfg" engineid + [ -n "$engineid" ] && echo "engineID $engineid" >> $CONFIGFILE + config_get engineidtype "$cfg" engineidtype + [ "$engineidtype" -ge 1 -a "$engineidtype" -le 3 ] && \ + echo "engineIDType $engineidtype" >> $CONFIGFILE + config_get engineidnic "$cfg" engineidnic + [ -n "$engineidnic" ] && echo "engineIDNic $engineidnic" >> $CONFIGFILE +} + +snmpd_sink_add() { + local cfg="$1" + local section="$2" + local community + local port + local host + + config_get host "$cfg" host + [ -n "section" -a -n "$host" ] || return 0 + # optional community + config_get community "$cfg" community + # optional port + config_get port "$cfg" port + port=${port:+:$port} + echo "$section $host$port $community" >> $CONFIGFILE +} + +append_parm() { + local section="$1" + local option="$2" + local switch="$3" + local _loctmp + config_get _loctmp "$section" "$option" + [ -z "$_loctmp" ] && return 0 + echo "$switch $_loctmp" >> $CONFIGFILE +} + +append_authtrapenable() { + local section="$1" + local option="$2" + local switch="$3" + local _loctmp + config_get_bool _loctmp "$section" "$option" + [ -z "$_loctmp" ] && return 0 + [ "$_loctmp" -gt 0 ] && echo "$switch $_loctmp" >> $CONFIGFILE +} + +snmpd_setup_fw_rules() { + local net="$1" + local zone + + zone=$(fw3 -q network "$net" 2>/dev/null) + + local handled_zone + for handled_zone in $HANDLED_SNMP_ZONES; do + [ "$handled_zone" = "$zone" ] && return + done + + json_add_object "" + json_add_string type rule + json_add_string src "$zone" + json_add_string proto udp + json_add_string dest_port 161 + json_add_string target ACCEPT + json_close_object + + HANDLED_SNMP_ZONES="$HANDLED_SNMP_ZONES $zone" +} + +start_service() { + [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE" + + config_load snmpd + + config_get_bool snmp_enabled general enabled 1 + [ "$snmp_enabled" -eq 0 ] && return + + procd_open_instance + + config_foreach snmpd_agent_add agent + config_foreach snmpd_agentx_add agentx + config_foreach snmpd_system_add system + config_foreach snmpd_com2sec_add com2sec + if [ "$(uci -q get snmpd.general.ipv6cpipv4)" = "1" ]; then + config_foreach snmpd_com2sec6_add com2sec + else + config_foreach snmpd_com2sec6_add com2sec6 + fi + config_foreach snmpd_group_add group + config_foreach snmpd_view_add view + config_foreach snmpd_access_add access + config_foreach snmpd_trap_hostname_add trap_HostName + config_foreach snmpd_trap_ip_add trap_HostIP + config_foreach snmpd_access_default_add access_default + config_foreach snmpd_access_HostName_add access_HostName + config_foreach snmpd_access_HostIP_add access_HostIP + config_foreach snmpd_pass_add pass + config_foreach snmpd_exec_add exec + config_foreach snmpd_disk_add disk + config_foreach snmpd_engineid_add engineid + append_parm trapcommunity community trapcommunity + config_foreach snmpd_sink_add trapsink trapsink + config_foreach snmpd_sink_add trap2sink trap2sink + config_foreach snmpd_sink_add informsink informsink + append_authtrapenable authtrapenable enable authtrapenable + append_parm v1trapaddress host v1trapaddress + append_parm trapsess trapsess trapsess + + procd_set_param command $PROG -Lf /dev/null -f + procd_set_param file $CONFIGFILE + procd_set_param respawn + + for iface in $(ls /sys/class/net 2>/dev/null); do + procd_append_param netdev "$iface" + done + + procd_open_data + + json_add_array firewall + config_list_foreach general network snmpd_setup_fw_rules + json_close_array + + procd_close_data + + procd_close_instance +} + +stop_service() { + [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE" + procd_set_config_changed firewall +} + +service_triggers(){ + local script=$(readlink "$initscript") + local name=$(basename ${script:-$initscript}) + + procd_open_trigger + procd_add_raw_trigger "interface.*" 2000 /etc/init.d/$name reload + procd_close_trigger + + procd_add_reload_trigger 'snmpd' +} + +service_started() { + procd_set_config_changed firewall +} diff --git a/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd b/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd index 6b875d1c9..8c6f6a547 100755 --- a/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd +++ b/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd @@ -7,4 +7,13 @@ if [ "$(uci -q get snmpd.general.network)" = "" ]; then commit snmpd EOF fi + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@snmpd[-1] + add ucitrack snmpd + set ucitrack.@snmpd[-1].init=snmpd + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache exit 0 \ No newline at end of file