Total Pageviews

Friday, 23 February 2018

利用subnet vpn翻墙

Simple, auditable & elegant VPN, built with TLS mutual authentication and TUN. 

Simple VPN server/client for the rest of us.

Overview

subnet establishes a TLS connection to the server. A TUN interface is created, and setup with the given network parameters (local IP, subnet). All traffic that matches the localIP + subnet gets routed to the VPN server.
On the server, all traffic which is received is checked against all client's localIPs. If it matches, it goes down there. If it doesn't, it gets routed to the servers TUN device (to its network). If the server's kernel is configured correctly, packets coming back into the TUN device will be NATed, and hence can be routed correctly. They then get routed back to the correct client.

Use cases

Tunnel all non-LAN traffic through another box on the internet (traditional VPN).

Setup the server:
export GOPATH=`pwd` #set your GOPATH where you want the build to happen
go get -u -v github.com/twitchyliquid64/subnet/
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -j MASQUERADE
./bin/subnet --mode init-server-certs --cert server.certPEM --key server.keyPEM --ca ca.certPEM --ca_key ca.keyPEM
./bin/subnet --mode server --key server.keyPEM --cert server.certPEM --ca ca.certPEM --network 192.168.69.1/24 0.0.0.0

Setup the client:
First, generate a certificate/key pair for each client, by running this on the server:
subnet --mode make-client-cert --ca ca.certPEM --ca_key ca.keyPEM client.certPEM client.keyPEM

Then, download client.certPEM, client.keyPEM and ca.certPEM to your client machine.

Now, run this on the client machine:
export GOPATH=`pwd` #set your GOPATH where you want the build to happen
go get -u github.com/twitchyliquid64/subnet
sudo subnet -gw 192.168.69.1 -network 192.168.69.4/24 -cert client.certPEM -key client.keyPEM -ca ca.certPEM <server address>

#If you are on Mac OSX (replace 'Wi-Fi' with your interface):
sudo networksetup -setdnsservers Wi-Fi 8.8.8.8
Explanation:
  • subnet is downloaded and compiled on both client and server.
  • A CA certificate is generated, and a server certificate is generated which is signed by the CA cert (init-server-certs mode).
  • A client certificate is generated, which again is based off the CA cert (make-client-cert mode).
  • Server's networking stack is told to allow the forwarding of packets and to apply NAT to the packets.
  • Server gets the VPN address 182.168.69.1, managing traffic for 182.168.69.1 - 182.168.69.255.
  • Client gets the address 182.168.69.4.
  • Client remaps its default gateway to 182.168.69.1, forcing all non-LAN traffic through the VPN server.
  • On connection, both sides verify the TLS cert against the CA cert given on the command line.

Make a remote LAN accessible on your machine.

Setup the server (linux only):
export GOPATH=`pwd` #set your GOPATH where you want the build to happen
go get -u github.com/twitchyliquid64/subnet
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -j MASQUERADE
./bin/subnet --mode init-server-certs --cert server.certPEM --key server.keyPEM --ca ca.certPEM --ca_key ca.keyPEM
./bin/subnet --mode server --key server.keyPEM --cert server.certPEM --ca ca.certPEM --network 182.168.69.1/24 0.0.0.0
Setup the client:
First, generate a certificate/key pair for each client, by running this on the server:
./bin/subnet --mode make-client-cert --ca ca.certPEM --ca_key ca.keyPEM client.certPEM client.keyPEM
Then, transfer client.certPEM, client.keyPEM and ca.certPEM to your client.
Now, run this on the client:
export GOPATH=`pwd` #set your GOPATH where you want the build to happen
go get -u github.com/twitchyliquid64/subnet
sudo ./bin/subnet -network 182.168.69.4/24 -cert client.certPEM -key client.keyPEM -ca ca.certPEM <server address>
Explanation:
  • subnet is downloaded and compiled on both client and server.
  • Certificates are generated, all based on the CA cert which is also generated.
  • Server gets the VPN address 182.168.69.1, managing traffic for 182.168.69.1 - 182.168.69.255.
  • Client gets the address 182.168.69.4. The /24 subnet mask means traffic for addresses 182.168.69.1 to 182.168.69.255 will be routed through the VPN.
  • Any traffic to 182.168.69.1 will go to the VPN server. Any traffic to 182.168.69.1 to 182.168.69.255 will go to clients connected to the same server with that address. All other traffic is routed outside of subnet.

