127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package main
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"log"
|
||
"os/exec"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
func createIPSet(setName string) error {
|
||
cmd := exec.Command("ipset", "create", setName, "hash:ip")
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
// 记录错误信息,但不退出
|
||
log.Printf("failed to execute command: %v, stderr: %s", err, stderr.String())
|
||
}
|
||
return err // 返回错误以便调用者处理
|
||
}
|
||
|
||
func AddIPSet(setName string, ip string) error {
|
||
cmd := exec.Command("ipset", "add", setName, ip)
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
// 记录错误信息,但不退出
|
||
log.Printf("failed to add IP to set: %v, stderr: %s", err, stderr.String())
|
||
}
|
||
return err // 返回错误以便调用者处理
|
||
}
|
||
|
||
// NumIPSet returns the number of entries in the specified ipset set.
|
||
func NumIPSet(setName string) (int, error) {
|
||
cmd := exec.Command("sh", "-c", fmt.Sprintf("ipset list %s | grep \"Number of entries\" | cut -d ':' -f 2 | sed 's/ //g'", setName))
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
log.Printf("cmd.Run() failed with %v, stderr: %s\n", err, stderr.String())
|
||
return 0, fmt.Errorf("failed to execute command: %w, stderr: %s", err, stderr.String())
|
||
}
|
||
|
||
output := strings.TrimSpace(stdout.String())
|
||
numEntries, err := strconv.Atoi(output)
|
||
if err != nil {
|
||
log.Printf("failed to parse output as integer: %v, output: %s\n", err, output)
|
||
return 0, fmt.Errorf("failed to parse output as integer: %w, output: %s", err, output)
|
||
}
|
||
|
||
return numEntries, nil
|
||
}
|
||
|
||
// IsIpset 检查名为 setName 的 ipset 是否存在,通过返回 0 表示存在,非零表示不存在或其他错误。
|
||
func IsIpset(setName string) int {
|
||
cmd := exec.Command("ipset", "list", setName)
|
||
err := cmd.Run()
|
||
|
||
if err != nil {
|
||
if exitError, ok := err.(*exec.ExitError); ok {
|
||
// The program has exited with an exit code != 0
|
||
return exitError.ExitCode()
|
||
} else {
|
||
// Another error occurred (e.g., command not found)
|
||
return -1 // 或者你可以选择其他方式来标识这种情况
|
||
}
|
||
}
|
||
|
||
// Command executed successfully, the set exists
|
||
return 0
|
||
}
|
||
|
||
func iptables(setName string) error {
|
||
|
||
cmd := exec.Command("sh", "-c", fmt.Sprintf("iptables -A INPUT -p tcp -m set --match-set %s src -j DROP", setName))
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
log.Printf("cmd.Run() failed with %v, stderr: %s\n", err, stderr.String())
|
||
err = fmt.Errorf("failed to execute command: %w, stderr: %s", err, stderr.String())
|
||
}
|
||
|
||
return err
|
||
}
|
||
|
||
/*
|
||
func main() {
|
||
// 创建 IPSet,但即使出错也继续执行
|
||
err := createIPSet("root0")
|
||
if err != nil {
|
||
log.Println("创建 IPSet 出错:", err)
|
||
} else {
|
||
fmt.Println("IPSet 创建成功!")
|
||
}
|
||
|
||
// 添加 IP 到 IPSet,出错时继续执行
|
||
err = AddIPSet("root0", "1.1.1.1")
|
||
if err != nil {
|
||
log.Println("添加 IP 到 IPSet 出错:", err)
|
||
}
|
||
|
||
// 获取 IPSet 条目数,出错时继续执行
|
||
num, err := NumIPSet("root0")
|
||
if err != nil {
|
||
log.Println("获取 IPSet 条目数出错:", err)
|
||
} else {
|
||
fmt.Printf("IPSet 条目数: %d\n", num)
|
||
}
|
||
|
||
iptables("root0")
|
||
}
|
||
*/
|