Files
forge/internal/controller/maker/hsnet.go
2026-01-07 18:55:22 +08:00

370 lines
11 KiB
Go

package maker
import (
"context"
"os"
"path/filepath"
"gitea.loveuer.com/yizhisec/pkg3/logger"
"yizhisec.com/hsv2/forge/pkg/archiver"
"yizhisec.com/hsv2/forge/pkg/resource"
)
func (m *maker) HSNet(ctx context.Context) error {
const (
_service = `[Unit]
Description=hs-net Container Service
Documentation=https://docs.containerd.io
After=network.target containerd.service
[Service]
# 启动前清理旧容器
ExecStartPre=-/usr/local/bin/k0s ctr -n hs-net task kill hs-net
ExecStartPre=-/usr/local/bin/k0s ctr namespace create hs-net
ExecStartPre=-/usr/local/bin/k0s ctr -n hs-net container rm hs-net
# 拉取最新镜像(按需启用/注释)
# ExecStartPre=/usr/local/bin/k0s ctr -n hs-net images pull hub.yizhisec.com/hybridscope/hsnet:release_2.1.0-std
# 容器启动命令
ExecStart=/usr/local/bin/k0s ctr -n hs-net run \
--net-host \
--privileged \
--env LD_LIBRARY_PATH=/yizhisec/hs_net \
--env RUST_BACKTRACE=1 \
--mount type=bind,src=/etc/localtime,dst=/etc/localtime,options=rbind:ro \
--mount type=bind,src=/etc/hosts,dst=/etc/hosts,options=rbind:ro \
--mount type=bind,src=/etc/yizhisec,dst=/etc/yizhisec,options=rbind:rw \
--mount type=bind,src=/tmp,dst=/tmp,options=rbind:rw \
--mount type=bind,src=/etc/yosguard/uuid,dst=/etc/gateway/uuid.json,options=rbind:ro \
--mount type=bind,src=/mnt/huge,dst=/mnt/huge,options=rbind:rw \
--mount type=bind,src=/var/run,dst=/var/run,options=rbind:rw \
--mount type=bind,src=/yizhisec,dst=/yizhisec,options=rbind:rw \
--mount type=bind,src=/yizhisec/hs_net/conf,dst=/etc/hs_net,options=rbind:rw \
hub.yizhisec.com/hybridscope/hsnet:release_2.1.0-std hs-net
# --cgroup host \
# --env RUSTFLAGS="-C target-cpu=nehalem" \
# 重启策略
Restart=always
RestartSec=5s
# 资源限制(按需调整)
MemoryLimit=2G
CPUQuota=80%
# 日志处理(将容器 stdout/stderr 交由 journald 管理)
StandardOutput=journal
StandardError=journal
SyslogIdentifier=hs-net
# 清理退出的容器
ExecStop=/usr/local/bin/k0s ctr -n hs-net task kill hs-net
ExecStopPost=/usr/local/bin/k0s ctr -n hs-net container rm hs-net
[Install]
WantedBy=multi-user.target`
_conf_out = `log:
level: info
controller:
protocol: https
registerHost: hs-gateway-register-controller
host: hs-gateway-controller
port: 443
tokenFilePath: /etc/yizhisec/token
registerRetry: 30
wg:
private_key: qPfOaNKrV11kzaGQiNQNyiu6wMQGUpIM+/xqboVAnng=
private_network: 246.0.0.1/8
listen_port: 23209
mtu: 1300
obf_key: 0
keep_alive: 61
tun_name: wg_tun
yosGuard:
host: __ip__
port: 7788
mqtt:
protocol: tls
host: mqtt.yizhisec.com
port: '443'
cert: /yizhisec/hs_net/conf/ssl/mqtt.client.crt
key: /yizhisec/hs_net/conf/ssl/mqtt.client.key
keep_alive: 60
paseto_key: TtKVnSzEHO3jRv/GWg3f5k3H1OVfMnPZ1Ke9E6MSCXk=
resource_server: hs-gateway-controller
dns_cache:
Address: 127.0.0.1:9028
gatewayVersionFile: /etc/yizhisec/gateway_version.json
lastVersion: null
workDir: /yizhisec/hs_net/workspace
eth_names: []
tag: ''
cluster_mock: ''
openobserve_uri: ''
tcp_mode_disable: false
`
_conf_in = `{
"LogLevel": "info",
"LogFile": "/yizhisec/hs_net/workspace/log/wireguard",
"DnsVirtNetwork": null,
"DnsVirtNetworkV6": null,
"Foreground": false,
"WithPprof": false,
"DnsCache": {
"Address": "127.0.0.1:9028"
},
"log": {
"level": "info"
},
"yosGuard": {
"host": "__ip__",
"port": 7788
},
"controller": {
"protocol": "https",
"host": "hs-gateway-controller",
"registerHost": "hs-gateway-register-controller",
"port": 443,
"registerRetry": 30,
"tokenFilePath": "/etc/yizhisec/token"
},
"wg": {
"private_key": "qPfOaNKrV11kzaGQiNQNyiu6wMQGUpIM+/xqboVAnng=",
"private_network": "246.0.0.1/8",
"listen_port": 23209,
"mtu": 1380,
"obf_key": 0,
"keep_alive": 60,
"tun_name": "wg_tun"
},
"mqtt": {
"protocol": "tls",
"host": "mqtt.yizhisec.com",
"port": 443,
"cert": "/yizhisec/hs_net/conf/ssl/mqtt.client.crt",
"key": "/yizhisec/hs_net/conf/ssl/mqtt.client.key",
"keep_alive": 60
},
"paseto_key": "TtKVnSzEHO3jRv/GWg3f5k3H1OVfMnPZ1Ke9E6MSCXk=",
"resource_server": "hs-gateway-controller",
"gatewayVersionFile": "/etc/yizhisec/gateway_version.json",
"lastVersion": null,
"workDir": "/yizhisec/hs_net/workspace",
"dns_cache": {
"Address": "127.0.0.1:9028"
}
}
`
_url = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_net/release/2.1.0-std/package.tar.gz"
)
var (
err error
workdir = filepath.Join(m.workdir, "dependency", "hs_net")
)
logger.Info("☑️ MakeHSNet: 开始构建 hs-net, workdir = %s", workdir)
_ = os.RemoveAll(workdir)
if err = os.MkdirAll(workdir, 0755); err != nil {
logger.Debug("❌ MakeHSNet: 创建目录失败: %s", err.Error())
return err
}
// {Name: "", Fallback: "", Save: "app.less_dns.tar", Force: true},
imgName := "hub.yizhisec.com/hybridscope/hsnet:release_2.1.0-std"
logger.Debug("☑️ maker.HSNet: start pull image = %s", imgName)
if err = m.Image(ctx, imgName,
WithImageForcePull(true),
WithImageSave(filepath.Join(workdir, "hsnet.tar")),
); err != nil {
logger.Debug("❌ maker.HSNet: 拉取镜像失败: %v", err)
return err
}
logger.Debug("✅ maker.HSNet: pull image success = %s", imgName)
imgName = "hub.yizhisec.com/hybridscope/less_dns_service:latest"
logger.Debug("☑️ maker.HSNet: start pull image = %s", imgName)
if err = m.Image(ctx, imgName,
WithImageForcePull(true),
WithImageSave(filepath.Join(workdir, "less-dns.tar")),
); err != nil {
logger.Debug("❌ maker.HSNet: 拉取镜像失败: %v", err)
return err
}
logger.Debug("✅ maker.HSNet: pull image success = %s", imgName)
if err = archiver.DownloadAndExtract(ctx, _url, workdir); err != nil {
logger.Debug("❌ MakeHSNet: 下载和解压失败: %s", err.Error())
return err
}
// mv workdir/package/server workdir/
// mv workdir/package/server_aes workdir/
if err = os.Rename(filepath.Join(workdir, "package", "server"), filepath.Join(workdir, "server")); err != nil {
logger.Debug("❌ MakeHSNet: 重命名文件失败: %s", err.Error())
return err
}
if err = os.Rename(filepath.Join(workdir, "package", "server_aes"), filepath.Join(workdir, "server_aes")); err != nil {
logger.Debug("❌ MakeHSNet: 重命名文件失败: %s", err.Error())
return err
}
// write down conf_out to server.conf
if err = os.WriteFile(filepath.Join(workdir, "server.conf"), []byte(_conf_out), 0644); err != nil {
logger.Debug("❌ MakeHSNet: 写入配置文件失败: %s", err.Error())
return err
}
// write down conf_in to conf/server.conf
if err = os.MkdirAll(filepath.Join(workdir, "conf", "ssl"), 0755); err != nil {
logger.Debug("❌ MakeHSNet: 创建目录失败: %s", err.Error())
return err
}
if err = os.WriteFile(filepath.Join(workdir, "conf", "server.conf"), []byte(_conf_in), 0644); err != nil {
logger.Debug("❌ MakeHSNet: 写入配置文件失败: %s", err.Error())
return err
}
// write resource.SSLMQTTClientCrt
if err = os.WriteFile(filepath.Join(workdir, "conf", "ssl", "mqtt.client.crt"), resource.SSLMQTTClientCrt, 0644); err != nil {
logger.Debug("❌ MakeHSNet: 写入配置文件失败: %s", err.Error())
return err
}
if err = os.WriteFile(filepath.Join(workdir, "conf", "ssl", "mqtt.client.key"), resource.SSLMQTTClientKey, 0644); err != nil {
logger.Debug("❌ MakeHSNet: 写入配置文件失败: %s", err.Error())
return err
}
// mkdir workspace
if err = os.MkdirAll(filepath.Join(workdir, "workspace"), 0755); err != nil {
logger.Debug("❌ MakeHSNet: 创建目录失败: %s", err.Error())
return err
}
// new empty file lastVersion.txt
if err = os.WriteFile(filepath.Join(workdir, "lastVersion.txt"), []byte{}, 0644); err != nil {
logger.Debug("❌ MakeHSNet: 创建空文件失败: %s", err.Error())
return err
}
// write hs-net.service
if err = os.WriteFile(filepath.Join(workdir, "hs-net.service"), []byte(_service), 0644); err != nil {
logger.Debug("❌ MakeHSNet: 写入服务文件失败: %s", err.Error())
return err
}
// upsert.sh script
const _upsert = `#!/bin/bash
set -e
echo "Starting hs-net deployment..."
# 1. Copy token file
echo "Copying token file..."
mkdir -p /etc/yizhisec
cp ../../configmap/token /etc/yizhisec/token
echo "Token file copied successfully"
# 2. Get local IP address
echo "Detecting local IP address..."
LocalIP=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+')
if [ -z "$LocalIP" ]; then
echo "Error: Failed to detect local IP address"
exit 1
fi
echo "Local IP detected: $LocalIP"
# 3. Update /etc/hosts with required entries
echo "Updating /etc/hosts..."
for host in "hs-gateway-register-controller" "hs-gateway-controller" "mqtt.yizhisec.com"; do
if grep -q "$host" /etc/hosts; then
sed -i "/$host/d" /etc/hosts
fi
echo "$LocalIP $host" >> /etc/hosts
echo "Added: $LocalIP $host"
done
echo "/etc/hosts updated successfully"
# 4. Replace __ip__ in server.conf
echo "Updating server.conf..."
sed -i "s/__ip__/$LocalIP/g" server.conf
echo "server.conf updated successfully"
# 5. Replace __ip__ in conf/server.conf
echo "Updating conf/server.conf..."
sed -i "s/__ip__/$LocalIP/g" conf/server.conf
echo "conf/server.conf updated successfully"
# 6. Create /mnt/huge directory
echo "Creating /mnt/huge directory..."
mkdir -p /mnt/huge
echo "/mnt/huge directory created successfully"
# 7. Create workspace directories
echo "Creating workspace directories..."
mkdir -p /yizhisec/hs_net/workspace/log
mkdir -p /yizhisec/hs_net/conf
echo "Workspace directories created successfully"
# 8. Copy configuration files
echo "Copying configuration files..."
cp -r conf/* /yizhisec/hs_net/conf/
echo "Configuration files copied successfully"
# 9. Copy binaries based on CPU AVX support
echo "Detecting CPU AVX support..."
if grep -q avx /proc/cpuinfo; then
echo "AVX support detected, using server_aes"
cp server_aes /yizhisec/hs_net/server
chmod +x /yizhisec/hs_net/server
echo "server_aes copied to /yizhisec/hs_net/server with execute permission"
else
echo "AVX not supported, using server"
cp server /yizhisec/hs_net/server
chmod +x /yizhisec/hs_net/server
echo "server copied to /yizhisec/hs_net/server with execute permission"
fi
echo "Binary copied successfully"
# 10. Copy lastVersion.txt
echo "Copying lastVersion.txt..."
cp lastVersion.txt /yizhisec/hs_net/
echo "lastVersion.txt copied successfully"
# 11. Load container image
echo "Loading hs-net container image..."
k0s ctr -n hs-net images import hs-net.tar
echo "Container image loaded successfully"
# 12. Install and enable systemd service
echo "Installing hs-net systemd service..."
cp hs-net.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable hs-net.service
echo "hs-net service installed and enabled"
# 13. Start the service
echo "Starting hs-net service..."
systemctl restart hs-net.service
echo "hs-net service started successfully"
echo "hs-net deployment completed successfully!"
echo "You can check the service status with: systemctl status hs-net.service"
`
// Write upsert.sh
logger.Debug("☑️ MakeHSNet: 写入 upsert.sh 脚本...")
if err = os.WriteFile(filepath.Join(workdir, "upsert.sh"), []byte(_upsert), 0755); err != nil {
logger.Debug("❌ MakeHSNet: 写入 upsert.sh 失败: %s", err.Error())
return err
}
logger.Debug("✅ MakeHSNet: 写入 upsert.sh 成功")
logger.Info("✅ MakeHSNet: 构建 hs-net 成功, workdir = %s", workdir)
return nil
}