golang Sophos UTM REST API客户端插件库go-sophos的使用

golang Sophos UTM REST API客户端插件库go-sophos的使用

go-sophos简介

go-sophos是一个用于Go语言的Sophos UTM REST API客户端库,零依赖。

Documentation Go Report Card codecov go workflow MIT License Mentioned in Awesome Go

前提条件

  • Sophos UTM REST API必须在管理员设置中启用
  • 熟悉Sophos文档
  • API类型和函数是根据UTM声明的Restd版本生成和版本化的

使用方法

API从0.1.0版本开始稳定

安装:

go get github.com/esurdam/go-sophos

创建客户端

import "github.com/esurdam/go-sophos"

// 所有初始化时传递的选项将应用于所有后续调用
client, _ := sophos.New(
    "192.168.0.1:4848", 
    sophos.WithBasicAuth("user", "pass"),
)

获取WebAdmin当前端口

import "github.com/esurdam/go-sophos"

client, _ := sophos.New(
    "192.168.0.1:4848", 
    sophos.WithApiToken("abCDEFghIjklMNOPQkwSnwbutCpHdjQz"),
)
res, _ := client.Get("/api/nodes/webadmin.port")

var port int
res.MarshalTo(&port)
fmt.Println(port)
// Output: 4848

节点操作

节点使用包级函数进行交互:

import "github.com/esurdam/go-sophos/api/v1.3.0/nodes"

v, err := nodes.GetWebadminPort(client)
fmt.Println(v)
// Output: 4848

err = nodes.UpdateWebadminPort(client, 4444)

或者作为结构体类型,带有围绕函数的语法糖:

import "github.com/esurdam/go-sophos/api/v1.3.0/nodes"

var wap nodes.WebadminPort
err := wap.Get(client)
fmt.Println(wap.Value)
// Output: 4848

wap.Value = 4444
err = wap.Update(client)

对象操作

objects目录中的每个文件代表一个从定义生成的端点,并包含其生成的对象。

对象实现了RestObject接口:

import "github.com/esurdam/go-sophos/api/v1.3.0/objects"

var dns objects.Dns
err := client.GetObject(&dns)

注意,一些对象是复数形式,只实现了RestGetter接口:

import "github.com/esurdam/go-sophos/api/v1.3.0/objects"

var ss objects.DnsRoutes
_ = client.GetObject(&ss)

// 每个单独的DnsRoute都是一个RestObject
for _, s := range ss {
    ub, _ := client.GetUsedBy(&s)
    fmt.Printf("DNS ROUTE: %s [%s]\n  Used By Nodes: %v\n  Used by Objects: %v\n",s.Name, s.Reference, ub.Nodes, ub.Objects)
    // OUTPUT: DNS ROUTE: sophos.boom.local [REF_DnsRouBoomloca]
    //             Used By Nodes: [dns.routes]
    //             Used by Objects: []
}

示例

删除一个包过滤规则

import "github.com/esurdam/go-sophos"

client, _ := sophos.New(
    "192.168.0.1:4848", 
    sophos.WithBasicAuth("user", "pass"),
)

_, err := client.Delete(
    "api/objects/packetfilter/packetfilter/REF_PacPacXYZ", 
    sophos.WithSessionClose, 
    sophos.AutoResolveErrsMode,
)

使用对象的方式:

import "github.com/esurdam/go-sophos"
import "github.com/esurdam/go-sophos/api/v1.3.0/objects"

client, _ := sophos.New(
    "192.168.0.1:4848", 
    sophos.WithBasicAuth("user", "pass"),
)

// 对象知道API路由
pf := objects.PacketfilterPacketfilter{
	Reference: "REF_PacPacXYZ"
}

err := client.DeleteObject(&pf, 
	sophos.WithSessionClose, 
	sophos.AutoResolveErrsMode
)

创建一个包过滤器

import "github.com/esurdam/go-sophos"
import "github.com/esurdam/go-sophos/api/v1.3.0/objects"

client, _ := sophos.New(
    "192.168.0.1:4848", 
    sophos.WithBasicAuth("user", "pass"),
)

pf := objects.PacketfilterPacketfilter{
    Action:       "accept",
    Destinations: []string{sophos.RefNetworkAny},
    Direction:    "in",
    Log:          true,
    Services:     []string{sophos.RefServiceAny},
    Sources:      []string{sophos.RefNetworkAny},
    Status:       true,
}

err := client.PostObject(&pf, 
	sophos.WithRestdInsert("packetfilter.rules", 0), 
	sophos.WithSessionClose,
)

// 成功创建将解组响应
pf.Reference  

错误处理

if err != nil {
    // 对于修改请求(PATCH, PUT, POST, DELETE),返回的错误可能是*sophos.Errors类型
    err.(*sophos.Errors).Error() == err.Error()
    sophos.IsFatalErr(err) == err.(*sophos.Errors).IsFatal()
    
    // 查看每个单独的错误
    for _, e := range *err.(*sophos.Errors) {
    	e.Error() 
    	e.IsFatal()
    }
}

生成类型

Sophos类型是使用bin/gen.go自动生成的,它查询UTM的api/definitions路径来生成api目录中的所有文件,这些文件包含与UTM API定义对应的结构体和辅助函数。

生成的包是版本化的,可以针对旧版本生成并提交。

export ENDPOINT=192.168.0.1:4848
export TOKEN=abcde1234

make

测试

make test

贡献

请阅读CONTRIBUTING.md了解我们的行为准则,以及向我们提交拉取请求的流程。

许可证

该项目采用MIT许可证 - 有关详细信息,请参阅LICENSE.md文件


更多关于golang Sophos UTM REST API客户端插件库go-sophos的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang Sophos UTM REST API客户端插件库go-sophos的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-sophos: Sophos UTM REST API 客户端库

