package main import ( "fmt" "os" "os/exec" "regexp" "strconv" ) func getDefaultInterface() (string, error) { cmd := exec.Command("ip", "route", "get", "8.8.8.8") output, err := cmd.Output() if err != nil { return "", fmt.Errorf("ошибка при получении интерфейса: %v", err) } re := regexp.MustCompile(`dev (\S+)`) match := re.FindStringSubmatch(string(output)) if len(match) < 2 { return "", fmt.Errorf("интерфейс не найден") } fmt.Printf("[+] Используется интерфейс: %s\n", match[1]) return match[1], nil } func runCmd(command string) { fmt.Printf("[~] %s\n", command) cmd := exec.Command("bash", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() if err != nil { fmt.Fprintf(os.Stderr, "[-] Ошибка выполнения: %v\n", err) } } func main() { if len(os.Args) < 3 { fmt.Println("Использование: --port PORT [--limit SPEED] [--default-rate SPEED]") os.Exit(1) } args := parseArgs() port, err := strconv.Atoi(args["port"]) if err != nil { fmt.Println("[-] Порт должен быть числом") os.Exit(1) } iface, err := getDefaultInterface() if err != nil { fmt.Println("[-] " + err.Error()) os.Exit(1) } classID := fmt.Sprintf("1:%d", 20+port%1000) runCmd(fmt.Sprintf("tc qdisc add dev %s root handle 1: htb default 10 || true", iface)) runCmd(fmt.Sprintf("tc class add dev %s parent 1: classid 1:10 htb rate %s || true", iface, args["default-rate"])) runCmd(fmt.Sprintf("tc class add dev %s parent 1: classid %s htb rate %s ceil %s || true", iface, classID, args["limit"], args["limit"])) runCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -p tcp --sport %d -j CLASSIFY --set-class %s || true", port, classID)) runCmd(fmt.Sprintf("iptables -t mangle -A OUTPUT -p tcp --sport %d -j CLASSIFY --set-class %s", port, classID)) fmt.Printf("[+] Ограничение %s для порта %d успешно установлено!\n", args["limit"], port) } func parseArgs() map[string]string { args := map[string]string{ "limit": "10mbit", "default-rate": "1000mbit", } for i := 1; i < len(os.Args); i++ { if os.Args[i] == "--port" && i+1 < len(os.Args) { args["port"] = os.Args[i+1] i++ } else if os.Args[i] == "--limit" && i+1 < len(os.Args) { args["limit"] = os.Args[i+1] i++ } else if os.Args[i] == "--default-rate" && i+1 < len(os.Args) { args["default-rate"] = os.Args[i+1] i++ } } if _, ok := args["port"]; !ok { fmt.Println("[-] Не указан порт (--port)") os.Exit(1) } return args } Код package main import ( "fmt" "os" "os/exec" "regexp" "strconv" ) func getDefaultInterface() (string, error) { cmd := exec.Command("ip", "route", "get", "8.8.8.8") output, err := cmd.Output() if err != nil { return "", fmt.Errorf("ошибка при получении интерфейса: %v", err) } re := regexp.MustCompile(`dev (\S+)`) match := re.FindStringSubmatch(string(output)) if len(match) < 2 { return "", fmt.Errorf("интерфейс не найден") } fmt.Printf("[+] Используется интерфейс: %s\n", match[1]) return match[1], nil } func runCmd(command string) { fmt.Printf("[~] %s\n", command) cmd := exec.Command("bash", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() if err != nil { fmt.Fprintf(os.Stderr, "[-] Ошибка выполнения: %v\n", err) } } func main() { if len(os.Args) < 3 { fmt.Println("Использование: --port PORT [--limit SPEED] [--default-rate SPEED]") os.Exit(1) } args := parseArgs() port, err := strconv.Atoi(args["port"]) if err != nil { fmt.Println("[-] Порт должен быть числом") os.Exit(1) } iface, err := getDefaultInterface() if err != nil { fmt.Println("[-] " + err.Error()) os.Exit(1) } classID := fmt.Sprintf("1:%d", 20+port%1000) runCmd(fmt.Sprintf("tc qdisc add dev %s root handle 1: htb default 10 || true", iface)) runCmd(fmt.Sprintf("tc class add dev %s parent 1: classid 1:10 htb rate %s || true", iface, args["default-rate"])) runCmd(fmt.Sprintf("tc class add dev %s parent 1: classid %s htb rate %s ceil %s || true", iface, classID, args["limit"], args["limit"])) runCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -p tcp --sport %d -j CLASSIFY --set-class %s || true", port, classID)) runCmd(fmt.Sprintf("iptables -t mangle -A OUTPUT -p tcp --sport %d -j CLASSIFY --set-class %s", port, classID)) fmt.Printf("[+] Ограничение %s для порта %d успешно установлено!\n", args["limit"], port) } func parseArgs() map[string]string { args := map[string]string{ "limit": "10mbit", "default-rate": "1000mbit", } for i := 1; i < len(os.Args); i++ { if os.Args[i] == "--port" && i+1 < len(os.Args) { args["port"] = os.Args[i+1] i++ } else if os.Args[i] == "--limit" && i+1 < len(os.Args) { args["limit"] = os.Args[i+1] i++ } else if os.Args[i] == "--default-rate" && i+1 < len(os.Args) { args["default-rate"] = os.Args[i+1] i++ } } if _, ok := args["port"]; !ok { fmt.Println("[-] Не указан порт (--port)") os.Exit(1) } return args }