Usage

Usage of ./subnet:
./subnet <server address>
  -blockProfile
     Enable block profiling
  -ca string
     Path to PEM-encoded cert to validate client/serv
  -ca_key string
     Path to PEM-encoded key to use generating certificates
  -cert string
     Path to PEM-encoded cert for our side of the connection
  -cpuProfile
     Enable CPU profiling
  -gw string
     (Client only) Set the default gateway to this value
  -i string
     TUN interface, one is picked if not specified
  -key string
     Path to PEM-encoded key for our cert
  -mode string
     Whether the process starts a server or as a client (default "client")
  -network string
     Address for this interface with netmask (default "182.168.69.1/24")
  -port string
     Port for the VPN connection (default "3234") 
from https://github.com/twitchyliquid64/subnet 
----------
我的补充说明:
subnet是基于go的程序,所以需先安装go环境:
wget https://dl.google.com/go/go1.16.linux-amd64.tar.gz
tar zxvf  go1.16.linux-amd64.tar.gz
echo 'export PATH=$PATH:/root/go/bin' >> /etc/profile
cd go
mkdir gopath
echo 'export GOROOT=/root/go' >> /etc/profile
echo 'export GOPATH=/root/go/gopath' >> /etc/profile
echo 'export PATH=$PATH:/root/go/gopath/bin' >> /etc/profile

echo 'export GOBIN=/root/go/gopath/bin' >> /etc/profile

source /etc/profile

这样,go环境就搭建好了

https://golang.org/dl/

检验一下:
root@ar:~/go# echo $GOROOT
/root/go
root@ar:~/go# echo $GOPATH
/root/go/gopath
root@ar:~/go# echo $GOBIN
root@ar:~/go# /root/go/gopath/bin
root@ar:~/go# cd 
root@ar:~# 
然后,
cd $GOPATH
go get -u -v github.com/twitchyliquid64/subnet/
iptables -t nat -A POSTROUTING -j MASQUERADE
sysctl net.ipv4.ip_forward=1
mkdir subnet-certs
cd subnet-certs 
运行:
subnet --mode init-server-certs --cert server.certPEM --key server.keyPEM --ca ca.certPEM --ca_key ca.keyPEM
会显示:
NOTICE: Certificates expire (and will need to be rotated) one year from now.
运行:
subnet --mode server --key server.keyPEM --cert server.certPEM --ca ca.certPEM --network 182.168.69.1/24 0.0.0.0
会显示:
2018/02/27 01:52:08 Created iface tun1
2018/02/27 01:52:08 Listen for TLS on 0.0.0.0:3234, IP tun1 set to 182.168.69.1, localNetMask 255.255.255.0

这条命令subnet --mode server --key server.keyPEM --cert server.certPEM --ca ca.certPEM --network 182.168.69.1/24 0.0.0.0是在前台运行的,我们可用systemd把此命令运行为service:

nano /etc/systemd/system/subnet.service
内容如下:
[Unit]
Description=subnet
After=network.target

[Service]
ExecStart=/root/go/gopath/bin/subnet --mode server --key /root/subnet-certs/server.keyPEM --cert /root/subnet-certs/server.certPEM --ca /root/subnet-certs/ca.certPEM --network 182.168.69.1/24 0.0.0.0
Restart=always

[Install]
WantedBy=multi-user.target 


启动subnet
systemctl daemon-reload 
systemctl start subnet
这其实就是以daemon(service)方式启动subnet程序
  
