tinc国内服务器访问国外

tinc实现国内服务器通过国外服务器访问外网

国内服务器建议使用: 腾讯云vps(新用户便宜)

目标:有两个服务器:国内服务器A,外网地址:111.111.111.111;国外服务器B,外网地址:222.222.222.222
实现:A和B用tinc打通,A发起通过B访问国外,A本身提供的服务不受影响。
tinc的网络,给服务器A配的地址:192.168.2.1,给服务器B配的地址:192.168.2.254

安装(在两个机器上同样的步骤):
apt-get install tinc -y
自己起网络名称:tinc0
mkdir -p /etc/tinc/tinc0/hosts

—————- 国外服务器A操作 —————-

创建配置文件
1.建立网络配置目录(网络名称为 tinc0):
sudo mkdir -p /etc/tinc/tinc0/hosts
2.建立配置文件 tinc.conf
sudo vi /etc/tinc/tinc0/tinc.conf
编辑 tinc.conf 内容如下:

Name = tinc_us
Interface = tinc0
AddressFamily = ipv4

由于本主机为核心主机,只负责等待和认证其他主机的连接。因此,本主机没有配置 ConnectTo。
3.建立启动和关闭脚本 创建启动脚本 tinc-up
sudo vi /etc/tinc/tinc0/tinc-up
编辑 tinc-up 内容如下:
!/bin/sh
ifconfig $INTERFACE 192.168.2.254 netmask 255.255.255.0

创建启动脚本 tinc-down
sudo vi /etc/tinc/tinc0/tinc-down
编辑 tinc-down 内容如下:
!/bin/sh
ifconfig $INTERFACE down

赋予脚本可执行权限:
sudo chmod +x /etc/tinc/tinc0/tinc-up
sudo chmod +x /etc/tinc/tinc0/tinc-down
4.创建本主机描述文件(网络名称为 tinc_us)
sudo vi /etc/tinc/tinc0/hosts/tinc_us
编辑 tinc_us 内容如下:
Address = 222.222.222.222
Subnet = 0.0.0.0/0

密钥一路回车:tincd -n tinc0 -K
会在/etc/tinc/tinc0/hosts/tinc_us文件中自动加入密钥,把 /etc/tinc/tinc0/hosts/tinc_us 拷贝到 国内服务器的 /etc/tinc/tinc0/hosts/目录中。

目录结构
.
├── tinc0
│   ├── hosts
│   │   ├── tinc_bj
│   │   └── tinc_us
│   ├── rsa_key.priv
│   ├── tinc.conf
│   ├── tinc-down
│   └── tinc-up
└── nets.boot
root@hk:/etc/tinc# cat nets.boot 
tinc0

root@hk:/etc/tinc/tinc0# cat tinc.conf 
Name = tinc_bj
Interface = tinc0
AddressFamily = ipv4

root@hk:/etc/tinc/tinc0# cat tinc-up 
#!/bin/sh
ifconfig $INTERFACE 192.168.2.254 netmask 255.255.255.0

root@hk:/etc/tinc/tinc0# cat tinc-down 
#!/bin/sh
ip link set $INTERFACE down

给执行权限:
chmod 755 /etc/tinc/tinc0/tinc-*
root@hk:/etc/tinc/tinc0/hosts# cat tinc_bj 
Address = 111.111.111.111
Subnet = 192.168.2.1/32
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
root@hk:/etc/tinc/tinc0/hosts# cat tinc_us 
Address = 222.222.222.222
Subnet = 0.0.0.0/0
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
启动tinc服务:
systemctl start tinc@tinc0

—————- 以下为国内服务器B操作 —————-

创建配置文件
1.建立网络配置目录(网络名称为 tinc0):
sudo mkdir -p /etc/tinc/tinc0/hosts
2.建立配置文件 tinc.conf
sudo vi /etc/tinc/tinc0/tinc.conf
编辑 tinc.conf 内容如下:

