欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何用go操作iptables和ipset設(shè)置黑白名單

 更新時間:2025年06月25日 10:46:15   作者:在成都搬磚的鴨鴨  
這篇文章主要介紹了如何用go操作iptables和ipset設(shè)置黑白名單問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

1、背景

iptables是linux中一個比較好用的防火墻工具,可以通過它對網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行管理和過濾,iptables中的四表五鏈在網(wǎng)上能查到很多文章解釋,這里不做過多解釋。

ipset是一個用于管理IP地址集合的工具,能和iptables組合起來一起使用,方便維護(hù)和管理各種防火墻規(guī)則。

本文會給出一個通過go庫操作iptables中filter表的INPUT鏈和ipset來實(shí)現(xiàn)允許和拒絕進(jìn)入本機(jī)ipv4網(wǎng)絡(luò)數(shù)據(jù)包的示例。

2、go庫下載

【1】iptables下載

go get -u github.com/coreos/go-iptables

【2】ipset下載

go get -u github.com/vishvananda/netlink

3、go庫和命令行對比

操作方式優(yōu)點(diǎn)缺點(diǎn)
命令行操作簡單方便平臺架構(gòu)版本兼容性差,復(fù)雜場景靈活性差
go庫操作平臺兼容性強(qiáng),復(fù)雜場景靈活性高需要花時間驗(yàn)證庫的正確性

4、代碼示例

【1】定義iptables規(guī)則和ipset集合名稱常量

// ipset類型
const (
	HASH_IP       = "hash:ip"
	HASH_IP_PORT  = "hash:ip,port"
	HASH_NET      = "hash:net"
	HASH_NET_PORT = "hash:net,port"
)

// ipset名稱
const (
	WL_IP       = "wl_ip"
	WL_IP_PORT  = "wl_ip_port"
	WL_NET      = "wl_net"
	WL_NET_PORT = "wl_net_port"
	BL_IP       = "bl_ip"
	BL_IP_PORT  = "bl_ip_port"
	BL_NET      = "bl_net"
	BL_NET_PORT = "bl_net_port"
)

var ipSetNameToTypeMp = map[string]string{
	WL_IP:       HASH_IP,
	WL_IP_PORT:  HASH_IP_PORT,
	WL_NET:      HASH_NET,
	WL_NET_PORT: HASH_NET_PORT,
	BL_IP:       HASH_IP,
	BL_IP_PORT:  HASH_IP_PORT,
	BL_NET:      HASH_NET,
	BL_NET_PORT: HASH_NET_PORT,
}

// iptables規(guī)則
var iptRules = [][]string{
	{"-m", "state", "--state", "ESTABLISHED,RELATED", "-j", "ACCEPT"},    //已建連接允許
	{"-i", "lo", "-j", "ACCEPT"},                                         //本地回環(huán)包運(yùn)行
	{"-m", "set", "--match-set", WL_IP, "src", "-j", "ACCEPT"},           //對集合條目里的源ip允許
	{"-m", "set", "--match-set", WL_IP_PORT, "src,dst", "-j", "ACCEPT"},  //對集合條目里的源ip和目的port允許
	{"-m", "set", "--match-set", WL_NET, "src", "-j", "ACCEPT"},          //對集合條目里的源ip允許
	{"-m", "set", "--match-set", WL_NET_PORT, "src,dst", "-j", "ACCEPT"}, //對集合條目里的源ip和目的port允許
	{"-m", "set", "--match-set", BL_IP, "src", "-j", "ACCEPT"},           //對集合條目里的源ip拒絕
	{"-m", "set", "--match-set", BL_IP_PORT, "src,dst", "-j", "ACCEPT"},  //對集合條目里的源ip和目的port拒絕
	{"-m", "set", "--match-set", BL_NET, "src", "-j", "ACCEPT"},          //對集合條目里的源ip拒絕
	{"-m", "set", "--match-set", BL_NET_PORT, "src,dst", "-j", "ACCEPT"}, //對集合條目里的源ip和目的port拒絕
}

一般都會對本機(jī)的已建連接和lo網(wǎng)口的數(shù)據(jù)包放行,兩條規(guī)則分別為:

1、iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
2、iptables -A INPUT -i lo -j ACCEPT

默認(rèn)在filter表上增加規(guī)則,也可以增加-t指定其它表

【2】創(chuàng)建ipset集合

//創(chuàng)建ipset集合
	for setName, setType := range ipSetNameToTypeMp {
		if err := netlink.IpsetCreate(setName, setType, netlink.IpsetCreateOptions{Replace: true}); err != nil {
			logger.Error("ipset create error", zap.String("set_name", setName), zap.Error(err))
			continue
		}
	}

