chisel icon indicating copy to clipboard operation
chisel copied to clipboard

[Feature Request] TUN interface support (Simple VPN solution)

Open nutinshell opened this issue 8 years ago • 9 comments

Hi, it's cool to have tun device, so we can use chisel as a simple VPN solution :)

nutinshell avatar Aug 18 '15 07:08 nutinshell

I've been thinking about this, would be cool, though it's a lot of work. I probably won't have time to give this a shot for a long time, though I'll leave this open incase you or anyone else wants to try.

jpillora avatar Aug 18 '15 08:08 jpillora

I had a look into what it would take to achieve this:

  • The TUN interface (tunnel - psuedo-IP interface) would only be needed on the client
  • The TUN interface would be used to achieve chisel client <endpoint> all, where the special all remote would redirect all traffic to the TUN interface
  • Creation of TUN interface
    • Go libraries
      • https://github.com/liudanking/tuntap
      • https://github.com/songgao/water
    • Linux natively supported
    • OSX needs tuntap k(ernel) ext(ension)s
      • Could add an option to auto-install by embedding the .pkg (58KB) and using the installer -pkg <pathToPackage> command?
      • Contribute OSX interface creation back to songgao/water
    • Windows ???
  • Give the TUN interface an unused ip/subnet
  • On startup insert a default route via the TUN interface, remove it on shutdown
  • Then, in a loop
    • chisel client will:
      • Read packets off the interface
      • Parse each for TCP and UDP, drop the rest
      • Encapsulate and send to the chisel server
      • Received server packets are then written to the interface and will land in the OS network stack
    • chisel server will:
      • Receive cliented packets are decapsulated
      • Split into sessions
      • For each session tunnel packets to that endpoint (on-demand remote endpoints :+1:)
      • Received remote packets are then tunneled back and the client
  • En[de]capsulation
    • Packets will be in the form [ip => dst ip][tcp or udp => dst port][payload] the client should extract the destination ip, tcp or udp, port and payload from each and binary encode them
    • Custom encapsulation saves bandwidth since we only send the payload, we should only take what's necessary to establish a session and also allows for chisel fields to be added later

References

  • https://github.com/meshbird/meshbird
  • https://github.com/stargrave/govpn

jpillora avatar Aug 20 '15 05:08 jpillora

In the meantime, for anyone looking for a simple private VPN solution, checkout Zero Tier https://www.zerotier.com/ It's like a free Hamachi.

jpillora avatar Jun 24 '17 02:06 jpillora

@aus I like the idea of a TUN remote, though I think it'd need to be the other way around?

  • ensure TUN is supported on both client and server
  • chisel client <ip> tun:<target>
  • chisel client connects to server at ip
  • chisel client creates a TUN interface and gives it a new IP
  • chisel server also creates a TUN interface
  • you setup local routes directing packets to the TUN interface
  • packets would flow like: source -> chisel client TUN -> [chisel client -> chisel server] -> chisel server TUN -> dest

jpillora avatar Sep 15 '20 17:09 jpillora

You are right. I had it backwards. However, thinking about this a bit more, do we need to have a TUN at both ends for this to work? Could we just have it on the client end and do this:

  • source emits packet on TUN
  • chisel client listens for TUN packets, serializes the received packet, and sends it through SSH channel
  • chisel server receives serialized packet, deserializes, modifies the packet.SrcIP
  • chisel server does net.DialIP and writes the modified packet on conn

....but then how do you track responses to send back to client, since you are not session based. You also need a to include the protocol when doing a DialIP and how do we guarantee that? Hmmm...

I guess maybe you should do a similar approach to UDP: start up a net.ListenIP, track what IPs we should expect responses from, wait for a response, then timeout if none received. But this seems like the wrong approach...

If your TUN only supported TCP and UDP and ignored everything else, you could get away with one-sided TUN. Convert the IP packet to a TCP or UDP session before tunneling and Dial. It'd be similar to SOCKS at that point, But that's not true TUN, so not ideal either.

And now I'm talking myself out of this one-sided TUN idea. 😄

I guess if we want true TUN, you have to have it both ends because you have to TX -> forward and RX <- forward each packet on both sides.

<target> would be the IP of the TUN on both client and server, right?

Let's take this HTTP packet capture as an example and run through your list:

setup

  • chisel server --tun
  • chisel client example.com tun:192.168.1.140
  • client connects to server
  • client and server negotiate TUN connection. If agree, both start tun0 with IP of 192.168.1.140
  • client and server setup routes
    • how do we determine what routes to apply?
    • should this be left up user?
    • probably would require root privs right?
  • client and server loops:
    • Read(): for each packet on tun0, serialize and tunnel
    • Write(): for each packet on channel, deserialize and emit to tun0

example

  • for the HTTP example, client emits first packet TCP SYN packet src: 192.168.1.40 dst: 174.143.213.184
  • chisel client catches the packet, serializes it, and tunnel
  • chisel server receives tunnel packet, deserializes, and writes same packet to its local tun0
  • now comes the SYN ACK to server's tun0. server sees the incoming packet. src: 174.143.213.184 dst: 192.168.1.140
  • chisel server catches the packet, serializes it and tunnels
  • rinse repeat...

tear down

  • client ^C and disconnects. client removes TUN devices and restores routes.
  • server sees client disconnect and removes its matching TUN

I like it... probably some other things to consider. I'll keep thinking...

aus avatar Sep 16 '20 03:09 aus

tcp/ip over http ? Cool !!! Is it supported now? @jpillora

tivizi avatar Oct 23 '20 02:10 tivizi

Chisel does TCP over HTTP. See the README. This issue is for something else

On 23 Oct 2020 at 1:37:12 pm, tivizi [email protected] wrote:

tcp/ip over http ? Cool !!! Is it supported now? @jpillora https://github.com/jpillora

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jpillora/chisel/issues/3#issuecomment-714870603, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE2X47D6UJXJX4WHITWZLDSMDT5RANCNFSM4BNVPDLQ .

jpillora avatar Oct 25 '20 09:10 jpillora

Would this feature allow someone to route all their network traffic through chisel (e.g. 0.0.0.0) or is this already handled by chisel?

mrbluecoat avatar Mar 16 '21 02:03 mrbluecoat

In the server context, 0.0.0.0 usually means "listen on all interfaces" - this is supported

This issue is a feature request for chisel to be able to "listen on all ports" - not implemented due to the complexity above

On 16 Mar 2021 at 1:37:21 pm, Mr. Blue Coat @.***> wrote:

Would this feature allow someone to route all their network traffic through chisel (e.g. 0.0.0.0) or is this already handled by chisel?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jpillora/chisel/issues/3#issuecomment-799898305, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE2X42LWMPRF2IAQM7RNZDTD276DANCNFSM4BNVPDLQ .

jpillora avatar Mar 16 '21 02:03 jpillora