Name = tinc_bj
Interface = tinc0
AddressFamily = ipv4
ConnectTo = tinc_us  #这里要加连接到国外的网络名称

本主机要配置 ConnectTo 到国外。
3.建立启动和关闭脚本 创建启动脚本 tinc-up
sudo vi /etc/tinc/tinc0/tinc-up
编辑 tinc-up 内容如下:

#!/bin/sh
ifconfig $INTERFACE 192.168.2.1 netmask 255.255.255.0
ip route add 222.222.222.222 via 10.0.8.1 dev eth0

ip route add 192.168.2.0/24 dev $INTERFACE
ip route add 0.0.0.0/1 dev $INTERFACE
ip route add 128.0.0.0/1 dev $INTERFACE

sed -i 's/127.0.0.53/8.8.8.8/g' /etc/resolv.conf
ip route add 8.8.8.8/32 dev $INTERFACE
sysctl -p

创建启动脚本 tinc-down
sudo vi /etc/tinc/tinc0/tinc-down

#!/bin/sh
ip link set $INTERFACE down
ip route del 222.222.222.222 via 10.0.8.1 dev eth0

ip route del 192.168.2.0/24 dev $INTERFACE
ip route del 0.0.0.0/1 dev $INTERFACE
ip route del 128.0.0.0/1 dev $INTERFACE

sed -i 's/8.8.8.8/127.0.0.53/g' /etc/resolv.conf
ip route del 8.8.8.8/32 dev $INTERFACE

赋予脚本可执行权限:
sudo chmod +x /etc/tinc/tinc0/tinc-up
sudo chmod +x /etc/tinc/tinc0/tinc-down
4.创建本主机描述文件(网络名称为 tinc_bj)
sudo vi /etc/tinc/tinc0/hosts/tinc_bj
Address = 111.111.111.111
Subnet =
192.168.2.1/32

密钥一路回车:tincd -n tinc0 -K
会在/etc/tinc/tinc0/hosts/tinc_bj文件中自动加入密钥,把 /etc/tinc/tinc0/hosts/tinc_bj 拷贝到 国外服务器的 /etc/tinc/tinc0/hosts/目录中。

此时已经安装完tinc,目录结构如下:
root@VM-0-14-ubuntu:/etc/tinc# tree .
.
├── tinc0
│   ├── hosts
│   │   ├── tinc_bj
│   │   └── tinc_us
│   ├── rsa_key.priv
│   ├── tinc.conf
│   ├── tinc-down
│   └── tinc-up
└── nets.boot

2 directories, 7 files

root@VM-0-14-ubuntu:/etc/tinc# cat nets.boot 
tinc0

root@VM-0-14-ubuntu:/etc/tinc/tinc0# cat tinc.conf 
Name = tinc_bj
Interface = tinc0
AddressFamily = ipv4
ConnectTo = tinc_us

root@VM-0-14-ubuntu:/etc/tinc/tinc0# cat tinc-up 
#!/bin/sh
ifconfig $INTERFACE 192.168.2.1 netmask 255.255.255.0
ip route add 222.222.222.222 via 10.0.8.1 dev eth0

ip route add 192.168.2.0/24 dev $INTERFACE
ip route add 0.0.0.0/1 dev $INTERFACE
ip route add 128.0.0.0/1 dev $INTERFACE

root@VM-0-14-ubuntu:/etc/tinc/tinc0# cat tinc-down 
#!/bin/sh
ip link set $INTERFACE down
ip route del 222.222.222.222 via 10.0.8.1 dev eth0

ip route del 192.168.2.0/24 dev $INTERFACE
ip route del 0.0.0.0/1 dev $INTERFACE
ip route del 128.0.0.0/1 dev $INTERFACE

给执行权限:
chmod 755 /etc/tinc/tinc0/tinc-*

