[PYTHON] UDP port forwarding

Introduction

I often see TCP port forwarding, but I don't see UDP port forwarding because it may have limited uses. This time, I would like to do UDP port forwarding while studying UDP and sockets.

environment

OS X El Capitan Python 2.7.11 snmpwalk 5.6.2.1

Implement in Python

udp_portforwarder.py


import socket
UDP_IP_LISTEN = "192.168.1.12"
UDP_PORT_LISTEN = 161
UDP_IP_TO = "192.168.1.119"
UDP_PORT_TO = 161

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP_LISTEN, UDP_PORT_LISTEN))

src_port = 0

while True:
  data, (host, port) = sock.recvfrom(4096)

  # receive from remote server
  if src_port != 0 and host != UDP_IP_LISTEN:
    sock.sendto(data, (UDP_IP_LISTEN, src_port))
  # send to remote server
  else:
    src_port = port
    sock.sendto(data, (UDP_IP_TO, UDP_PORT_TO))
   
  print 'forwarded', host, port

Commentary 1 Since we want to target UDP, specify SOCK_DGRAM for socket.

Commentary 2 Since the response from the request source and the response from the destination and two types of packets arrive at the bound port by recvfrom, conditional branching is performed at the source address.

Commentary 3 Since it is necessary to return it to the requesting port, the requesting port number is stored in src_port when the packet from the requesting source arrives.

Operation check

  1. Execute tshark udp (to check packet details)
  2. Run sudo python udp_capture_portforwarder_remote.py
  3. Execute snmpwalk -c public -v 1 192.168.1.12

Operation result

snmpwalk


snmpwalk -c public -v 1 192.168.1.12
butada-mac:python_udp_capture_test butada$ snmpwalk -c public -v 1 192.168.1.12
SNMPv2-MIB::sysDescr.0 = STRING: Darwin macbook.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.16
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (454525) 1:15:45.25
SNMPv2-MIB::sysContact.0 = STRING: SysAdmin
SNMPv2-MIB::sysName.0 = STRING: SystemName
SNMPv2-MIB::sysLocation.0 = STRING: data centre A
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (4) 0:00:00.04
SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBC
<Omitted>

udp_capture_portforwarder_remote.py


$ sudo python udp_capture_portforwarder_remote.py 
sent to remote snmp
forwarded 192.168.1.12 57598
received from remote snmp
forwarded 192.168.1.119 161
sent to remote snmp
forwarded 192.168.1.12 57598
received from remote snmp
forwarded 192.168.1.119 161
sent to remote snmp
forwarded 192.168.1.12 57598
received from remote snmp
forwarded 192.168.1.119 161
sent to remote snmp
forwarded 192.168.1.12 57598
received from remote snmp
forwarded 192.168.1.119 161
sent to remote snmp
forwarded 192.168.1.12 57598
received from remote snmp
forwarded 192.168.1.119 161
<Omitted>

tshark


$ tshark udp
1897 2373.448956 192.168.1.12 -> 192.168.1.119 SNMP 82 get-next-request 1.3.6.1.2.1
1898 2373.450958 192.168.1.119 -> 192.168.1.12 SNMP 215 get-response 1.3.6.1.2.1.1.1.0
1899 2373.451207 192.168.1.12 -> 192.168.1.119 SNMP 85 get-next-request 1.3.6.1.2.1.1.1.0
1900 2373.453134 192.168.1.119 -> 192.168.1.12 SNMP 95 get-response 1.3.6.1.2.1.1.2.0
1901 2373.453259 192.168.1.12 -> 192.168.1.119 SNMP 85 get-next-request 1.3.6.1.2.1.1.2.0
1902 2373.454931 192.168.1.119 -> 192.168.1.12 SNMP 88 get-response 1.3.6.1.2.1.1.3.0
1903 2373.455061 192.168.1.12 -> 192.168.1.119 SNMP 85 get-next-request 1.3.6.1.2.1.1.3.0
1904 2373.456796 192.168.1.119 -> 192.168.1.12 SNMP 93 get-response 1.3.6.1.2.1.1.4.0
<Omitted>

result

I confirmed that UDP port forwarding can be done using snmpget. I couldn't put the concrete result here, but I was able to confirm that IPMI can be port-forwarded in the same way using ipmiutil.

application

SNMP packet capture & replay

I applied this technique to capture packets and create simple stubs. In other words, the capture is recorded when forwarding, and the stub is based on the captured content and returns the recorded response without forwarding. http://qiita.com/butada/items/77af324c2a1bb880f101

reference

http://memo.saitodev.com/home/python_network_programing/ http://stackoverflow.com/questions/11350145/are-there-simple-descriptions-on-port-forwarding-using-python http://stackoverflow.com/questions/2694212/socket-set-source-port-number

Recommended Posts

UDP port forwarding
About WOL port forwarding
Try and learn iptablse, port forwarding
Linux ssh port forwarding (tunnel) settings
Port forwarding your web server using iptables
Including docker-nginx port forwarding on AWS Linux 2
Binding port forwarding to unix domain socket works