netlink.IpsetCreateOptions中可以定義其它自定義參數(shù),比如:超時時間、ipv4/ipv6、最大個數(shù)、是否覆蓋已存在的集合等。

【3】創(chuàng)建iptables規(guī)則

//創(chuàng)建iptables規(guī)則
	ipt, err := iptables.New()
	if err != nil {
		logger.Error("iptables new error", zap.Error(err))
		return
	}

	for _, iptRule := range iptRules {
		if err = ipt.AppendUnique("filter", "INPUT", iptRule...); err != nil {
			logger.Error("iptables append unique error", zap.Error(err))
			continue
		}
	}

AppendUnique函數(shù)是往指定鏈中追加規(guī)則,如果規(guī)則存在就不會去做操作。

【4】添加條目

//增加ipset條目
	var port = uint16(100)

	if err = netlink.IpsetAdd(WL_IP, &netlink.IPSetEntry{IP: net.ParseIP("1.1.1.1")}); err != nil { //對源ip為1.1.1.1的包加白
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(WL_IP_PORT, &netlink.IPSetEntry{IP: net.ParseIP("2.2.2.2"), Port: &port}); err != nil { //對源ip為2.2.2.2,目的端口為100的包加白
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(WL_NET, &netlink.IPSetEntry{IP: net.ParseIP("3.3.3.3"), CIDR: 24}); err != nil { //對源ip在3.3.3.3/24范圍內(nèi)的包加白
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(WL_NET_PORT, &netlink.IPSetEntry{IP: net.ParseIP("4.4.4.4"), CIDR: 24, Port: &port}); err != nil { //對源在4.4.4.4/24范圍內(nèi),目的端口為100的包加白
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(BL_IP, &netlink.IPSetEntry{IP: net.ParseIP("5.5.5.5")}); err != nil { //對源ip為1.1.1.1的包加黑
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(BL_IP_PORT, &netlink.IPSetEntry{IP: net.ParseIP("6.6.6.6"), Port: &port}); err != nil { //對源ip為2.2.2.2,目的端口為100的包加黑
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(BL_NET, &netlink.IPSetEntry{IP: net.ParseIP("7.7.7.7"), CIDR: 24}); err != nil { //對源ip在3.3.3.3/24范圍內(nèi)的包加黑
		logger.Error("ipset add error", zap.Error(err))
	}

	if err = netlink.IpsetAdd(BL_NET_PORT, &netlink.IPSetEntry{IP: net.ParseIP("8.8.8.8"), CIDR: 24, Port: &port}); err != nil { //對源在4.4.4.4/24范圍內(nèi),目的端口為100的包加黑
		logger.Error("ipset add error", zap.Error(err))
	}

根據(jù)不同的集合類型給netlink.IPSetEntry設(shè)置不同的參數(shù)。

【5】查看iptables

[root@xxx ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set wl_ip src
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set wl_ip_port src,dst
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set wl_net src
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set wl_net_port src,dst
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set bl_ip src
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set bl_ip_port src,dst
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set bl_net src
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            match-set bl_net_port src,dst
[root@xxx ~]# iptables -S | grep INPUT
-P INPUT ACCEPT
-N SPA_HIDE_INPUT
-N SPA_WL_INPUT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m set --match-set wl_ip src -j ACCEPT
-A INPUT -m set --match-set wl_ip_port src,dst -j ACCEPT
-A INPUT -m set --match-set wl_net src -j ACCEPT
-A INPUT -m set --match-set wl_net_port src,dst -j ACCEPT
-A INPUT -m set --match-set bl_ip src -j ACCEPT
-A INPUT -m set --match-set bl_ip_port src,dst -j ACCEPT
-A INPUT -m set --match-set bl_net src -j ACCEPT
-A INPUT -m set --match-set bl_net_port src,dst -j ACCEPT

【6】查看ipset

[root@xxx ~]# ipset list
Name: bl_ip
Type: hash:ip
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16544
References: 1
Members:
5.5.5.5

Name: bl_ip_port
Type: hash:ip,port
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 1
Members:
6.6.6.6,tcp:100

Name: bl_net
Type: hash:net
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16816
References: 1
Members:
7.7.7.0/24

Name: bl_net_port
Type: hash:net,port
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16816
References: 1
Members:
8.8.8.0/24,tcp:100

Name: wl_ip
Type: hash:ip
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16544
References: 1
Members:
1.1.1.1

Name: wl_ip_port
Type: hash:ip,port
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 1
Members:
2.2.2.2,tcp:100

Name: wl_net
Type: hash:net
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16816
References: 1
Members:
3.3.3.0/24

Name: wl_net_port
Type: hash:net,port
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16816
References: 1
Members:
4.4.4.0/24,tcp:100

5、總結(jié)

上面給出了一部分go的iptables和ipset庫的基礎(chǔ)用法,在真實(shí)的業(yè)務(wù)場景中是可以做出很多優(yōu)化,比如:黑白名單各自定義一條自定義鏈再追加到INPUT鏈去維護(hù),這樣黑白名單相互之間不會互相影響。

更多功能可以根據(jù)庫里的API應(yīng)用到適合的場景。

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一鍵定位Golang線上服務(wù)內(nèi)存泄露的秘籍

    一鍵定位Golang線上服務(wù)內(nèi)存泄露的秘籍

    內(nèi)存泄露?別讓它拖垮你的Golang線上服務(wù)!快速掌握Go語言服務(wù)內(nèi)存泄漏排查秘籍,從此問題無處遁形,一文讀懂如何精準(zhǔn)定位與有效解決Golang應(yīng)用中的內(nèi)存問題,立即閱讀,讓性能飛升!
    2024-01-01
  • Go 語言中靜態(tài)類型和動態(tài)類型的使用

    Go 語言中靜態(tài)類型和動態(tài)類型的使用

    本文主要介紹了Go語言中的靜態(tài)類型和動態(tài)類型,靜態(tài)類型在編譯時確定,提供了類型安全,性能優(yōu)化和代碼清晰,而動態(tài)類型在運(yùn)行時確定,提供了更高的靈活性,但可能引發(fā)運(yùn)行時錯誤,下面就來介紹一下,感興趣的可以了解一下
    2024-10-10
  • 一文帶大家搞懂Go語言中的迭代器

    一文帶大家搞懂Go語言中的迭代器

    迭代器是使用戶可在容器對象上遍訪的對象,設(shè)計人員使用此接口無需關(guān)心容器對象的內(nèi)存分配的實(shí)現(xiàn)細(xì)節(jié),本文主要為大家詳細(xì)介紹一下Go語言中的迭代器的實(shí)現(xiàn),需要的可以了解下
    2025-02-02
  • Windows+Linux系統(tǒng)下Go語言環(huán)境安裝配置過程

    Windows+Linux系統(tǒng)下Go語言環(huán)境安裝配置過程

    Go 語言被設(shè)計成一門應(yīng)用于搭載 Web 服務(wù)器,存儲集群或類似用途的巨型中央服務(wù)器的系統(tǒng)編程語言。這篇文章主要介紹了Windows+Linux系統(tǒng)下Go語言環(huán)境搭建配置過程,針對每種系統(tǒng)給大家講解的非常詳細(xì),需要的朋友可以參考下
    2021-06-06
  • Go type關(guān)鍵字(類型定義與類型別名的使用差異)用法實(shí)例探究

    Go type關(guān)鍵字(類型定義與類型別名的使用差異)用法實(shí)例探究

    這篇文章主要為大家介紹了Go type關(guān)鍵字(類型定義與類型別名的使用差異)用法實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go 防止 goroutine 泄露的方法

    Go 防止 goroutine 泄露的方法

    Go 的并發(fā)模型與其他語言不同,雖說它簡化了并發(fā)程序的開發(fā)難度,但如果不了解使用方法,常常會遇到 goroutine 泄露的問題。本篇主要從如何寫出正確代碼的角度來介紹如何防止 goroutine 的泄露,需要的朋友可以參考下
    2019-09-09
  • 詳解Golang中g(shù)cache模塊的基本使用

    詳解Golang中g(shù)cache模塊的基本使用

    這篇文章主要通過結(jié)合商業(yè)項(xiàng)目的使用場景,為大家介紹了gcache的基本使用、緩存控制以及淘汰策略。使用gcache做緩存處理,簡單方便易上手
    2022-11-11
  • ?Go?語言實(shí)現(xiàn)?HTTP?文件上傳和下載

    ?Go?語言實(shí)現(xiàn)?HTTP?文件上傳和下載

    這篇文章主要介紹了Go語言實(shí)現(xiàn)HTTP文件上傳和下載,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Go語言實(shí)現(xiàn)請求超時處理的方法總結(jié)

    Go語言實(shí)現(xiàn)請求超時處理的方法總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Go語言中實(shí)現(xiàn)請求的超時控制的方法,主要是通過timer和timerCtx來實(shí)現(xiàn)請求的超時控制,希望對大家有所幫助
    2023-05-05
  • go語言實(shí)現(xiàn)短信發(fā)送實(shí)例探究

    go語言實(shí)現(xiàn)短信發(fā)送實(shí)例探究

    這篇文章主要為大家介紹了go語言實(shí)現(xiàn)短信發(fā)送實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01

最新評論