uhppoted / uhppoted-tunnel

Tunnels UDP packets between a pair of machines to enable UHPPOTE controller remote access
MIT License
6 stars 1 forks source link

Pi Configuration as secure wireless tunnel #3

Closed GWustenstein closed 1 year ago

GWustenstein commented 2 years ago

Posting this as a separate issue as a placeholder to document and resolve configuration related matters...

Problem statement: In the following use case, an access controller is placed in a difficult to reach location, it may be easier to get power to the location than it is to run physical ethernet to it, for example an outbuilding, electric gate, etc. One could simply employ a wireless bridge to the site, however such devices are subject to well-known exploits and port 60000 is wide open for the controllers.

Solution: Instead, a Raspberry Pi (or equiv.) is applied as the tunnel endpoint co-located to the controller with the physical ethernet connected to the controller (--out udp/broadcast), and the wifi interface acting as a secure WAN (ideally as --in tls/client with client certs listed with the server's CA)

Issues:

uhppoted commented 2 years ago

Mmm, for a scenario like that I would probably be reaching for a small switch and an external wifi router with a firewall (e.g. something like an Ubiquiti or https://teklager.se + pfSense) - but it does add significantly to the cost.

I'll look into it - it's probably immaterial, but which particular RaspberryPi model are you using?

GWustenstein commented 2 years ago

The principal issue with using a switch: If you put the access controller on the same subnet as the wifi, you now have unsecured udp flying around the ethers. Gain access to the wifi from the comfort of a car outside and you pretty much have assume physical entry is possible from there.

In this case mentioned in OP, a 4b has a gig-e on one end and a wifi. But any pi with a spare usb can be outfitted with a wifi dongle to accomplish a similar task. Bind the -out to eth0 and lock down wlan0 to tls and ssh/vnc with lengthy keys and your remaining worries are mostly physical security and not being lazy with updates or the keys.

uhppoted commented 1 year ago

Hi,

Does this still need looking into or was it an artifact of the Debian Bulleye upgrade?

uhppoted commented 1 year ago

Closing this - seems like more of a Raspberry Pi system issue. Feel free to reopen if necessary

GWustenstein commented 1 year ago

Agreed, I have yet to getting around to writing a recipe for setting up the router config in a way to configure an interface as a specific UDP tunnel destination. Though I completely hate the idea of unprotected UDP flying around the network, it will have to do for now. The end goal is to have a pi or similar dual ethernet device located inside the locked box with the access controller, configured as a secure tunnel; Only big-key encrypted traffic runs external to/from the box.

uhppoted commented 1 year ago

Actually I'm going to reopen this because it looks interesting!

Turns out there's a SO_BINDTODEVICE socket option (Linux only) which lets you bind to a specific interface. Wasn't aware of it and it's not cross platform but for most part anything running tunnel in this mode will be running on Linux anyway.

If you want to do it without waiting for my fix, there are also ways to do it using just the system:

uhppoted commented 1 year ago

Working notes:

  1. https://unix.stackexchange.com/questions/648718/force-programs-bind-to-an-interface-not-ip-address
  2. https://unix.stackexchange.com/questions/210982/bind-unix-program-to-specific-network-interface
  3. https://superuser.com/questions/241178/how-to-use-different-network-interfaces-for-different-processes
  4. https://groups.google.com/g/golang-nuts/c/ez7iAmT7ddE
  5. https://stackoverflow.com/questions/20616029/os-x-equivalent-of-so-bindtodevice
  6. https://stackoverflow.com/questions/2065495/using-a-specific-network-interface-for-a-socket-in-windows/2080495#2080495
  7. https://stackoverflow.com/questions/1207746/problems-with-so-bindtodevice-linux-socket-option
  8. https://pkg.go.dev/syscall#BindToDevice
  9. https://funwithandroid.blogspot.com/2014/08/doing-setsockopt-in-go.html
  10. https://iximiuz.com/en/posts/go-net-http-setsockopt-example/#net-http-set-client-socket-options
  11. https://iximiuz.com/en/posts/go-net-http-setsockopt-example/#net-http-set-server-socket-options
  12. https://djangocas.dev/blog/linux/linux-SO_BINDTODEVICE-and-mac-IP_BOUND_IF-to-bind-socket-to-a-network-interface
  13. https://gist.github.com/bacher09/51ce161105a9e1f49b8b917f8eccd3c5
  14. https://github.com/jursonmo/tcpbinddev
  15. https://github.com/golang/go/issues/6966
  16. https://gist.github.com/atotto/dae840a49f20a0373b49bc1658bdc73b
  17. https://raspberrypi.stackexchange.com/questions/87804/make-a-program-to-run-on-a-specific-network-interface
  18. https://raspberrypi.stackexchange.com/questions/15119/force-raspberry-to-get-internet-from-specific-network
GWustenstein commented 1 year ago

That would be great...depending on the widget, one could specify it on the command line or config, so a zero-w (if you can get them) plus a cruddy micro to ethernet adapter would do the trick for the better part of $30/US

uhppoted commented 1 year ago

Could probably do it even less expensively using a PicoW and some not-too-complicated C code! Hmmm .. thinks .. :-)

uhppoted commented 1 year ago

Tasks:

GWustenstein commented 1 year ago

Well, an ESP32 could do it as well, and you could go so far as to bit-bang manchester at 10mbps with the $2 kits if you really wanted and a hacked 10bT i/f built with resistors and spare i/o pins, but just imagine trying to load in a set of keys, let alone debug DNS on it...

uhppoted commented 1 year ago

And that's a wrap! The bind-to-device functionality is available in the master branch if you need it before the next release which is a fair bit down the line. Have tested it on a Macbook, Rasberry Pi 3B+ and Ubuntu and seems to work as expected.

Will leave this open for another couple of days to give it time to bed down.

uhppoted commented 1 year ago

Closing - seems to be stable and do what it is supposed to do. Feel free to reopen if needed.