package maker import ( "context" "os" "path/filepath" "yizhisec.com/hsv2/forge/pkg/archiver" "yizhisec.com/hsv2/forge/pkg/logger" "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 }