go-sophos 是一个用于与 Sophos UTM (Unified Threat Management) 设备 REST API 交互的 Go 语言客户端库。它提供了简单易用的接口来管理 Sophos UTM 设备。

基本用法

安装

go get github.com/esurdam/go-sophos

初始化客户端

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/esurdam/go-sophos"
)

func main() {
	// 创建客户端配置
	config := sophos.ClientConfig{
		Endpoint:   "https://your-utm-ip:4444", // UTM管理地址
		Username:   "admin",                    // 管理员用户名
		Password:   "your-password",            // 管理员密码
		SkipVerify: true,                       // 如果使用自签名证书,可以跳过验证
	}

	// 创建客户端
	client, err := sophos.NewClient(config)
	if err != nil {
		log.Fatalf("创建客户端失败: %v", err)
	}

	// 测试连接
	ctx := context.Background()
	version, err := client.GetVersion(ctx)
	if err != nil {
		log.Fatalf("获取版本信息失败: %v", err)
	}
	fmt.Printf("Sophos UTM 版本: %s\n", version.Version)
}

常用功能示例

1. 获取防火墙规则

func listFirewallRules(client *sophos.Client) {
	rules, err := client.GetFirewallRules(context.Background())
	if err != nil {
		log.Fatalf("获取防火墙规则失败: %v", err)
	}

	fmt.Println("防火墙规则列表:")
	for _, rule := range rules {
		fmt.Printf("ID: %s, 名称: %s, 动作: %s, 源: %s, 目标: %s\n",
			rule.ID, rule.Name, rule.Action, rule.Source, rule.Destination)
	}
}

2. 创建新的防火墙规则

func createFirewallRule(client *sophos.Client) {
	newRule := sophos.FirewallRule{
		Name:        "Allow HTTP from LAN",
		Action:      "accept",
		Source:      []string{"LAN"},
		Destination: []string{"Any"},
		Service:     []string{"HTTP"},
		Comment:     "允许LAN访问HTTP",
		Status:      true,
	}

	createdRule, err := client.CreateFirewallRule(context.Background(), newRule)
	if err != nil {
		log.Fatalf("创建防火墙规则失败: %v", err)
	}

	fmt.Printf("成功创建规则: ID=%s, 名称=%s\n", createdRule.ID, createdRule.Name)
}

3. 获取网络接口信息

func listInterfaces(client *sophos.Client) {
	interfaces, err := client.GetInterfaces(context.Background())
	if err != nil {
		log.Fatalf("获取接口信息失败: %v", err)
	}

	fmt.Println("网络接口列表:")
	for _, iface := range interfaces {
		fmt.Printf("名称: %s, IP: %s, 状态: %s\n", 
			iface.Name, iface.Address, iface.Status)
	}
}

4. 更新对象

func updateHostObject(client *sophos.Client) {
	// 首先获取现有对象
	host, err := client.GetHostObject(context.Background(), "example-host")
	if err != nil {
		log.Fatalf("获取主机对象失败: %v", err)
	}

	// 修改属性
	host.Address = "192.168.1.100"
	host.Comment = "更新后的服务器IP"

	// 提交更新
	updatedHost, err := client.UpdateHostObject(context.Background(), host.Name, *host)
	if err != nil {
		log.Fatalf("更新主机对象失败: %v", err)
	}

	fmt.Printf("成功更新主机: %s (%s)\n", updatedHost.Name, updatedHost.Address)
}

高级用法

批量操作

func batchOperations(client *sophos.Client) {
	// 创建批量操作请求
	batch := sophos.NewBatchRequest()
	
	// 添加多个操作
	batch.AddGet("/api/objects/network/host/example-host")
	batch.AddGet("/api/objects/network/network/LAN")
	batch.AddGet("/api/objects/service/http/HTTP")
	
	// 执行批量请求
	results, err := client.Batch(context.Background(), batch)
	if err != nil {
		log.Fatalf("批量操作失败: %v", err)
	}
	
	// 处理结果
	for i, res := range results {
		if res.Error != nil {
			fmt.Printf("操作 %d 失败: %v\n", i, res.Error)
		} else {
			fmt.Printf("操作 %d 成功\n", i)
		}
	}
}

监听事件

func listenEvents(client *sophos.Client) {
	// 创建事件监听器
	listener, err := client.NewEventListener(context.Background())
	if err != nil {
		log.Fatalf("创建事件监听器失败: %v", err)
	}
	defer listener.Close()

	fmt.Println("开始监听事件...")
	for event := range listener.Events {
		fmt.Printf("收到事件: 类型=%s, 消息=%s\n", event.Type, event.Message)
	}
}

错误处理

func handleErrors(client *sophos.Client) {
	_, err := client.GetHostObject(context.Background(), "non-existent-host")
	if err != nil {
		if sophosErr, ok := err.(*sophos.Error); ok {
			// 处理API返回的错误
			fmt.Printf("API错误: 状态码=%d, 消息=%s\n", 
				sophosErr.StatusCode, sophosErr.Message)
		} else {
			// 处理其他类型的错误
			fmt.Printf("其他错误: %v\n", err)
		}
		return
	}
}

注意事项

  1. 安全性: 在生产环境中,建议使用证书验证而不是跳过验证(SkipVerify)
  2. 性能: 批量操作可以显著减少API调用次数
  3. 错误处理: 总是检查错误并适当处理
  4. 并发: 客户端是线程安全的,可以在多个goroutine中使用
  5. API限制: Sophos UTM API可能有速率限制,注意不要过度调用

go-sophos 库提供了对 Sophos UTM 大多数功能的访问,包括防火墙规则、网络对象、用户管理、VPN配置等。完整的API文档可以参考库的GitHub页面和Sophos UTM官方REST API文档。

回到顶部