03-12-2021 10:38 PM - edited 03-13-2021 11:08 PM
Co-Authored by @Pooja Yadav
This document describes the SNMP Configuration, Verification and Troubleshooting on ASA appliances.
Knowledge of SNMP and basics of ASA
There are no specific requirements for this document.
ASAv running software 9.12(3)12
Snmpwalk (Part of SNMP package on Linux)
SolarWinds Network Performance Monitor (Network Management System)
The information in this document was created from the devices in a specific lab environment. All of the devices used in this document started with a cleared (default) configuration. If your network is live, ensure that you understand the potential impact of any command.
Simple Network Management Protocol (SNMP) is an application layer communication protocol that lets you monitor managed network devices. A typical SNMP implementation includes three components:
SNMP agent—The SNMP agent is the SNMP process that resides on the managed device and communicates with the NMS. The SNMP agent exchanges network management information with the SNMP manager software running on an NMS, or host. The agent responds to requests for information and actions from the manager. The agent also controls access to the agent’s MIB, the collection of objects that can be viewed by the SNMP manager.
Traps are used when the Device needs to alert the network management software of an event without being polled. SNMP traps allow an agent to send device information to the manager over Port UDP 162. Traps ensure that the NMS gets information if a certain event occurs on the device that needs to be recorded without being polled by the NMS first.
SNMP has three versions: SNMPv1, SNMPv2c, and SNMPv3. The ASA provides support for network monitoring using SNMP versions 1, 2c, and 3 and supports the use of all three versions simultaneously.
SNMPv1
SNMPv1 is the initial version of SNMP and provides the minimum network management functions. SNMPv1 provides authentication based on community names, causing low security. In addition, a limited number of error codes are returned in packets. SNMPv1 supports noAuthnoPriv security level.
noAuthnoPriv- Uses a community string match for authentication
SNMPv2c
SNMPv2c also provides authentication based on community names. Compared with SNMPv1, SNMPv2c includes a bulk retrieval mechanism and detailed error message reporting to management stations. It's improved error handling support includes expanded error codes that distinguish different types of errors; these conditions are reported through a single error code in SNMPv1. SNMPv2 also supports noAuthnoPriv security level.
noAuthnoPriv- Uses a community string match for authentication.
SNMPv3
SNMPv3 has a security model in which an authentication strategy is set up for a user and the group in which the user resides. A security level is the permitted level of security within a security model. A combination of a security model and a security level determines which security mechanism is employed when handling an SNMP packet.
The SNMPv3 supports the following set of security levels:
Issue the following commands under config terminal:
snmp-server enable snmp-server host <interface name> <IP address of SNMP server> community <community string> version 2c |
The SNMP agent running on the ASA interface lets you monitor the devices through network management systems (NMSs). Here we have used SolarWinds Network Performance Monitor for the demonstration purpose.
Let’s get started with adding ASA to the SolarWinds Server and monitoring the node.
Step 1: Log in to the SolarWinds dashboard.
Step 2: Click on Manage Nodes.
Step 3: Click on Add Node.
Step 4: Defining the node by specifying the node i.e. ASA details namely IP Address / Hostname, SNMP version and community string.
Step 5: After clicking the TEST, the server tries to validate the ASA for polling.
If the test is successful, the node can be successfully onboarded.
Step 6. Click NEXT until you reach the OK, ADD NODE.
The node with the hostname “ciscoasa” has been successfully added.
Verify SNMPv2c on ASA
1. CLI configuration verification
ciscoasa# show run snmp-server |
If you want to see the actual string, then get into ‘enable’ mode and type the command shown below:
ciscoasa# more system:running-config | in snmp-server |
ciscoasa# show snmp-server statistics |
ciscoasa# show snmp-server engineID Local SNMP engineID: 80000009fe44f33fa37704d6db48f42eb0f465ec66cd0c53fe |
ciscoasa# show snmp-server host host ip = 10.106.62.62, interface = mgmt community ***** version 2c |
2. Test SNMP polling by performing SNMPwalk
You can verify if you are able to poll the ASA by performing Snmpwalk from SNMP configured host. Here we are testing using OID 1.3.6.1.2.1.1.3, you can use any OID from ASA listed under “show snmp-server oidlist”.
[root@localhost ~]# snmpwalk -v2c -c cisco123 10.106.64.23 1.3.6.1.2.1.1.3 |
3. Take captures on ASA
You can verify if the ASA is receiving the SNMP traffic and responding by configuring captures on ASA. Additionally, export the captures in Wireshark for analysis. Look for OID, version and the response. Here is the output of the capture taken on ASA (configured with SNMPv2) while testing and validating the ASA by SNMP server (as performed in the above steps, while adding the ASA to SolarWinds server).
ciscoasa# capture snmpv2 interface mgmt match udp host 10.106.64.23 eq snmp host 10.106.62.62
ciscoasa# show capture |
ciscoasa# show capture snmpv2 2 packets captured 1: 10:03:19.873749 10.106.62.62.54658 > 10.106.64.23.161: udp 44 |
Below is the analysis of captures exported in Wireshark. You can see NMS is sending the get-request packet to the ASA and ASA is responding with get-response data.
Here the NMS is polling the ASA with OID 1.3.6.1.2.1.1.2 (sysObjectID).
NOTE: The ASA supports SNMP read-only access through issuance of a GET request. SNMP write access is not allowed, so you cannot make changes with SNMP. In addition, the SNMP SET request is not supported.
4. Verify the SNMP traps
If traps are enabled then it can be verified by taking captures. Here for the demonstration, we are triggering an SNMP trap by shutting down one of the interfaces of ASA and followed by bringing it up.
You can see below that ASA sends traps to the SNMP server when an event of interface going down and coming up has occurred.
ciscoasa(config)# snmp-server enable traps snmp linkup linkdown
ciscoasa(config)# capture trap interface mgmt match udp host 10.106.64.23 host 10.106.62.62 eq 162
ciscoasa(config)# int g0/2
ciscoasa(config)# show capture trap 2 packets captured 1: 13:57:58.736091 10.106.64.23.162 > 10.106.62.62.162: udp 122 |
SNMPv2 is very simple to configure but uses plain text community string (a password that devices will need to talk to each other and transfer information when SNMP requests occur) that could be sniffed from network traffic. Therefore, SNMPv3 is recommended for better security as it supports authentication and privacy (encryption).
Issue the following commands under config terminal:
snmp-server group <Group Name> v3 priv snmp-server user <Username> <Group Name> v3 auth sha <Authentication Password> priv aes 128 <Privacy Password> snmp-server host <ASA Interface> <IP of Server> version 3 <username> |
Here we have performed the following configuration for demonstration of SNMPv3 and will be using the same authentication and encryption passwords to decrypt the polling traffic captured on ASA.
snmp-server group admin v3 priv
snmp-server user alice admin v3 auth sha cisco123 priv aes 128 cisco321
snmp-server host outside 10.106.62.62 version 3 alice
Step 1-3 will be same as previous while adding ASA node to the SNMP server. However, defining a node will need additional details of authentication and encryption.
Step 4: Defining the node by specifying the node details namely IP Address/Hostname, SNMP version, port, SNMPv3 username, SNMPv3 Context (If multi-context node), Authentication and Encryption/Privacy methods and passwords.
Step 5: After clicking the TEST, the server tries to validate the node for polling. As ASA doesn’t support SNMP write access i.e. you cannot make changes with SNMP hence SNMPv3 write credentials need not be set here.
If the test is successful, the node can be successfully onboarded.
Step 6: Click NEXT until you reach the OK, ADD NODE same as done previously during SNMPv2 set up. The node will be successfully added to the SNMP server.
Verify SNMPv3 on ASA
1. CLI configuration verification
CiscoASA# show run snmp-server |
CiscoASA# show snmp-server statistics 4377 SNMP packets input 0 Bad SNMP version errors 0 Unknown community name 0 Illegal operation for community name supplied 0 Encoding errors 4334 Number of requested variables 0 Number of altered variables 7 Get-request PDUs 4327 Get-next PDUs 0 Get-bulk PDUs 0 Set-request PDUs (Not supported) 4399 SNMP packets output 0 Too big errors (Maximum packet size 1500) 0 No such name errors 0 Bad values errors 0 General errors 4377 Response PDUs 22 Trap PDUs |
CiscoASA# show snmp-server engineID |
CiscoASA# show snmp-server host |
CiscoASA# show snmp-server oidlist ------------------------------------------------- |
2. Test SNMP polling by performing SNMPwalk
You can verify if you are able to poll the ASA by performing Snmpwalk from any SNMP configured host. Here we are testing using OID 1.3.6.1.4.1.9.9.147.1.2.1.1.1.4, you can use any OID from ASA listed under “show snmp-server oidlist”.
root@localhost ~]# snmpwalk -v3 -l authpriv -u bob -a SHA -A "cisco123" -x AES -X "cisco123" 10.106.48.223 1.3.6.1.4.1.9.9.147.1.2.1.1.1.4 |
3. Take captures on ASA
You can verify if the ASA is receiving the SNMP traffic and responding by configuring captures. Additionally, export the captures in Wireshark for analysis. Look for the OID, version and the response. Here is the output of the capture taken on ASA (configured with SNMPv3) while testing and validating the ASA by SNMP server (as performed in the above steps while adding the ASA to the SolarWinds server).
CiscoASA#capture snmpv3 interface outside match udp host 10.106.48.223 eq snmp host 10.106.62.62
CiscoASA# show capture 6 packets captured 1: 11:12:52.399851 10.106.62.62.59619 > 10.106.48.223.161: udp 66 |
Below is the analysis of captures exported in Wireshark
Here, you can see the encrypted PDUs as SNMPv3 supports authentication and encryption.
In order to see the details of the packet first, you need to decrypt it. Select the packet and Right-Click. Protocol preferences-> Open Simple Network Management Protocol preferences.
The Preferences dialog box will open. Click on Edit.
Specify the Engine ID and Enter the credentials Username, Password and select the Authentication model and Privacy Protocol that we mentioned while configuring the SNMPv3.
Et voila!
Encrypted get-request
Decrypted get-request
Encrypted get-response
Decrypted get-response
4. Running debug ( CPU INTENSIVE !)
CiscoASA# debug snmp packet
CiscoASA# debug snmp error |
The Wireshark captures for SNMPv2, SNMPv3 and SNMP trap are attached.
Use the below details for decrypting the SNMPv3 capture.
SNMP engineID: 80000009fe2346c0ac12ac795c22fa2c27675a4f173cc56328
Username: alice
Authentication Model: SHA1
Password: cisco123
Privacy protocol: AES
Privacy password: cisco123
Net-SNMP is a suite of applications used to implement SNMP v1, SNMP v2c and SNMP v3 using both IPv4 and IPv6. Net-SNMP is housed on SourceForge and is usually in the top 100 projects in the sourceforge ranking system. We leverage the Net-SNMP as provided by Wind River Linux on our FXOS.
The software that handles SNMP requests on a network node is called an agent. The Net-SNMP agent (snmpd) is responsible for handling incoming requests passed to it from the Net-SNMP library's transport and processing layers. The agent is made up of many pieces. These pieces include parts from multiple libraries and different parts of the agent itself. It usually interacts with libraries, the network, plugins, other processes, the file system, the local OS, and the local OS's kernel.
Post 9.14 release, the SNMP implementation on ASA is migrated from earlier offering of SR-SNMP to the Net-SNMP.
Goals of the new architecture
Typically following logs are requested
debug menu netsnmp <command>
Commands options are:
1) Show disconnect agentx sockets.
2) Show registered alarms.
3) Show snmp sessions.
4) Show snmp static config.
5) Enable sub agent config log.
6) Disable sub agent config log.
7) Show snmp dynamic config.
9) Enable master agent logging based on token.
- debug menu netsnmp 9 <token> —-> to enable logging only for the token provided
- debug menu netsnmp 9 all —-> to enable full logging
10) Show active connections.
11) Show command line arguments.
Sample outputs for these Command option
1) Show disconnect agentx sockets:
ciscoasa# debug menu netsnmp 1
**************************Disconnect arr*******************************
Callback for agentx_reopen_session:0x0000556ebd18a920
Callback for agentx_check_session: 0x0000556ebd1893d0
2) Show registered alarms
ciscoasa# debug menu netsnmp 2
****************************alarms*************************************
Alarm 1: ss:0x00007f0b281d1a60, tcp://127.0.0.1:2000vcid 0. flags:0x21 cb:0x0000556ebd1893d0, running 1
The alarms here refers to the connections between snmp master-agent and sub-agent
3) Show snmp sessions
ciscoasa# debug menu netsnmp 3
****************************Sessions***********************************
ss:0x00007f0b281d1a60 [alarm:1] agentx tcp://127.0.0.1:2000
ss:0x00007f0b280c7c40 [alarm:-1] agentx
ss:0x00007f0b280c5630 [alarm:-1] agentx
4) Show the SNMP static config
ciscoasa# debug menu netsnmp 4
####
# snmpd.conf for Context : 0, Version : 3.
####
[snmp] persistentDir /var/net-snmp/agent2000
view all_view included .1
agentAddress 169.254.1.2:161,udp6:[fd00:0:0:1::2]:161
[snmp] clientaddr6 fd00:0:0:1::2
[snmp] clientaddr 169.254.1.2
authtrapenable 1
exactEngineID 0x80000009fe48d5bae52c1f3f2d848dcc1d59169b38506db88a
access public "" v1 noAuthNoPriv exact all_view none none
access public "" v2c noAuthNoPriv exact all_view none none
group public v1 public
group public v2c public
com2sec public 192.168.0.87/32public
trap2sink 192.168.0.87:162public
------------------------------------------------------------
setserialno 1863464976
engineBoots 51
oldEngineID 0x80000009fe48d5bae52c1f3f2d848dcc1d59169b38506db88a
------------------------------------------------------------
tcp 0 0 127.0.0.1:2000 0.0.0.0:* LISTEN 1393/snmpd
tcp 0 0 127.0.0.1:2000 127.0.0.1:38803 ESTABLISHED 1393/snmpd
udp 0 0 169.254.1.2:161 0.0.0.0:* 1393/snmpd
udp 0 0 169.254.1.2:52214 0.0.0.0:* 1393/snmpd
udp6 0 0 fd00:0:0:1::2:161 :::* 1393/snmpd
tap_nlp Link encap:Ethernet HWaddr 86:6d:87:80:52:31
inet6 addr: fd00:0:0:1::2/64 Scope:Global
inet6 addr: fe80::846d:87ff:fe80:5231/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:412 (412.0 B) TX bytes:2728 (2.6 KiB)
------------------------------------------------------------
root 1393 1 0 09:26 ? 00:00:00 /usr/sbin/snmpd --master=agentx -x tcp:2000 -C -c /usr/share/snmp/agent2000/snmpd.conf,/var/net-snmp/agent2000/snmpd.conf -D -agentx/master -A -p /var/run/snmpd2000.pid-Lf /mnt/disk0/log/ma_ctx2000.log -I-ifTable -I-ipNetToPhysicalTable -I-ipv6InterfaceTable -I-ifXTable -I-ipAddressTable -I-ipAd dressPrefixTable -I-sysORTable -I-ipAddressPrefixTable -I-ipDefaultRouterTable -I-ipSystemStatsTable -I-ipv6ScopeZoneIndexTable -I-ipIfStatsTable -I-ipCidrRouteTable -I-ine tCidrRouteTable -I-tcpConnectionTable -I-tcpListenerTable -I-udpEndpointTable -I-inetNetToMediaTable -I-snmpNotifyTable -I-snmpTargetAddrEntry -I-snmpTargetParamsEntry -I-s nmpNotifyTable_data -I-snmpNotifyFilterTable -I-at -I-ip -I-tcp -I-icmp -I-udp -I-tcpTable -I-udpTable -I-system_mib -I-var_route -I-ip_scalars -I-target_counter_5_5 -I-smu x -I-cpu -I-hw_mem -I-cpu_linux -I-interface -I-ipv6
5) Enable sub agent config log:
ciscoasa# debug menu netsnmp 5
The logs will be displayed on the console.
6) Disable sub agent config log:
ciscoasa# debug menu netsnmp 6
7) Show snmp dynamic config:
ciscoasa# debug menu netsnmp 7
agentAddress 169.254.1.2:161,udp6:[fd00:0:0:1::2]:161
usmUser 1 2 0x80000009fee97eb6e22a1e40014976bace911e44c325d40337 "uspriv1" "uspriv1" NULL .1.3.6.1.6.3.http://10.1.1.30x15c27c5534f0a4ce0ce45923b7a1b865da1584d2 .1.3.6.1.6.3.http://10.1.2.40x15c27c5534f0a4ce0ce45923b7a1b865 0x
group privg usm uspriv1
ciscoasa# debug menu netsnmp 8
9) Enable master agent logging:
ciscoasa# debug menu netsnmp 9 snmp_agent
trace: netsnmp_add_varbind_to_cache(): snmp_agent.c, 2513:
snmp_agent: tp->start SNMPv2-MIB::sysDescr, tp->end SNMPv2-MIB::sysObjectID,
Full logging can be enabled using:
ciscoasa# debug menu netsnmp 9 all
The logs will be available at the path disk0:/log/ma_ctx2000.log
10) Show active connections:
ciscoasa# debug menu netsnmp 10
------------------------------------------------------------
tap_nlp Link encap:Ethernet HWaddr 1e:4d:f6:17:ec:fb
inet6 addr: fd00:0:0:1::2/64 Scope:Global
inet6 addr: fe80::1c4d:f6ff:fe17:ecfb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5 errors:0 dropped:0 overruns:0 frame:0
TX packets:34 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:370 (370.0 B) TX bytes:2592 (2.5 KiB)
------------------------------------------------------------
tcp 0 0 http://127.0.0.1:5757 0.0.0.0:* LISTEN 1192/lina
tcp 0 0 http://127.0.0.1:5759 0.0.0.0:* LISTEN 1192/lina
tcp 0 0 http://127.0.0.1:2000 0.0.0.0:* LISTEN 1301/snmpd
tcp 0 0 http://127.0.0.1:2710 0.0.0.0:* LISTEN 1157/python
tcp 0 69 http://127.0.0.1:47828 http://127.0.0.1:2710ESTABLISHED 1192/lina
tcp 0 0 http://127.0.0.1:46420 http://127.0.0.1:2000ESTABLISHED 1192/lina
tcp 0 0 http://127.0.0.1:2000 http://127.0.0.1:46420ESTABLISHED 1301/snmpd
tcp 0 0 http://127.0.0.1:2710 http://127.0.0.1:47828ESTABLISHED 1157/python
udp 0 0 http://169.254.1.2:16 10.0.0.0:* 1301/snmpd
udp6 0 0 fd00:0:0:1::2:161 :::* 1301/snmpd
11) Show command line arguments:
ciscoasa# debug menu netsnmp 11
snmp pid: 1301
/usr/sbin/snmpd --master=agentx -x tcp:2000 -C -c /usr/share/snmp/agent2000/snmpd.conf,/var/net-snmp/agent2000/snmpd.conf -D -agentx/master -A -p /var/run/snmpd2000.pid -Lf /mnt/disk0/log/ma_ctx2000.log -I-snmpMPDStats -I-system_mib -I-sysORTable -I-vacm_vars -I-setSerialNo -I-at -I-ip -I-tcp -I-icmp -I-udp -I-ipv6 -I-snmpNotifyTable -I-snmpNotifyFilterProfileTable -I-snmpTargetAddrEntry -I-snmpTargetParamsEntry -I-target_counter_5_5 -I-target_counters -I-vacm_contex -I-var_route -I-tcpTable -I-udpTable -I-ip_scalars -I-snmpNotifyTable_data -I-snmpNotifyFilterTable_data_storage -I-snmpNotifyFilterTable -I-snmpNotifyFilterProfileTable_data -I-snmpTargetAddrEntry_data -I-snmpTargetParamsEntry_data -I-ifTable -I-ifXTable -I-ipAddressTable -I-ipAddressPrefixTable -I-ipDefaultRouterTable -I-inetNetToMediaTable -I-ipSystemStatsTable -I-ipv6ScopeZoneIndexTable -I-ipIfStatsTable -I-ipCidrRouteTable -I-inetCidrRouteTable -I-tcpConnectionTable -I-tcpListenerTable -I-udpEndpointTable -I-interface -I-ipNetToPhysicalTable -I-smux -I-ipv6InterfaceTable
This command displays the process id of the snmpd process along with all the command line arguments supplied to it. The options are:
-x ADDRESS: Listens for AgentX connections on the specified address
-C: Do not read any configuration files except the ones optionally specified by the -c option.
-c FILE: Read FILE as a configuration file (or a comma-separated list of configuration files)
-Lf: Specify the file where logging output should be directed
-A: Append to the log file rather than truncating it.
-p: Save the process ID of the daemon in FILE.
-I: Specifies which modules should (or should not) be initialized when the agent starts up. If the module name is preceded with a ’-’, it should not be started.
This output will also be available as part of the debug menu netsnmp 4 command.
ciscoasa# show snmp-server statistics
ciscoasa# show snmp-server statistics
13 SNMP packets input
0 Bad SNMP version errors
0 Unknown community name
0 Illegal operation for community name supplied
0 Encoding errors
13 Number of requested variables
0 Number of altered variables
0 Get-request PDUs
13 Get-next PDUs
0 Get-bulk PDUs
0 Set-request PDUs (Not supported)
35 SNMP packets output
0 Too big errors (Maximum packet size 1500)
0 No such name errors
0 Bad values errors
0 General errors
13 Response PDUs
22 Trap PDUs
The show snmp-server statistics command is useful to pinpoint SNMP issues. It shows the number of SNMP packets received and sent, classified by the type of packet and the error condition (if present). Comparing the number of packets received with the number of packets sent can show potential issues.
https://snmp.cloudapps.cisco.com/Support/SNMP/do/BrowseOID.do?local=en
https://www.solarwinds.com/network-performance-monitor/use-cases/snmp-monitoring
Nice work. Thanks for sharing with the community.
Thanks @Marvin Rhoads
I am looking to move from ASA based load balancing with Cert + Username & Password authentication to SAML based authentication which means we can no longer use ASA based load balancing and wanted the GSLB F5 to query the ASA via SNMP for device load and determine which is the least loaded ASA in the pool to return in the DNS response.
Which "number" in regards to load is worth monitoring, as I can't seem to find the "Device Load" value from
show vpn-sessiondb summary
---------------------------------------------------------------------------
VPN Session Summary
---------------------------------------------------------------------------
Active : Cumulative : Peak Concur : Inactive
----------------------------------------------
AnyConnect Client : 478 : 25515 : 660 : 76
SSL/TLS/DTLS : 478 : 25515 : 660 : 76
---------------------------------------------------------------------------
Total Active and Inactive : 554 Total Cumulative : 25515
Device Total VPN Capacity : 2500
Device Load : 22%
------------------------------------------------------------------------
Is the 22% just the mathematical calculation of 554/2500 as it seems like it to me. I couldn't find anywhere in the SNMP MIB that shows that number.
The two SNMP OIDs as per the above post I think are worthwhile is the VPN session count and cumulative CPU load.
VPN Session Count:
snmpget -c public -v 2c 192.168.100.1 -OS .1.3.6.1.4.1.9.9.392.1.3.1.0
CISCO-REMOTE-ACCESS-MONITOR-MIB::crasNumSessions.0 = Gauge32: 1 Sessions
And the highest value from cumulative index from the 1 minute CPU Load. So on my 5506-X with a single CPU it would be CPU 3 as that is the highest value from snmpwalk.
snmpwalk -c public -v 2c 192.168.100.1 -OS .1.3.6.1.4.1.9.9.109.1.1.1.1.7
CISCO-PROCESS-MIB::cpmCPUTotal1minRev.1 = Gauge32: 1 percent
CISCO-PROCESS-MIB::cpmCPUTotal1minRev.2 = Gauge32: 1 percent
CISCO-PROCESS-MIB::cpmCPUTotal1minRev.3 = Gauge32: 1 percent
So to query just that CPU I would use:
snmpget -c public -v 2c 192.168.100.1 -OS .1.3.6.1.4.1.9.9.109.1.1.1.1.7.3
CISCO-PROCESS-MIB::cpmCPUTotal1minRev.3 = Gauge32: 1 percent
Or is there a better metric to query via SNMP to see the overall system and VPN load of the appliance to determine which is the least loaded ASA?
Thanks for sharing such great information. It is beneficial to me. I always search to read quality content and finally, I found this in your post. keep it up!
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: