{"id":20115505,"url":"https://github.com/asphaltt/go-nfnetlink-example","last_synced_at":"2025-07-04T01:33:54.160Z","repository":{"id":138614634,"uuid":"424269623","full_name":"Asphaltt/go-nfnetlink-example","owner":"Asphaltt","description":"An example for nfnetlink with Go.","archived":false,"fork":false,"pushed_at":"2021-11-09T15:39:45.000Z","size":5,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-06T13:46:28.788Z","etag":null,"topics":["go-nfnetlink","iptables","iptables-nfqueue","nfnetlink"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Asphaltt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-03T15:02:25.000Z","updated_at":"2025-04-09T10:28:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"71992032-82bd-4258-95b9-c85c43224608","html_url":"https://github.com/Asphaltt/go-nfnetlink-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Asphaltt/go-nfnetlink-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asphaltt%2Fgo-nfnetlink-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asphaltt%2Fgo-nfnetlink-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asphaltt%2Fgo-nfnetlink-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asphaltt%2Fgo-nfnetlink-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Asphaltt","download_url":"https://codeload.github.com/Asphaltt/go-nfnetlink-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asphaltt%2Fgo-nfnetlink-example/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263430722,"owners_count":23465427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go-nfnetlink","iptables","iptables-nfqueue","nfnetlink"],"created_at":"2024-11-13T18:35:29.611Z","updated_at":"2025-07-04T01:33:54.116Z","avatar_url":"https://github.com/Asphaltt.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 使用 Go 对接 iptables NFQUEUE 的例子\n\n最近在学习 `iptables NFQUEUE` 的时候，顺手使用 Go 语言写了一个例子。\n\n\u003e 源代码：[github.com/Asphaltt/go-nfnetlink-example](https://github.com/Asphaltt/go-nfnetlink-example)\n\n## 例子的效果\n\n使用 `iptables NFQUEUE` 监听新建 tcp 连接：\n\n```bash\n./nfnetlink-example\nA new tcp connection will be established: 192.168.x.yyy:61883 -\u003e xxx.yyy.219.56:80\nA new tcp connection will be established: 192.168.x.yyy:61886 -\u003e xxx.yyy.219.56:80\nA new tcp connection will be established: 192.168.x.yyy:61887 -\u003e xxx.yyy.235.132:80\nA new tcp connection will be established: 192.168.x.yyy:61888 -\u003e xxx.yyy.235.132:80\nA new tcp connection will be established: 192.168.x.yyy:61889 -\u003e xxx.yyy.137.56:443\nA new tcp connection will be established: 192.168.x.yyy:61890 -\u003e xxx.yyy.137.56:443\n```\n\n## 简洁的代码\n\n使用了 [go-nfnetlink](https://github.com/subgraph/go-nfnetlink) 纯 Go 实现的 `nfnetlink` 库，不依赖 `libnetfilter_queue` Linux 系统库，编译后即可使用。\n\n从 `iptables NFQUEUE` 中接收 tcp 连接的 **SYN** 包，并从 **SYN** 包中解析得到源 IP 地址、源 tcp 端口、目的 IP 地址、目的 tcp 端口等信息。\n\n```go\n\tq := nfqueue.NewNFQueue(1)\n\n\tps, err := q.Open()\n\tif err != nil {\n\t\tfmt.Printf(\"Error opening NFQueue: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\tdefer q.Close()\n\n\tfor p := range ps {\n\t\tnetworkLayer := p.Packet.NetworkLayer()\n\t\tipsrc, ipdst := networkLayer.NetworkFlow().Endpoints()\n\n\t\ttransportLayer := p.Packet.TransportLayer()\n\t\ttcpsrc, tcpdst := transportLayer.TransportFlow().Endpoints()\n\n\t\tfmt.Printf(\"A new tcp connection will be established: %s:%s -\u003e %s:%s\\n\",\n\t\t\tipsrc, tcpsrc, ipdst, tcpdst)\n\t\tp.Accept()\n\t}\n```\n\n使用的 `iptables` 规则如下：\n\n```bash\niptables -t raw -I PREROUTING -p tcp --syn -j NFQUEUE --queue-num=1 --queue-bypass\n```\n\n在 `raw` 表 `PREROUTING` 链上匹配 tcp 连接的 **SYN** 包。\n\n## `iptables NFQUEUE`\n\n\u003e ### NFQUEUE\n\u003e\n\u003e This target passes the packet to userspace using the **nfnetlink_queue** handler. The packet is put into the queue identified by its 16-bit queue number. Userspace can inspect and modify the packet if desired. Userspace must then drop or reinject the packet into the kernel. Please see libnetfilter_queue for details. **nfnetlink_queue** was added in Linux 2.6.14. The **queue-balance** option was added in Linux 2.6.31, **queue-bypass** in 2.6.39.\n\u003e\n\u003e - **--queue-num** *value*\n\u003e\n\u003e   This specifies the QUEUE number to use. Valid queue numbers are 0 to 65535. The default value is 0.\n\u003e\n\u003e \n\u003e\n\u003e - **--queue-balance** *value*:*value*\n\u003e\n\u003e   This specifies a range of queues to use. Packets are then balanced across the given queues. This is useful for multicore systems: start multiple instances of the userspace program on queues x, x+1, .. x+n and use \"--queue-balance *x*:*x+n*\". Packets belonging to the same connection are put into the same nfqueue.\n\u003e\n\u003e \n\u003e\n\u003e - **--queue-bypass**\n\u003e\n\u003e   By default, if no userspace program is listening on an NFQUEUE, then all packets that are to be queued are dropped. When this option is used, the NFQUEUE rule behaves like ACCEPT instead, and the packet will move on to the next table.\n\u003e\n\u003e \n\u003e\n\u003e - **--queue-cpu-fanout**\n\u003e\n\u003e   Available starting Linux kernel 3.10. When used together with **--queue-balance** this will use the CPU ID as an index to map packets to the queues. The idea is that you can improve performance if there's a queue per CPU. This requires **--queue-balance** to be specified.\n\n\u003e Doc: [iptables-extensions](https://ipset.netfilter.org/iptables-extensions.man.html)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasphaltt%2Fgo-nfnetlink-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasphaltt%2Fgo-nfnetlink-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasphaltt%2Fgo-nfnetlink-example/lists"}