Skip to content

Commit

Permalink
Merge pull request #2435 from johannaengland/docs/snmp-tunnels
Browse files Browse the repository at this point in the history
Document a recipe for establishing SNMP tunnels using socat/SSH
  • Loading branch information
johannaengland authored Mar 27, 2023
2 parents e94023b + 9d9a401 commit 9c3eaa5
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ found in the [HISTORY](HISTORY) file.

## [Unreleased]

### Added

#### Developer-centric features
- Document a recipe for establishing SNMP tunnels using socat/SSH ([#2426](https://github.com/Uninett/nav/issues/2426), [#2435](https://github.com/Uninett/nav/pulls/2435))

### Fixed

#### User-visible fixes
Expand Down
1 change: 1 addition & 0 deletions doc/hacking/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
extending-nav-locally
web-interface-customization
/api/searchproviders
snmp-tunnels
133 changes: 133 additions & 0 deletions doc/hacking/snmp-tunnels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
=========================================
Establishing SNMP tunnels using socat/SSH
=========================================

While developing new functionality related to SNMP collection in NAV,
a developer's workstation isn't necessarily attached to a network that
provides the developer with the necessary access to communicate with the
required set of switches/routers etc. For internal equipment, this is
usually solved by connecting via VPN, but sometimes, the devices one needs
to talk to is located at a customer site where there is no VPN access.

In the case of having SSH access to a Linux server at the customer premises,
that is allowed to communicate with the customer's switches and routers,
one can establish an SNMP tunnel to the customer's equipment using a
combination of SSH and socat.

This guide will document two ways to establish such an SNMP tunnel: one using
docker and one without.

Course of action - with docker
==============================

1. Copy the content of :file:`docker-compose.snmp.yml` into
:file:`docker-compose.override.yml` or later run docker-compose like this:
``docker compose -f docker-compose.yml -f docker-compose.snmp.yml up``.

2. Change the line ``command: 192.168.0.1 user@my-hop-host 10000`` to the ip
address or name of the device you want to reach, the relevant hop host and
whatever port you want to tunnel through.

3. Make sure that ssh key to the hop host is saved (you can test this by doing
``ssh user@my-hop-host``, it is saved if you're not prompted for a password).
If you haven't generated an SSH key yet you can run `ssh-keygen` and follow
the prompts. Afterwards you can use
``ssh-copy-id -i ~/.ssh/mykey user@my-hop-host`` to copy that key to the
server.

4. Now you can start nav.

5. In SeedDB: Add an SNMP management profile with the community for the device.

6. In SeedDB: Add an IP device with the IP "mydevice.mydomain" and the
management profile created in step 5. Click on "check connectivity", which should
be answering "ok".

Troubleshooting - with docker
=============================
When starting docker:

- the error message
``mydevice.mydomain_1 | bind [::1]:10000: Cannot assign requested address``
can be ignored, it should still work

- if the error message
``mydevice.mydomain_1 | 2023/02/21 13:36:11 socat[1744] E bind(5,
{AF=2 0.0.0.0:10000}, 16): Address already in use``
appears: change the port in the docker file

When adding IP device in SeedDB:

- if an error message appears go into the docker container using
``docker-compose exec nav /bin/bash`` and do ``ping mydevice.mydomain``. If that
works, then make sure you're using the right management profile, because
tunneling works.

Course of action - without docker
=================================

1. Forward a TCP port from your machine to another, which has the necessary
SNMP access level.

.. code-block:: sh
ssh -L 1161:localhost:1161 user@the-machine-with-access
2. Then, on that port, set up a UDP-to-TCP tunnel using socat on that machine:

.. code-block:: sh
socat tcp4-listen:1161,reuseaddr,fork UDP:ip-or-name-of-switch-to-talk-to:161
3. In a different terminal window, on your localhost, set up a socat
tunnel to tunnel UDP traffic on port 161 through the forwarded TCP port
(sudo is necessary because you need to bind to port 161, which only root can do):

.. code-block:: sh
sudo socat -T15 udp4-recvfrom:161,reuseaddr,fork tcp:localhost:1161
4. Finally, to test connectivity in another terminal window:

.. code-block:: sh
snmpwalk -v2c -c public localhost SNMPv2-MIB::system
(replace ``public`` with the respective community string if it differs)

5. When tunneling works you can add a new management profile with the
respective community string the switch uses to NAV.

6. Then add an IP device with that management profile and 127.0.0.1 as
IP address.

Troubleshooting - without docker
================================

- if in step 2 the error "Address already in use" appears, you can figure
out which process is using it by running

.. code-block:: sh
sudo netstat -aupn
(these flags are Linux specific, use

.. code-block:: sh
man netstat
to figure out which flags might be helpful on other operating systems).

Then kill the process by running

.. code-block:: sh
sudo kill process_id
If the process restarts on its own it might be that you need to kill its
parent process. This command can help identify the parent process:

.. code-block:: sh
ps axuwf

0 comments on commit 9c3eaa5

Please sign in to comment.