Files
wgServer/internal/database/utils.go
2025-10-16 16:27:36 +07:00

145 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package database
import (
"fmt"
"io"
"log"
"net"
"net/http"
"os/exec"
"strings"
)
// CheckWireGuardInstalled проверяет установлен ли WireGuard
func CheckWireGuardInstalled() bool {
cmd := exec.Command("which", "wg")
err := cmd.Run()
return err == nil
}
// GenerateKeys генерирует пару ключей WireGuard
func GenerateKeys() (privateKey, publicKey string, err error) {
// Генерируем приватный ключ
cmd := exec.Command("wg", "genkey")
privateKeyBytes, err := cmd.Output()
if err != nil {
return "", "", err
}
privateKey = strings.TrimSpace(string(privateKeyBytes))
// Генерируем публичный ключ из приватного
cmd = exec.Command("wg", "pubkey")
cmd.Stdin = strings.NewReader(privateKey)
publicKeyBytes, err := cmd.Output()
if err != nil {
return "", "", err
}
publicKey = strings.TrimSpace(string(publicKeyBytes))
return privateKey, publicKey, nil
}
// GetNextClientIP возвращает следующий доступный IP адрес для клиента
func GetNextClientIP(server *Server) string {
// Парсим адрес сервера (например 10.0.0.1/24)
parts := strings.Split(server.Address, "/")
if len(parts) != 2 {
return ""
}
ipParts := strings.Split(parts[0], ".")
if len(ipParts) != 4 {
return ""
}
// Формируем IP клиента
ip := fmt.Sprintf("%s.%s.%s.%d", ipParts[0], ipParts[1], ipParts[2], server.NextClientIP)
server.NextClientIP++
return ip
}
// GetServerEndpoint получает внешний IP адрес сервера
func GetServerEndpoint() string {
// Пробуем получить внешний IP
resp, err := http.Get("https://api.ipify.org")
if err == nil {
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err == nil {
return string(body)
}
}
// Если не получилось, возвращаем локальный IP
return GetLocalIP()
}
// GetLocalIP получает локальный IP адрес
func GetLocalIP() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "127.0.0.1"
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String()
}
}
}
return "127.0.0.1"
}
// GetDefaultInterface получает основной сетевой интерфейс для интернета
func GetDefaultInterface() string {
// Пытаемся определить через маршруты
cmd := exec.Command("sh", "-c", "ip route | grep default | awk '{print $5}' | head -n1")
output, err := cmd.Output()
if err == nil && len(output) > 0 {
iface := strings.TrimSpace(string(output))
if iface != "" {
return iface
}
}
// Пробуем альтернативный способ
cmd = exec.Command("sh", "-c", "ip -4 route ls | grep default | grep -Po '(?<=dev )\\S+' | head -n1")
output, err = cmd.Output()
if err == nil && len(output) > 0 {
iface := strings.TrimSpace(string(output))
if iface != "" {
return iface
}
}
// Возвращаем eth0 по умолчанию
log.Println("⚠️ Не удалось определить сетевой интерфейс, использую eth0")
return "eth0"
}
// EnableIPForwarding включает IP forwarding в системе
func EnableIPForwarding() error {
// Временно включаем
cmd := exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("sysctl failed: %v, output: %s", err, string(output))
}
// Проверяем что включилось
cmd = exec.Command("cat", "/proc/sys/net/ipv4/ip_forward")
output, err = cmd.Output()
if err == nil {
value := strings.TrimSpace(string(output))
if value != "1" {
return fmt.Errorf("IP forwarding не включился, значение: %s", value)
}
}
// Делаем постоянным
cmd = exec.Command("sh", "-c", "grep -q 'net.ipv4.ip_forward' /etc/sysctl.conf || echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf")
return cmd.Run()
}