mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			136 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package iplibrary
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						|
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
						|
	"github.com/TeaOSLab/EdgeNode/internal/utils"
 | 
						|
	executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec"
 | 
						|
	"runtime"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// IPTablesAction IPTables动作
 | 
						|
// 相关命令:
 | 
						|
//
 | 
						|
//	iptables -A INPUT -s "192.168.2.32" -j ACCEPT
 | 
						|
//	iptables -A INPUT -s "192.168.2.32" -j REJECT
 | 
						|
//	iptables -D INPUT ...
 | 
						|
//	iptables -F INPUT
 | 
						|
type IPTablesAction struct {
 | 
						|
	BaseAction
 | 
						|
 | 
						|
	config *firewallconfigs.FirewallActionIPTablesConfig
 | 
						|
 | 
						|
	iptablesNotFound bool
 | 
						|
}
 | 
						|
 | 
						|
func NewIPTablesAction() *IPTablesAction {
 | 
						|
	return &IPTablesAction{}
 | 
						|
}
 | 
						|
 | 
						|
func (this *IPTablesAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
						|
	this.config = &firewallconfigs.FirewallActionIPTablesConfig{}
 | 
						|
	err := this.convertParams(config.Params, this.config)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (this *IPTablesAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
						|
	return this.runAction("addItem", listType, item)
 | 
						|
}
 | 
						|
 | 
						|
func (this *IPTablesAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
						|
	return this.runAction("deleteItem", listType, item)
 | 
						|
}
 | 
						|
 | 
						|
func (this *IPTablesAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
						|
	if item.Type == "all" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	if len(item.IpTo) == 0 {
 | 
						|
		return this.runActionSingleIP(action, listType, item)
 | 
						|
	}
 | 
						|
	cidrList, err := iPv4RangeToCIDRRange(item.IpFrom, item.IpTo)
 | 
						|
	if err != nil {
 | 
						|
		// 不合法的范围不予处理即可
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	if len(cidrList) == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	for _, cidr := range cidrList {
 | 
						|
		item.IpFrom = cidr
 | 
						|
		item.IpTo = ""
 | 
						|
		err := this.runActionSingleIP(action, listType, item)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (this *IPTablesAction) runActionSingleIP(action string, listType IPListType, item *pb.IPItem) error {
 | 
						|
	// 暂时不支持ipv6
 | 
						|
	// TODO 将来支持ipv6
 | 
						|
	if utils.IsIPv6(item.IpFrom) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if item.Type == "all" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	var path = this.config.Path
 | 
						|
	var err error
 | 
						|
	if len(path) == 0 {
 | 
						|
		path, err = executils.LookPath("iptables")
 | 
						|
		if err != nil {
 | 
						|
			if this.iptablesNotFound {
 | 
						|
				return nil
 | 
						|
			}
 | 
						|
			this.iptablesNotFound = true
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		this.config.Path = path
 | 
						|
	}
 | 
						|
	iptablesAction := ""
 | 
						|
	switch action {
 | 
						|
	case "addItem":
 | 
						|
		iptablesAction = "-A"
 | 
						|
	case "deleteItem":
 | 
						|
		iptablesAction = "-D"
 | 
						|
	default:
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	args := []string{iptablesAction, "INPUT", "-s", item.IpFrom, "-j"}
 | 
						|
	switch listType {
 | 
						|
	case IPListTypeWhite:
 | 
						|
		args = append(args, "ACCEPT")
 | 
						|
	case IPListTypeBlack:
 | 
						|
		args = append(args, "REJECT")
 | 
						|
	default:
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if runtime.GOOS == "darwin" {
 | 
						|
		// MAC OS直接返回
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	var cmd = executils.NewTimeoutCmd(30*time.Second, path, args...)
 | 
						|
	cmd.WithStderr()
 | 
						|
	err = cmd.Run()
 | 
						|
	if err != nil {
 | 
						|
		var output = cmd.Stderr()
 | 
						|
		if strings.Contains(output, "No chain/target/match") {
 | 
						|
			err = nil
 | 
						|
		} else {
 | 
						|
			return fmt.Errorf("%w, output: %s", err, output)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 |