设置开机启动subnet
systemctl enable subnet

在服务器上的~/subnet-certs/里面,运行:
subnet --mode make-client-cert --ca ca.certPEM --ca_key ca.keyPEM client.certPEM client.keyPEM
会在当前目录下,生成client.certPEM和client.keyPEM文件.
  至此,subnet
服务器端的配置已经全部完成.

在本地机器mac上。
跟服务器上一样,需先安装go环境。然后,
cd $GOPATH
go get -u -v github.com/twitchyliquid64/subnet/
然后把生成的可执行文件subnet添加到环境变量。
mkdir subnet-certs-for-client
cd subnet-certs-for-client
然后把服务器上的~/subnet-certs/里面的client.certPEM文件client.keyPEM文件ca.certPEM文件下载到当前目录。
sudo subnet -gw 182.168.69.1 -network 182.168.69.4/24 -cert client.certPEM -key client.keyPEM -ca ca.certPEM vps-ip 
会显示:
2018/02/27 16:50:53 Created iface utun1
2018/02/27 16:50:54 Remote presented certificate 8947204077936876025 with time bounds (2018-02-27 06:47:34 +0000 UTC-2018-08-27 05:47:34 +0000 UTC). Verification error for certificate: <nil>
2018/02/27 16:50:54 IP of utun1 set to 182.168.69.4, localNetMask 255.255.255.0
2018/02/27 16:50:54 Default gateway is 192.168.1.1 on en0
2018/02/27 16:50:54 Traffic to my-vps-ip now routed via 192.168.1.1 on en0
(注:如果你运行该vpn的客户端命令后,遇到提示:Certificate expired or used too soon,那么在$GOPATH
里面重新运行go get -u -v github.com/twitchyliquid64/subnet ,以重新生成可执行文件subnet,
on linux vps,i removed all the certs and key files,and re-run: subnet --mode init-server-certs --cert server.certPEM --key server.keyPEM --ca ca.certPEM --ca_key ca.keyPEM
and subnet --mode make-client-cert --ca ca.certPEM --ca_key ca.keyPEM client.certPEM client.keyPEM
then i removed ca.certPEM, client.certPEM, client.keyPEM FROM MY MAC,AND re-download ca.certPEM, client.certPEM, client.keyPEM from vps to my mac.
然后运行:
sudo subnet -gw 182.168.69.1 -network 182.168.69.4/24 -cert client.certPEM -key client.keyPEM -ca ca.certPEM my-vps-ip
参见https://github.com/twitchyliquid64/subnet/issues/11)

#If you are on Mac OSX (replace 'Wi-Fi' with your interface): 
sudo networksetup -setdnsservers Wi-Fi 8.8.8.8
这样,在mac上,就成功连上了这个subnet vpn,你的整台mac机器就处于翻墙状态了。
不过,有时dns server 8.8.8.8也不一定能够成功连上,此时就需要设置dns proxy了:
具体请看此文https://briteming.blogspot.com/2019/08/socks-proxydnsdns-proxy-by-snail007.html ,

sudo networksetup -setdnsservers "Wi-Fi" 127.0.0.1

运行本地的ss程序,


sudo ~/goproxy-by-snail007/proxy dns -S socks -T tcp -P 127.0.0.1:1080 -p :53

这样,在mac上,就成功连上了这个subnet vpn。

如果你翻墙失败,
1)按ctrl+c,重新运行vpn客户端命令
sudo subnet -gw 182.168.69.1 -network 182.168.69.4/24 -cert client.certPEM -key client.keyPEM -ca ca.certPEM vps-ip
2) sudo networksetup -setdnsservers "Wi-Fi" 127.0.0.1
3)按ctrl+c,重新运行dns proxy命令

sudo ~/goproxy-by-snail007/proxy dns -S socks -T tcp -P 127.0.0.1:1080 -p :53

即可重新成功连上这个subnet vpn。


No comments:

Post a Comment