Инициализация проекта

Всем привет :)
This commit is contained in:
2025-10-16 16:27:36 +07:00
commit 0e93af1d8c
23 changed files with 4058 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
package wireguard
import (
"fmt"
"log"
"os/exec"
"wg-panel/internal/database"
)
// isPortAvailable проверяет доступен ли порт
func isPortAvailable(db *database.Database, port int, protocol string) bool {
protocols := []string{protocol}
if protocol == "both" {
protocols = []string{"tcp", "udp", "both"}
}
for _, client := range db.Clients {
for _, pf := range client.PortForwards {
if pf.Port == port {
// Проверяем конфликт протоколов
if pf.Protocol == "both" || protocol == "both" {
return false
}
for _, p := range protocols {
if pf.Protocol == p {
return false
}
}
}
}
}
return true
}
// AddPortForward добавляет проброс порта для клиента
func AddPortForward(db *database.Database, client *database.Client, port int, protocol, description string) error {
// Проверяем что порт свободен
if !isPortAvailable(db, port, protocol) {
return fmt.Errorf("порт %d/%s уже используется", port, protocol)
}
// Добавляем в список
portForward := database.PortForward{
Port: port,
Protocol: protocol,
Description: description,
}
client.PortForwards = append(client.PortForwards, portForward)
// Применяем правила iptables если клиент активен
if client.Enabled {
if err := applyPortForwardRules(client, portForward); err != nil {
return err
}
}
return nil
}
// updatePortForward обновляет проброс порта
func updatePortForward(client *database.Client, port int, protocol, newDescription string) error {
for i, pf := range client.PortForwards {
if pf.Port == port && pf.Protocol == protocol {
client.PortForwards[i].Description = newDescription
return nil
}
}
return fmt.Errorf("проброс порта не найден")
}
// RemovePortForward удаляет проброс порта
func RemovePortForward(client *database.Client, port int, protocol string) error {
// Находим и удаляем проброс
for i, pf := range client.PortForwards {
if pf.Port == port && pf.Protocol == protocol {
// Удаляем правила iptables
if client.Enabled {
removePortForwardRules(client, pf)
}
// Удаляем из списка
client.PortForwards = append(client.PortForwards[:i], client.PortForwards[i+1:]...)
return nil
}
}
return fmt.Errorf("проброс порта не найден")
}
// applyPortForwardRules применяет правила iptables для проброса порта
func applyPortForwardRules(client *database.Client, pf database.PortForward) error {
log.Printf(" 🔀 Применяю проброс порта %d (%s)", pf.Port, pf.Protocol)
netInterface := database.GetDefaultInterface()
protocols := []string{pf.Protocol}
if pf.Protocol == "both" {
protocols = []string{"tcp", "udp"}
}
for _, proto := range protocols {
commands := [][]string{
// DNAT только для пакетов приходящих с внешнего интерфейса
{"iptables", "-t", "nat", "-A", "PREROUTING", "-i", netInterface, "-p", proto,
"--dport", fmt.Sprintf("%d", pf.Port), "-j", "DNAT",
"--to-destination", fmt.Sprintf("%s:%d", client.Address, pf.Port)},
// Разрешаем FORWARD для этого порта
{"iptables", "-I", "FORWARD", "1", "-p", proto, "-d", client.Address,
"--dport", fmt.Sprintf("%d", pf.Port), "-j", "ACCEPT"},
}
for _, cmdArgs := range commands {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
output, err := cmd.CombinedOutput()
if err != nil {
log.Printf(" ⚠️ Ошибка: %v (output: %s)", err, string(output))
return err
}
}
}
log.Printf(" ✅ Проброс порта настроен")
return nil
}
// removePortForwardRules удаляет правила iptables для проброса порта
func removePortForwardRules(client *database.Client, pf database.PortForward) error {
netInterface := database.GetDefaultInterface()
protocols := []string{pf.Protocol}
if pf.Protocol == "both" {
protocols = []string{"tcp", "udp"}
}
for _, proto := range protocols {
commands := [][]string{
{"iptables", "-t", "nat", "-D", "PREROUTING", "-i", netInterface, "-p", proto,
"--dport", fmt.Sprintf("%d", pf.Port), "-j", "DNAT",
"--to-destination", fmt.Sprintf("%s:%d", client.Address, pf.Port)},
{"iptables", "-D", "FORWARD", "-p", proto, "-d", client.Address,
"--dport", fmt.Sprintf("%d", pf.Port), "-j", "ACCEPT"},
}
for _, cmdArgs := range commands {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Run() // Игнорируем ошибки при удалении
}
}
return nil
}
// ApplyAllPortForwards применяет все пробросы портов для клиента
func ApplyAllPortForwards(client *database.Client) error {
if !client.Enabled {
return nil
}
for _, pf := range client.PortForwards {
if err := applyPortForwardRules(client, pf); err != nil {
log.Printf(" ⚠️ Ошибка проброса порта %d: %v", pf.Port, err)
}
}
return nil
}
// removeAllPortForwards удаляет все пробросы портов для клиента
func removeAllPortForwards(client *database.Client) error {
for _, pf := range client.PortForwards {
removePortForwardRules(client, pf)
}
return nil
}