twitchyliquid64 / subnet

Simple, auditable & elegant VPN, built with TLS mutual authentication and TUN.
MIT License
1.06k stars 71 forks source link

how the server handle the packet sent by client ? #14

Open Jamlee opened 5 years ago

Jamlee commented 5 years ago

Hi, budy. i have read source code, somewhere i could not understand. ^_^.

why does not the raw packet sent by client need modified ?
for example, changing source ip etc.

Is the non-modify raw packet sent to tun0 directly always routed back correctly ?

twitchyliquid64 commented 5 years ago

Hi Jamlee,

The missing piece is that the operating system on the server (a Linux feature called IPTables Masquerade) is modifying the packets for us if needed.

Consider these two scenarios, where the VPN network has a netmask of 255.255.255.0 with a network address space of 192.168.69.1-255:

Client on the VPN (with address 192.168.69.3) is sending packet to another VPN client with address 192.168.69.8:

Client on the VPN (with address 192.168.69.3) is sending packet to 8.8.8.8:

Does that help?

Jamlee commented 5 years ago

yeah, it is really really helpul to me. cloud i tranlate your answer to chinese for helping more people from your nice work ?

你好, Jamlee。

这里错过的一点是在linux系统中 iptables 的 IPTables Masquerade 会在有必要的时候修改发送的IP包

考虑下面两个场景,前提是 vpn 的网段是 192.168.69.1-255, 子网掩码为 255.255.255.0:

VPN 的客户端(地址 192.168.69.3)发送了 ip packet 到 另外一个 vpn 客户端 (地址 192.168.69.8):

  1. 发送端依据地址 192.168.69.8 所以会发送数据包到 VPN(TUN) 设备, tun 封装了 ip raw packet ,然后通过 tcp 发送到服务端。
  2. 在服务接收端, vpn 进程把从 TCP 端口接受过来的 Ip raw packet 处理后写入到 tun 设备, tun 是本地设备,会被监听 192.168.69.8 的 app 获取到 tcp 信息。

               +---------------------+         +--------------------+    +---------------------+--------------------------------------+
               |                     |         | src 192.168.69.3   |    |                     |                                      |
               |                     |         | dst 192.168.69.8   |    |                     |      +---------------------------+   |
               |  +---------------+  |         +--------------------+    |  +---------------+  |      |                           |   |
               |  |   vpn client  |  |          ip packet on tcp tunel   |  |   vpn server  |  |      |                           |   |
               |  |               |  |     +-----------------------------+-->               |  |      |                           |   |
               |  +-------+-------+  |     |                             |  +-------+-------+  |      |    app behind on vpn      |   |
               |          |          |     |                             |          |          |      |      listening on         |   |
               |  +-------v-------+  |     |                             |  +-------v-------+  |      |     192.168.69.8          |   |
               |  |      tun0    ++--+-----+                             |  |      tun0     |  |      |                           |   |
               |  |  192.168.69.3 |  +                                   |  |  192.168.69.8 +--+------>                           |   |
               |  +---------------+  |                                   |  +---------------+  |      +---------------------------+   |
               +---------------------+                                   +---------------------+--------------------------------------+

VPN 的客户端(地址 192.168.69.3)发送了 ip packet 到地址 8.8.8.8:

  1. 发送端依据地址 192.168.69.8 所以会发送数据包到 VPN(TUN) 设备, tun 封装了 ip raw packet ,然后通过 tcp 发送到服务端。
  2. 在服务接收端, vpn 进程把从 TCP 端口接受过来的 Ip raw packet 处理后写入到 tun 设备, 由于 ip packet 不是本地设备,会被 linux 进行 源地址改写(也就是NAT功能啦)

    +---------------------+         +--------------------+    +---------------------+----------------------+
    |                     |         | src 192.168.69.3   |    |                     |                      |
    |                     |         | dst 8.8.8.8        |    |                     |                      |
    |  +---------------+  |         +--------------------+    |  +---------------+  |                      |
    |  |   vpn client  |  |          ip packet on tcp tunel   |  |   vpn server  |  |                      |
    |  |               |  |     +-----------------------------+-->               |  |                      |
    |  +-------+-------+  |     |                             |  +-------+-------+  |                      |      dst 8.8.8.8
    |          |          |     |                             |          |          |                      |      src 192.168.69.8
    |  +-------v-------+  |     |                             |  +-------v-------+  |                      |    NAT
    |  |      tun0    ++--+-----+                             |  |      tun0     |  |         NAT by linux |------------->
    |  |  192.168.69.3 |  +                                   |  |  192.168.69.8 +--+----> route by default|<-------------
    |  +---------------+  |                                   |  +---------------+  |      gw              |      dst 192.168.69.8
    +---------------------+                                   +---------------------+----------------------+      src 8.8.8.8

            node A                                                     node B
twitchyliquid64 commented 5 years ago

Yes thankyou! I can link to this from the readme, or feel free to submit a PR.

Thanks again!