Forwarding SNMP ports over SSH using socat

Here is an example of the problem we need to solve: We have SSH access to a network, but want to access an SNMP agent in that network from a local client. We use SNMP here in this example, but it could be any other protocol that uses UDP, such as DNS or TFTP.

We’ll forward the SNMP traffic in a TCP port like this, with “socat” doing the UDP-in-TCP tunneling:

One could use netcat, and that works as long as the SNMP client uses the same source port. But it changes source port eventually, trust me! :-)

Instead, we use socat. It has a “fork” parameter, that does exactly what we want.

Install socat

socat needs to be installed on both the SSH client and server. On ubuntu/debian this is done with:

client$ sudo apt-get install socat
client$ ssh server
server$ sudo apt-get install socat

Stop the SSH client’s snmpd (if any)

Because we’ll want the SNMP manager to be able to query the SSH client as if it was the switch, SSH client’s snmpd (listening on UDP port 161), needs to be stopped. Again, on ubuntu/debian this is done with:

client$ sudo /etc/init.d/snmpd stop

Run socat on both SSH client and server

Now we’re ready to run this. You’ll need two terminals that start on the SSH client to sit around doing nothing (or use screen)

Terminal one:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

This creates the SSH forwarding of TCP port 10000 and runs socat on the server. Notice how the switch’s IP address is mentioned in the socat command line as “switch”.

Terminal two:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

That sets up socat on the client. That should do it.

Test it!

client$ snmpget -v2c -cpublic localhost sysName.0
SNMPv2-MIB::sysName.0 = STRING: switch

Yup, it works!


  1. Jose M. Abad says:

    Cool !
    I use it to grab MRTG data from my ISP router through SNMP tunnel. I did it effortlessly y straight forward.
    Thanks a lot for your post.

  2. Newbie here, I am using OpenSSH_4.1p1, OpenSSL 0.9.8 05 Jul 2005 on Cygwin, and the -L parameter shows different parameters for the -L switch:

    [-L [bind_address:]port:host:hostport]

  3. Rob says:


    Do you know of a way to achieve this without installing socat? I am trying to do exactly this to a setup I have at CERN but due to security restrictions I am unable to install anything on the gateway.

    Is there an executable version of socat, that I can run from a local AFS directory, that you know of? Would I have to run it as sudo anyway?


    • Peter says:

      Sure, you don’t *need* socat. You could write this from scratch in any language you like. Whether or not you can find a statically linked socat executable depends e.g. on you OS, distribution. Basically, I have no idea. I haven’t needed it yet.

  4. Chad says:

    I stumbled upon this little gem while trying to work out a remote maintenance solution and it “works” but there’s one little thing that would need to be added/changed in order for it to work correctly. The equipment we are maintaining actually needs both UDP 161 AND UDP 162 in order to work correctly. I’ve tried a few variations to your solution but I can’t seem to get it to work right. Can you offer any suggestions or corrections to allow for both snmp ports to tunnel through ssh?

    • Peter says:

      :-) A little clarification here…

      Port 161 is for SNMP get, get-next, get-bulk, set and their responses. The SNMP Manager initiates the conversation by “sending a request”. The SNMP agent handles that request and sends a response. My example above only deals with port 161.

      Port 162 is for SNMP traps and informs, i.e. asynchronous notifications. Think “alerts” or “alarms” that the equipment sends to a manager, when the equipment discovers something is wrong. First you’ll need to configure the equipment to actually send something you “server”!!! (As is often the case, tshark is your friend). If you then still want to forward port 162, first you’ll need some running SNMP trap daemon (snmptrapd in Linux) that can receive and handle SNMP traps and informs (on the “client” side!) . On my debian & ubuntu boxes, it can’t be localhost, since we need to stop “snmp”, which is both snmpd and snmptrapd, in order for port 161 port forwarding to work.

      Once you have a trap receiver running (say on the host “trapreceiver”), the original SSH port forwarding command could look like this instead of the “ssh -L …” command above:

      ssh -L 10000:localhost:10000 -R 10001:localhost:10001 server

      Then, in addition to the other socat commands above:

      On the client machine, run:
      socat -T10 TCP4-LISTEN:10001,fork UDP4:trapreceiver:162

      And on the server machine run:
      sudo socat UDP4-LISTEN:162,fork TCP4:localhost:10001

      I haven’t tried this myself, but I’m pretty sure it will work. The tricky question is what to do with the traps once they’re received; what do you actually want to do with the traffic you get on trapreceiver’s port 162. By default snmptrapd doesn’t do anything useful. It’ll depend on the equipment and your use case.

Leave a Reply