mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-08-31 01:41:39 +08:00
系统防火墙:linux和windows分离
This commit is contained in:
+13
-79
@@ -1,9 +1,10 @@
|
||||
//go:build linux
|
||||
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
@@ -31,19 +32,6 @@ func (fw *FireWallEngine) IsFirewallEnabled() bool {
|
||||
return false
|
||||
}
|
||||
return len(out) > 0
|
||||
} else if runtime.GOOS == "windows" {
|
||||
const firewallRegistryPath = `SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile`
|
||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, firewallRegistryPath, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer key.Close()
|
||||
|
||||
enabled, _, err := key.GetIntegerValue("EnableFirewall")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return enabled == 1
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -67,82 +55,28 @@ func (fw *FireWallEngine) executeCommand(cmd *exec.Cmd) (error error, printstr s
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) AddRule(ruleName, ipToAdd, action, proc, localport string) error {
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "linux" {
|
||||
cmd = exec.Command("iptables", "-A", "INPUT", ipToAdd)
|
||||
} else if runtime.GOOS == "windows" {
|
||||
/*s := fmt.Sprintf(`netsh advfirewall firewall add rule name="%s" dir=in action=allow protocol=TCP localport=8080 remoteip=%s`, ruleName, ipToAdd)
|
||||
cmd = exec.Command("netsh", s)*/
|
||||
/*cmd = exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
|
||||
fmt.Sprintf(`name="%s"`, ruleName),
|
||||
fmt.Sprintf(`dir=in action=allow protocol=TCP localport=8080 remoteip=%s`, ipToAdd),
|
||||
)*/
|
||||
cmd = exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
|
||||
"name="+ruleName, "dir=in", "action="+action, "protocol="+proc, "localport="+localport,
|
||||
"remoteip="+ipToAdd,
|
||||
)
|
||||
} else {
|
||||
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
}
|
||||
cmd := exec.Command("iptables", "-A", "INPUT", ipToAdd)
|
||||
err, _ := fw.executeCommand(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
/*func (fw *FireWallEngine) EditRule(ruleNum int, newRule string) error {
|
||||
func (fw *FireWallEngine) EditRule(ruleNum int, newRule string) error {
|
||||
return fmt.Errorf("editRule is not supported on Windows")
|
||||
}*/
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) DeleteRule(ruleName string) (bool, error) {
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "linux" {
|
||||
cmd = exec.Command("iptables", "-D", "INPUT", fmt.Sprintf("%s", ruleName))
|
||||
} else if runtime.GOOS == "windows" {
|
||||
cmd = exec.Command("netsh", "advfirewall", "firewall", "delete", "rule", fmt.Sprintf("name=%s", ruleName))
|
||||
err, output := fw.executeCommand(cmd)
|
||||
fmt.Println(output)
|
||||
//已删除 1 规则。确定。
|
||||
if err == nil {
|
||||
if strings.Contains(output, "No rules match the specified criteria") {
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
if strings.Contains(output, "没有与指定标准相匹配的规则。") {
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
if strings.Contains(output, "已删除") {
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
cmd = exec.Command("iptables", "-D", "INPUT", fmt.Sprintf("%s", ruleName))
|
||||
err, _ := fw.executeCommand(cmd)
|
||||
return false, err
|
||||
}
|
||||
func (fw *FireWallEngine) IsRuleExists(ruleName string) (bool, error) {
|
||||
if runtime.GOOS == "linux" {
|
||||
cmd := exec.Command("iptables-save")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list iptables rules: %s, output: %s", err, string(output))
|
||||
}
|
||||
return strings.Contains(string(output), "-A INPUT -s "+ruleName+" -j ACCEPT"), nil
|
||||
} else if runtime.GOOS == "windows" {
|
||||
cmd := exec.Command("netsh", "advfirewall", "firewall", "show", "rule", "name="+ruleName)
|
||||
err, output := fw.executeCommand(cmd)
|
||||
if err == nil {
|
||||
if strings.Contains(output, "No rules match the specified criteria") {
|
||||
return false, nil
|
||||
}
|
||||
if strings.Contains(output, "没有与指定标准相匹配的规则。") {
|
||||
return false, nil
|
||||
}
|
||||
if strings.Contains(output, " "+ruleName+"-----") {
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
return false, fmt.Errorf("failed to show firewall rule: %s, output: %s", err, string(output))
|
||||
}
|
||||
cmd := exec.Command("iptables-save")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list iptables rules: %s, output: %s", err, string(output))
|
||||
}
|
||||
return false, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
return strings.Contains(string(output), "-A INPUT -s "+ruleName+" -j ACCEPT"), nil
|
||||
}
|
||||
func ConvertByte2String(byte []byte, charset Charset) string {
|
||||
var str string
|
||||
|
||||
+11
-12
@@ -48,19 +48,18 @@ func TestFireWallEngine_DeleteRule(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
func TestFireWallEngine_EditRule(t *testing.T) {
|
||||
fw := FireWallEngine{}
|
||||
// Edit an existing firewall rule (not supported on Windows)
|
||||
ruleNum := 1
|
||||
newRule := "-p tcp --dport 8080 -j DROP"
|
||||
if err := fw.EditRule(ruleNum, newRule); err != nil {
|
||||
fmt.Println("Failed to edit firewall rule:", err)
|
||||
} else {
|
||||
fmt.Println("Firewall rule edited successfully.")
|
||||
}
|
||||
func TestFireWallEngine_EditRule(t *testing.T) {
|
||||
fw := FireWallEngine{}
|
||||
// Edit an existing firewall rule (not supported on Windows)
|
||||
ruleNum := 1
|
||||
newRule := "-p tcp --dport 8080 -j DROP"
|
||||
if err := fw.EditRule(ruleNum, newRule); err != nil {
|
||||
fmt.Println("Failed to edit firewall rule:", err)
|
||||
} else {
|
||||
fmt.Println("Firewall rule edited successfully.")
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func TestFireWallEngine_IsFirewallEnabled(t *testing.T) {
|
||||
fw := FireWallEngine{}
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
//go:build !linux
|
||||
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Charset string
|
||||
|
||||
const (
|
||||
UTF8 = Charset("UTF-8")
|
||||
GB18030 = Charset("GB18030")
|
||||
)
|
||||
|
||||
const ACTION_ALLOW string = "allow" //,allow 表示允许连接,block 表示阻止连接,bypass 表示只允许安全连接。 =
|
||||
const ACTION_BLOCK string = "block"
|
||||
const ACTION_BYPASS string = "bypass"
|
||||
|
||||
type FireWallEngine struct {
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) IsFirewallEnabled() bool {
|
||||
const firewallRegistryPath = `SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile`
|
||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, firewallRegistryPath, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer key.Close()
|
||||
|
||||
enabled, _, err := key.GetIntegerValue("EnableFirewall")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return enabled == 1
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) executeCommand(cmd *exec.Cmd) (error error, printstr string) {
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err, err.Error()
|
||||
}
|
||||
cmd.Start()
|
||||
in := bufio.NewScanner(stdout)
|
||||
printstr = ""
|
||||
for in.Scan() {
|
||||
cmdRe := ConvertByte2String(in.Bytes(), "GB18030")
|
||||
//fmt.Println(cmdRe)
|
||||
printstr += cmdRe
|
||||
}
|
||||
cmd.Wait()
|
||||
return nil, printstr
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) AddRule(ruleName, ipToAdd, action, proc, localport string) error {
|
||||
|
||||
/*s := fmt.Sprintf(`netsh advfirewall firewall add rule name="%s" dir=in action=allow protocol=TCP localport=8080 remoteip=%s`, ruleName, ipToAdd)
|
||||
cmd = exec.Command("netsh", s)*/
|
||||
/*cmd = exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
|
||||
fmt.Sprintf(`name="%s"`, ruleName),
|
||||
fmt.Sprintf(`dir=in action=allow protocol=TCP localport=8080 remoteip=%s`, ipToAdd),
|
||||
)*/
|
||||
cmd := exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
|
||||
"name="+ruleName, "dir=in", "action="+action, "protocol="+proc, "localport="+localport,
|
||||
"remoteip="+ipToAdd,
|
||||
)
|
||||
err, _ := fw.executeCommand(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) EditRule(ruleNum int, newRule string) error {
|
||||
return fmt.Errorf("editRule is not supported on Windows")
|
||||
}
|
||||
|
||||
func (fw *FireWallEngine) DeleteRule(ruleName string) (bool, error) {
|
||||
cmd := exec.Command("netsh", "advfirewall", "firewall", "delete", "rule", fmt.Sprintf("name=%s", ruleName))
|
||||
err, output := fw.executeCommand(cmd)
|
||||
fmt.Println(output)
|
||||
//已删除 1 规则。确定。
|
||||
if err == nil {
|
||||
if strings.Contains(output, "No rules match the specified criteria") {
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
if strings.Contains(output, "没有与指定标准相匹配的规则。") {
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
if strings.Contains(output, "已删除") {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("error:delete firewall rule: %s, output: %s", ruleName, output)
|
||||
}
|
||||
func (fw *FireWallEngine) IsRuleExists(ruleName string) (bool, error) {
|
||||
cmd := exec.Command("netsh", "advfirewall", "firewall", "show", "rule", "name="+ruleName)
|
||||
err, output := fw.executeCommand(cmd)
|
||||
if err == nil {
|
||||
if strings.Contains(output, "No rules match the specified criteria") {
|
||||
return false, nil
|
||||
}
|
||||
if strings.Contains(output, "没有与指定标准相匹配的规则。") {
|
||||
return false, nil
|
||||
}
|
||||
if strings.Contains(output, " "+ruleName+"-----") {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("failed to show firewall rule: %s, output: %s", err, string(output))
|
||||
}
|
||||
func ConvertByte2String(byte []byte, charset Charset) string {
|
||||
var str string
|
||||
switch charset {
|
||||
case GB18030:
|
||||
var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
|
||||
str = string(decodeBytes)
|
||||
case UTF8:
|
||||
fallthrough
|
||||
default:
|
||||
str = string(byte)
|
||||
}
|
||||
return str
|
||||
}
|
||||
@@ -17,6 +17,8 @@ docker run --rm -v "$PWD":/media/sf_SamWaf -w /media/sf_SamWaf -e CGO_ENABLED=1
|
||||
//可调试的local ubuntu
|
||||
docker run --rm -v "$PWD":/home/ubuntu/samwaf -w /home/ubuntu/samwaf -e CGO_ENABLED=1 -e GOPROXY=https://goproxy.cn,direct golang:1.19 go build -v -ldflags="-extldflags "-static"" -o /home/ubuntu/samwaf/release/SamWafLinux64.exe main.go
|
||||
|
||||
//单元测试
|
||||
docker run --rm -v "$PWD":/media/sf_SamWaf -w /media/sf_SamWaf -e CGO_ENABLED=1 -e GOPROXY=https://goproxy.cn,direct golang:1.19 go test -v ./firewall -test.run TestFireWallEngine_IsFirewallEnabled
|
||||
|
||||
# 注意事项
|
||||
1. 如果linux使用multipass 需要以下方式开启
|
||||
|
||||
Reference in New Issue
Block a user