root@VM-0-14-ubuntu:/etc/tinc/tinc0/hosts# cat tinc_bj 
Address = 111.111.111.111
Subnet = 10.0.0.1/32
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

root@VM-0-14-ubuntu:/etc/tinc/tinc0/hosts# cat tinc_us 
Address = 222.222.222.222
Subnet = 0.0.0.0/0
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

启动服务:
systemctl start tinc@tinc0
能ping通 192.168.2.254 ,说明tinc就打通了。

如果你启动服务后服务器就断网了,可能是因为回包不对称导致,访问111.111.111.111,回包走了tinc0,具体可以通过tcpdump -i any | grep ip 来判断下。
这种情况说明你本地默认路由没有配置好,在ubuntu22.04情况下,要严格配置eth0网卡路由根据来源ip进行路由策略,哪来哪去。
参考:https://moneyslow.com/%E8%85%BE%E8%AE%AF%E4%BA%91%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%A4%9A%E4%B8%AA%E7%BD%91%E5%8D%A1%E9%85%8D%E7%BD%AE%E5%A4%9A%E4%B8%AA%E5%85%AC%E7%BD%91ip.html
重点是 /etc/netplan/50-cloud-init.yaml 这部分:

routes:
                    - to: 0.0.0.0/0 # 路由的目标地址。
                      via: 10.0.8.1 # 为通过路由的流量设置源 IP 地址。(网关)
                      table: 100 # eth0对应的路由表
            routing-policy:
                    - from: 10.0.8.2 # 主网卡私网ip,设置源 IP 地址以匹配此策略规则的流量。
                      table: 100 # 路由表编号
                      priority: 300 # 指定路由策略规则的优先级,以影响处理路由规则的顺序。
                                    # 数字越大,优先级越低:规则按优先级数字递增的顺序处理。

如果上面问题解决,可以启动tinc服务,可以继续:
在A上直接ping google.com,你可能因为dns的问题遇到困难,在ubuntu22.04操作系统下,有点麻烦,我们需要修改本机的dns设置
参考文章:https://moneyslow.com/ubuntu22-04%E4%B8%8Bdns%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%9C%B0%E5%9D%80127-0-0-53-%E5%92%8C-masquerade-%E7%9A%84%E7%9F%9B%E7%9B%BE.html

这里做了点取巧,在启动tinc-up的状态下,用8.8.8.8这个dns,你会看到上面tinc-up脚本里有一行:
cp /etc/resolv_vpn.conf /etc/resolv.conf
关闭tinc-down的情况下,恢复使用本机原来的dns,你会看到上面tinc-down脚本里有一行:
cp /etc/resolv_qcloud.conf /etc/resolv.conf

root@VM-8-2-ubuntu:~# cat /etc/resolv_vpn.conf 
nameserver 8.8.8.8
options edns0 trust-ad
search .
root@VM-8-2-ubuntu:~# cat /etc/resolv_qcloud.conf 
nameserver 183.60.83.19
nameserver 183.60.82.98
options edns0 trust-ad
search .

几点注意:
1、在hosts目录下,国外机器描述文件(/etc/tinc/tinc0/hosts/tinc_us)中,要有 Subnet = 0.0.0.0/0
2、国外服务器B开启snat:iptables -t nat -A POSTROUTING -j MASQUERADE
需要将所有的流量出去的时候,源地址都要snat为本机公网地址,手动执行:
iptables -t nat -A POSTROUTING -j MASQUERADE
3、注意国外服务器B的/etc/sysctl.conf 文件,要有net.ipv4.ip_forward=1
4、如果国外服务器开启tinc服务后,不能上网,请关闭ufw等防火墙排错

不同网卡出去的公网ip的shell脚本:

echo "default"
curl ifconfig.me
echo ""
echo "tinc0" 
curl --interface tinc0 ifconfig.me
echo ""
echo "eth0"
curl --interface eth0 ifconfig.me
echo ""

执行结果:

