174 lines
4.3 KiB
Go
174 lines
4.3 KiB
Go
package utils
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"github.com/spf13/cast"
|
||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||
"math/rand"
|
||
"os"
|
||
"slices"
|
||
"strings"
|
||
"wireguard-dashboard/client"
|
||
"wireguard-dashboard/model/entity"
|
||
"wireguard-dashboard/model/template_data"
|
||
"wireguard-dashboard/model/vo"
|
||
)
|
||
|
||
type wireguard struct{}
|
||
|
||
func Wireguard() wireguard {
|
||
return wireguard{}
|
||
}
|
||
|
||
// GetSpecClient
|
||
// @description: 获取指定客户端链接信息
|
||
// @receiver wireguard
|
||
// @param pk
|
||
// @return *wgtypes.Peer
|
||
// @return error
|
||
func (wireguard) GetSpecClient(pk string) (*wgtypes.Peer, error) {
|
||
device, err := client.WireguardClient.Devices()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
for _, v := range device {
|
||
for _, p := range v.Peers {
|
||
if p.PublicKey.String() == pk {
|
||
return &p, nil
|
||
}
|
||
}
|
||
}
|
||
|
||
return nil, nil
|
||
}
|
||
|
||
// GenerateClientIP
|
||
// @description: 生成客户端IP
|
||
// @receiver wireguard
|
||
// @param serverIP
|
||
// @param rule
|
||
// @return string
|
||
func (w wireguard) GenerateClientIP(serverIP, rule string, assignedIPS ...string) string {
|
||
// 再次拆分,只取最后一段
|
||
suffix := w.GetIPSuffix(serverIP)
|
||
prefix := w.GetIPPrefix(serverIP)
|
||
// 如果是随机模式,则需要结尾数字小于等于 255,并且生成的数字不能是已分配当中任何一个
|
||
// 如果是自动模式,只需要是已经分配的最后一位自增
|
||
switch rule {
|
||
case "RANDOM":
|
||
suffix = w.random(assignedIPS...)
|
||
case "AUTO":
|
||
switch len(assignedIPS) {
|
||
case 1:
|
||
suffix = w.GetIPSuffix(assignedIPS[0])
|
||
case 2:
|
||
suffix = w.GetIPSuffix(assignedIPS[1])
|
||
}
|
||
|
||
suffix = cast.ToString(cast.ToInt64(suffix) + 1)
|
||
}
|
||
|
||
return fmt.Sprintf("%s.%s", prefix, suffix)
|
||
}
|
||
|
||
// GenerateClientFile
|
||
// @description: 生成客户端临时配置文件
|
||
// @receiver w
|
||
// @param clientInfo
|
||
// @param setting
|
||
// @return tmpFilePath
|
||
// @return err
|
||
func (w wireguard) GenerateClientFile(clientInfo *entity.Client, setting *vo.ServerSetting) (tmpFilePath string, err error) {
|
||
var keys template_data.Keys
|
||
_ = json.Unmarshal([]byte(clientInfo.Keys), &keys)
|
||
|
||
var serverDNS []string
|
||
if *clientInfo.UseServerDns == 1 {
|
||
serverDNS = setting.DnsServer
|
||
}
|
||
|
||
// 处理一下数据
|
||
execData := template_data.ClientConfig{
|
||
PrivateKey: keys.PrivateKey,
|
||
IpAllocation: clientInfo.IpAllocation,
|
||
MTU: setting.MTU,
|
||
DNS: strings.Join(serverDNS, ","),
|
||
PublicKey: clientInfo.Server.PublicKey,
|
||
PresharedKey: keys.PresharedKey,
|
||
AllowedIPS: clientInfo.AllowedIps,
|
||
Endpoint: setting.EndpointAddress,
|
||
ListenPort: clientInfo.Server.ListenPort,
|
||
PersistentKeepalive: setting.PersistentKeepalive,
|
||
}
|
||
|
||
// 不同环境下处理文件路径
|
||
var outPath = "/tmp/" + fmt.Sprintf("%s.conf", clientInfo.Name)
|
||
var templatePath = "./template/wg.client.conf"
|
||
if os.Getenv("GIN_MODE") != "release" {
|
||
outPath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\" + fmt.Sprintf("%s.conf", clientInfo.Name)
|
||
templatePath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\wg.client.conf"
|
||
}
|
||
|
||
// 渲染数据
|
||
parseTemplate, err := Template().Parse(templatePath)
|
||
if err != nil {
|
||
return "", errors.New("读取模板文件失败")
|
||
}
|
||
|
||
err = Template().Execute(parseTemplate, execData, outPath)
|
||
if err != nil {
|
||
return "", errors.New("文件渲染失败")
|
||
}
|
||
|
||
return outPath, nil
|
||
}
|
||
|
||
// random
|
||
// @description: 随机模式
|
||
// @receiver w
|
||
// @param assignedIPS
|
||
// @return string
|
||
func (w wireguard) random(assignedIPS ...string) string {
|
||
randomNumber := rand.Int63n(256)
|
||
var assuffixIP []int64
|
||
for _, v := range assignedIPS {
|
||
assuffixIP = append(assuffixIP, cast.ToInt64(strings.Split(v, ".")[3]))
|
||
}
|
||
|
||
if slices.Contains(assuffixIP, randomNumber) {
|
||
return w.random(assignedIPS...)
|
||
}
|
||
|
||
return cast.ToString(randomNumber)
|
||
}
|
||
|
||
// GetIPSuffix
|
||
// @description: 获取IP后缀 [10.10.10.23] 这里只获取23
|
||
// @receiver w
|
||
// @param ip
|
||
// @return string
|
||
func (w wireguard) GetIPSuffix(ip string) string {
|
||
if strings.Contains(ip, "/") {
|
||
ip = strings.Split(ip, "/")[0]
|
||
}
|
||
|
||
// 再次拆分,只取最后一段
|
||
return strings.Split(ip, ".")[3]
|
||
}
|
||
|
||
// GetIPPrefix
|
||
// @description: 获取IP前缀[10.10.10.23] 这里只获取 10.10.10
|
||
// @receiver w
|
||
// @param ip
|
||
// @return string
|
||
func (w wireguard) GetIPPrefix(ip string) string {
|
||
if strings.Contains(ip, "/") {
|
||
ip = strings.Split(ip, "/")[0]
|
||
}
|
||
|
||
return strings.Join(strings.Split(ip, ".")[:3], ".")
|
||
}
|