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

77 lines
2.6 KiB
Go

package wireguard
import (
"log"
"os/exec"
"wg-panel/internal/database"
)
// ApplyWireGuardIPTablesRules применяет правила iptables для WireGuard сервера
func ApplyWireGuardIPTablesRules(server *database.Server) error {
netInterface := database.GetDefaultInterface()
iface := server.Interface
network := getNetworkFromAddress(server.Address)
log.Printf(" 🔧 Применяю правила iptables для %s (сеть: %s, интерфейс: %s)...", iface, network, netInterface)
// Правила FORWARD
commands := [][]string{
{"iptables", "-I", "FORWARD", "1", "-i", iface, "-j", "ACCEPT"},
{"iptables", "-I", "FORWARD", "1", "-o", iface, "-j", "ACCEPT"},
{"iptables", "-t", "nat", "-A", "POSTROUTING", "-s", network, "-o", netInterface, "-j", "MASQUERADE"},
}
for i, cmdArgs := range commands {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
output, err := cmd.CombinedOutput()
if err != nil {
log.Printf(" ⚠️ Команда #%d %v: %v (output: %s)", i+1, cmdArgs, err, string(output))
} else {
log.Printf(" ✅ Команда #%d выполнена: %v", i+1, cmdArgs)
}
}
log.Printf(" ✅ Правила iptables применены")
return nil
}
// RemoveWireGuardIPTablesRules удаляет правила iptables для WireGuard сервера
func RemoveWireGuardIPTablesRules(server *database.Server) error {
netInterface := database.GetDefaultInterface()
iface := server.Interface
log.Printf(" 🗑️ Удаляю правила iptables для %s...", iface)
commands := [][]string{
{"iptables", "-D", "FORWARD", "-i", iface, "-j", "ACCEPT"},
{"iptables", "-D", "FORWARD", "-o", iface, "-j", "ACCEPT"},
{"iptables", "-t", "nat", "-D", "POSTROUTING", "-s", getNetworkFromAddress(server.Address), "-o", netInterface, "-j", "MASQUERADE"},
}
for _, cmdArgs := range commands {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Run() // Игнорируем ошибки
}
return nil
}
// getNetworkFromAddress извлекает подсеть из адреса типа "10.0.0.1/24" -> "10.0.0.0/24"
func getNetworkFromAddress(address string) string {
// Простая реализация - заменяем последний октет на 0
parts := address[:len(address)-1] // убираем последнюю цифру
// Находим последнюю точку
lastDot := -1
for i := len(parts) - 1; i >= 0; i-- {
if parts[i] == '.' {
lastDot = i
break
}
}
if lastDot > 0 {
return parts[:lastDot+1] + "0" + address[len(address)-3:] // +0 и маска
}
return address
}