root@VM-8-2-ubuntu:~# ./curl.sh 
default
222.222.222.222
tinc0
222.222.222.222
eth0
111.111.111.111

接下来,你就可以拨号到guonei上来了,遨游世界:
https://moneyslow.com/2023%e5%b9%b4%e9%85%8d%e7%bd%aestrongswan-on-ubuntu-22-04.html

如果实现启动多个实例连接到多个vpn master server,则必须在主机配置文件中增加端口,不然会报端口冲突错误,参考:
《tinc启动多个实例报错Can’t bind to 0.0.0.0 port 655/tcp: Address already in use》

如何tinc可以联通,也能通过tinc0接口ping通8.8.8.8,但是就是不能访问正常业务的tcp端口,看这里:

最终的国外服务器的防火墙状态:

# ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----           
[ 5] Anywhere                   ALLOW IN    111.111.111.111              
[21] Nginx Full                 ALLOW IN    Anywhere                  
[22] Anywhere on tinc0          ALLOW IN    Anywhere                  
[23] Anywhere                   ALLOW OUT   Anywhere on tinc0          (out)
[24] 655/udp                    ALLOW IN    Anywhere                  
[25] 655/tcp                    ALLOW IN    Anywhere                  
[26] Anywhere on eth0           ALLOW FWD   Anywhere on tinc0         
[27] Nginx Full (v6)            ALLOW IN    Anywhere (v6)             
[28] Anywhere (v6) on tinc0     ALLOW IN    Anywhere (v6)             
[29] Anywhere (v6)              ALLOW OUT   Anywhere (v6) on tinc0     (out)
[30] 655/udp (v6)               ALLOW IN    Anywhere (v6)             
[31] 655/tcp (v6)               ALLOW IN    Anywhere (v6)             
[32] Anywhere (v6) on eth0      ALLOW FWD   Anywhere (v6) on tinc0 

# iptables -nL  -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.2.0/24       0.0.0.0/0    

# ufw show added | grep route
ufw route allow in on tinc0 out on eth0

# iptables -L FORWARD -v -n
# 下面默认策略FORWARD一定是ACCEPT
Chain FORWARD (policy ACCEPT 2482 packets, 125K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  17M 8909M ufw-before-logging-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  17M 8909M ufw-before-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  10M  621M ufw-after-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  10M  621M ufw-after-logging-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  10M  621M ufw-reject-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  10M  621M ufw-track-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0   

# ufw show added
Added user rules (see 'ufw status' for running firewall):
ufw allow from 202.91.33.112
ufw allow from 104.194.91.178
ufw deny from 192.144.128.0/17
ufw deny from 162.14.40.0/21
ufw allow from 49.233.91.24
ufw allow from 62.234.181.90
ufw deny from 1.162.0.0/16 comment 'claudebot'
ufw deny from 3.20.0.0/14 comment 'claudebot'
ufw deny from 3.132.0.0/14 comment 'claudebot'
ufw deny from 3.144.0.0/13 comment 'claudebot'
ufw deny from 3.14.0.0/15 comment 'claudebot'
ufw deny from 52.15.128.0/17 comment 'claudebot'
ufw deny from 18.116.0.0/14 comment 'claudebot'
ufw deny from 18.224.0.0/14 comment 'claudebot'
ufw deny from 52.14.0.0/16 comment 'claudebot'
ufw deny from 3.136.0.0/13 comment 'claudebot'
ufw deny from 3.16.0.0/14 comment 'claudebot'
ufw deny from 3.12.0.0/16 comment 'claudebot'
ufw deny from 18.216.0.0/14 comment 'claudebot'
ufw deny from 13.58.0.0/15 comment 'claudebot'
ufw allow 'Nginx Full'
ufw allow in on tinc0
ufw allow out on tinc0
ufw allow 655/udp
ufw allow 655/tcp
ufw route allow in on tinc0 out on eth0