内网集群架构(tinc)
常用于中小企业内部网络开发, 如外网服务器负责网络转发到内部公司网络服务器, 将数据功能转发到内网服务器当中, 将数据在广域网缩小成局域网处理.
这里采用 tinc 来搭建内网局域网, 首先这里假设外网服务器 111.111.111.111 来做外网路由, 也就是外网服务器.
注意这里最好对外公网暴露好端口号作为路由接入端口, 建议加入以 7000 做网段, 预留好端口 7000 来做其他内网服务器接入口, 而 7001-7999 则是需要暴露转发的服务.
同时这里注意开启内核转发:
# 查看 ip_forward 转发是否开启
sysctl -a|grep ip_forward
# 首次开启
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
# 启用 tun 设备
sudo modprobe tun
# 确认是否启用成功
ls /dev/net/tun
这里 Ubuntu 环境来做发行版环境, 首先可以安装 tinc :
sudo apt install tinc # 安装 tinc, 主网服务器和子网服务器都要
这里可以查看 tinc 在系统服务配置( /lib/systemd/system/[email protected] ):
[Unit]
Description=Tinc net %i
Documentation=info:tinc
Documentation=man:tinc(8) man:tinc.conf(5)
Documentation=http://tinc-vpn.org/docs/
PartOf=tinc.service
ReloadPropagatedFrom=tinc.service
[Service]
Type=simple
WorkingDirectory=/etc/tinc/%i
EnvironmentFile=/etc/default/tinc
ExecStart=/usr/sbin/tincd -n %i -D $EXTRA
ExecReload=/usr/sbin/tincd -n %i -kHUP
KillMode=mixed
Restart=on-failure
RestartSec=5
TimeoutStopSec=5
[Install]
WantedBy=tinc.service
这里可以看到 WorkingDirectory=/etc/tinc 配置的路径, 所以需要基于这个目录来配置.
还有需要注意很多云服务器商的 ufw 防火墙默认开启, 所以需要记得放行端口:
sudo ufw allow 7000/tcp
sudo ufw allow 7000/udp
sudo ufw reload
配置外网
这里假设虚拟内网名为 vps, 以此创建配置服务:
/etc/tinc
└── vps
├── hosts
│ └── vps
├── rsa_key.priv
├── tinc.conf
├── tinc-down
└── tinc-up
文件配置:
tinc.conf为 tincnet 的配置文件,tinc-up为启动该网络时自动执行的脚本tinc-down为关闭该网络时自动执行的脚本hosts文件夹保存着各个节点(路由器)的信息。
按这种方式来做配置:
# 创建配置目录
sudo mkdir /etc/tinc/vps
sudo mkdir /etc/tinc/vps/hosts
# 编写配置文件
sudo vim /etc/tinc/vps/tinc.conf
/etc/tinc/vps/tinc.conf 配置文件如下:
# 通用配置
Name = vps
Interface = tinc
Autoconnect = yes
# 虚拟网模式
# router / switch / hub ,相对应路由、交换机、集线器
# 默认模式 router
Mode = router
# 压缩数据等级,0 (关闭),1 (fast zlib) 至 9 (best zlib),10 (fast lzo) 和 11 (best lzo)
# 压缩等级越高, 所需要的 CPU 占用性能越大
Compression=9
# 数据加密方式
# 加密方式可选: aes-128-cbc aes-256-cbc
Cipher = aes-256-cbc
# 数据加密强度
# 加密强度可选: sha256 sha128 sha1
Digest = sha256
# 内网挂载配置
Device = /dev/net/tun
# 挂载私钥文件
PrivateKeyFile=/etc/tinc/vps/rsa_key.priv
/etc/tinc/vps/tinc-up 路由挂载脚本:
#!/bin/sh
# 10.7.0.0/24 作为网域, 用 10.7.0.x 是为了配合 7000 端口映射, 具体可以自定义
# 内部虚拟网对外公网主机设置 10.7.0.1, 这就是内网虚拟机的地址
ifconfig $INTERFACE 10.7.0.1 netmask 255.0.0.0
/etc/tinc/vps/tinc-down 路由关闭脚本:
#!/bin/sh
# 关闭虚拟内网
ifconfig $INTERFACE down
这两个脚本需要赋予启动权限:
sudo chmod +x /etc/tinc/vps/tinc-*
编写虚拟内网节点信息:
sudo vim /etc/tinc/vps/hosts/vps # 编写虚拟网主节点配置
主节点配置 /etc/tinc/vps/hosts/vps :
# 主节点公网IP地址, 也就是对外暴露的公网地址
Address = 111.111.111.111
# 主节点公网端口号, 对外的暴露端口
Port = 7000
# 主节点内网地址, 10.7.0.1 这就是配置的虚拟网地址
Subnet = 10.7.0.1/32
之后就是生成密钥在虚拟网:
# 生成密钥强度 4096 的私有密钥, 默认两个回车保存配置
sudo tincd -n vps -K4096
至此服务器配置已经完成, 这时候就是挂载服务器查看:
# 设置服务启动和开机启动
sudo systemctl start tinc.service
sudo systemctl enable tinc.service
sudo systemctl start [email protected]
sudo systemctl enable [email protected]
# 查看服务器是否挂载, 如果有看到挂起 `tinc` 网卡这就是配置完成
sudo ifconfig
# 可以考虑重启下看看是否开机会不会自动部署虚拟内网
# 查看监听端口是否挂起
sudo lsof -i :7000
之后就是客户端配置, 用于给公司/家庭内网组子网.
配置子网
公司/家庭内网只需要配好内网服务器, 之后就是按照之前流程配置再走一遍子网配置.
首先还是配置出新的配置:
/etc/tinc
└── vps
├── hosts
│ ├── vps
│ └── slave_1
├── rsa_key.priv
├── tinc.conf
├── tinc-down
└── tinc-up
新的子网名称为 slave_1 , 这里按照之前流程走遍:
# 创建配置目录
sudo mkdir /etc/tinc/vps
sudo mkdir /etc/tinc/vps/hosts
# 编写配置文件
sudo vim /etc/tinc/vps/tinc.conf
这里注意 /etc/tinc/vps/tinc.conf 是有所变化的:
# 通用配置, 注意 Name 是唯一的, 也就是子网必须修改成其他
# 也就是修改成 slave_1 表示 子网01, 后期扩展其他内网可以推到 slave_2...
Name = slave_1
# 注意,这里需要设置加入主网
ConnectTo = vps
Interface = tinc
Autoconnect = yes
# 虚拟网模式
# router / switch / hub ,相对应路由、交换机、集线器
# 默认模式 router
Mode = router
# 压缩数据等级,0 (关闭),1 (fast zlib) 至 9 (best zlib),10 (fast lzo) 和 11 (best lzo)
# 压缩等级越高, 所需要的 CPU 占用性能越大
Compression=9
# 数据加密方式
# 加密方式可选: aes-128-cbc aes-256-cbc
Cipher = aes-256-cbc
# 数据加密强度
# 加密强度可选: sha256 sha128 sha1
Digest = sha256
# 内网挂载配置
Device = /dev/net/tun
# 挂载私钥文件
PrivateKeyFile=/etc/tinc/vps/rsa_key.priv
/etc/tinc/vps/tinc-up 路由挂载脚本:
#!/bin/sh
# 注意, 这里配置的虚拟网必须是唯一, 也就是虚拟网地址
ifconfig $INTERFACE 10.7.0.2 netmask 255.0.0.0
/etc/tinc/vps/tinc-down 路由关闭脚本, 这个没有什么变化:
#!/bin/sh
# 关闭虚拟内网
ifconfig $INTERFACE down
最后赋予启动权限:
sudo chmod +x /etc/tinc/vps/tinc-*
主节点配置 /etc/tinc/vps/hosts/slave_1, 这就是子网的配置文件:
# 主节点公网IP地址, 也就是对外暴露的公网地址
Address = 111.111.111.111
# 主节点公网端口号, 对外的暴露端口
Port = 7000
# 子节点内网地址, 10.7.0.2 这就是配置的虚拟网地址
Subnet = 10.7.0.2/32
子网也需要生成密钥在虚拟网:
sudo tincd -n vps -K4096
注意
这里需要注意, 访问的时候是只认准 /etc/tinc/vps/hosts 内部交换的配置密钥文件, 所以主网/子网这个目录都需要进行同步.
也就是对外公网和内网的
hosts目录内部文件要一致, 也就是slave_1和vps同步一起, 这是十分关键的步骤.
也就是双方 hosts 需要交换:
# 在主网内部追加子网配置
sudo vim /etc/tinc/vps/hosts/slave_1 # 拷贝 slave_1 内容过去
# 在子网内部追加主网配置
sudo vim /etc/tinc/vps/hosts/vps # 拷贝 vps 内容过去
最后主网/子网重启下就行了:
# 记得主网必须要先重启, 之后设置子网服务启动和开机启动
sudo systemctl start tinc.service
sudo systemctl enable tinc.service
sudo systemctl start [email protected]
sudo systemctl enable [email protected]
测试访问
可以测试在内网服务跑 Nginx 的服务挂起个 7002 服务, 挂载服务( /etc/nginx/conf.d/echo.conf):
server{
# 监听内网服务的端口
listen 10.7.0.2:7002;
location / {
# 设置默认的返回格式
default_type text/html;
# 这里返回 http 为了兼容中文最好添加头信息
add_header Content-Type 'text/html; charset=utf-8';
# 设置返回的内容和状态码( 200 )
return 200 'Access Passed';
}
}
更 Nginx 之后就可以在 10.7.0.1 主网测试访问地址:
# 测试公网内部访问子网的服务,如果能够显示 'Access Passed' 就代表内网已经连接
curl 10.7.0.2:7002
批量端口转发
这里已经对外暴露 7000 端口作为主网监听, 之后主网 7001-7999 就需要把转发到子网的 7001-7999, 这里采用 Nginx 做直接代理转发.
注意云服务内部放行
7001-7999端口TCP服务, 建议预留好映射7022作为主网转发到ssh的地址
Nginx 默认不支持范围端口转发, 所以采用脚本来处理生成配置让 Nginx 加载:
# 所有的操作基于 /etc/nginx 目录处理
cd /etc/nginx
# 创建转发目录
sudo mkdir -p /etc/nginx/stream/7000
# 追加配置目录
sudo vim /etc/nginx/nginx.conf
修改主目录加入 stream 流量转发:
events {
worker_connections 1024;
# multi_accept on;
}
# 流转发配置
stream {
# 加载 7000 服务组服务
include /etc/nginx/stream/7000/*.conf;
# 后续其他服务组再次追加
include /etc/nginx/stream/8000/*.conf;
}
编写脚本处理那些编写流程, 方便来做处理:
sudo vim /etc/nginx/stream-group.sh
编写 /etc/nginx/stream-group.sh 脚本内容:
#!/bin/bash
# root? sudo?
if [ "$UID" -ne 0 ]; then
echo "Script is running as normal user[require: sudo]"
fi
cd $(dirname $0)
ROOT_PATH=$(pwd)
STREAM_PATH="${ROOT_PATH}/stream"
STREAM_FILE="access.conf"
STREAM_HOSTNAME="10.7.0.2"
# directory exists
if [ ! -d $STREAM_PATH ]; then
mkdir $STREAM_PATH
fi
# input group number
while :
do
read -p "Input Stream Group Number[2-64]:" group
if [[ "$group" -gt 1 && "$group" -lt 65 ]]; then
break
else
echo "$group is not between 2 and 64"
fi
done
# backup directory
STREAM_GROUP=$(( $group * 1000))
STREAM_GROUP_PATH="$STREAM_PATH/$STREAM_GROUP"
# directory exists? backup
if [ -d $STREAM_GROUP_PATH ]; then
while :
do
read -p "Backup ${STREAM_GROUP_PATH}[y/n]:" is_bak
if [ "$is_bak" = "y" ]; then
BAK_FILE=${STREAM_GROUP_PATH}_$(date +%Y%m%d)
BAK_FILE="${BAK_FILE}.tar"
tar -cvf $BAK_FILE $STREAM_GROUP_PATH
echo "Backup File: ${BAK_FILE}"
mv -f ${STREAM_GROUP_PATH} /tmp/$STREAM_GROUP
mkdir $STREAM_GROUP_PATH
break
elif [ "$is_bak" = "n" ]; then
rm -rf /tmp/$STREAM_GROUP
mv -f ${STREAM_GROUP_PATH} /tmp/$STREAM_GROUP
mkdir $STREAM_GROUP_PATH
break
fi
done
else
mkdir $STREAM_GROUP_PATH
fi
# write nginx config
STREAM_GROUP_FILE="${STREAM_GROUP_PATH}/${STREAM_FILE}"
touch $STREAM_GROUP_FILE
# each port
STREAM_GROUP_INDEX=$(( $STREAM_GROUP + 1))
STREAM_GROUP_END=$(( $STREAM_GROUP + 999))
while [ $STREAM_GROUP_INDEX -le $STREAM_GROUP_END ]; do
#echo $STREAM_GROUP_INDEX
# write server
echo "# ${STREAM_GROUP_INDEX} BEGIN =====================" >> $STREAM_GROUP_FILE
echo "server {" >> $STREAM_GROUP_FILE
echo " listen ${STREAM_GROUP_INDEX} reuseport;" >> $STREAM_GROUP_FILE
echo " tcp_nodelay on;" >> $STREAM_GROUP_FILE
echo " proxy_pass ${STREAM_HOSTNAME}:${STREAM_GROUP_INDEX};" >> $STREAM_GROUP_FILE
echo "}" >> $STREAM_GROUP_FILE
echo "# ${STREAM_GROUP_INDEX} END =====================" >> $STREAM_GROUP_FILE
echo "" >> $STREAM_GROUP_FILE
echo "" >> $STREAM_GROUP_FILE
STREAM_GROUP_INDEX=$((STREAM_GROUP_INDEX+1))
done
这里设置可执行之后生成配置文件:
sudo chmod +x /etc/nginx/stream-group.sh # 赋予权限
sudo /etc/nginx/stream-group.sh # 执行生成分组, 输入 7 生成 7001-7999的分组数据
# 可以看到 access.conf 配置文件内容
sudo vim /etc/nginx/stream/7000/access.conf
# 没问题重新加载 nginx 即可
sudo systemctl restart nginx.service
# 外网访问私有网络端口, 之前说过访问 111.111.111.111 是外网, 内网服务器开放 7002 端口
# 现在直接可以看下是否转发成功
curl 111.111.111.111:7002
至此就能生成公网代理转发到内网的服务.