hashicorp/go-sockaddr
GitHub: hashicorp/go-sockaddr
Go 语言的 IP 地址和 UNIX Socket 便捷操作库,提供基于启发式规则的运行时 IP 地址选择能力。
Stars: 290 | Forks: 54
# go-sockaddr
## `sockaddr` 库
Go 的 socket 地址便捷函数。`go-sockaddr` 是一个便捷
库,旨在让正确处理 IP 地址变得简单。`go-sockaddr`
松散地模仿了 UNIX 的 `sockaddr_t`,并创建了一个家族式的
`sockaddr_t` 类型的联合体(下文提供了 ASCII 图表)。库文档可在
[https://godoc.org/github.com/hashicorp/go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr) 获取。
该库的主要目的是在运行时评估配置时,为选择正确的
IP 地址制定启发式规则。详情和
使用该库的提示,请参阅
[文档](https://godoc.org/github.com/hashicorp/go-sockaddr)、
[`template` 包](https://godoc.org/github.com/hashicorp/go-sockaddr/template)、
测试
以及
[CLI 工具](https://github.com/hashicorp/go-sockaddr/tree/master/cmd/sockaddr)。
例如,使用此库可以查找满足以下条件的 IP 地址:
* 附加到默认路由
([`GetDefaultInterfaces()`](https://godoc.org/github.com/hashicorp/go-sockaddr#GetDefaultInterfaces))
* 包含在 CIDR 块内 ([`IfByNetwork()`](https://godoc.org/github.com/hashicorp/go-sockaddr#IfByNetwork))
* 是 RFC1918 地址
([`IfByRFC("1918")`](https://godoc.org/github.com/hashicorp/go-sockaddr#IfByRFC))
* 已排序
([`OrderedIfAddrBy(args)`](https://godoc.org/github.com/hashicorp/go-sockaddr#OrderedIfAddrBy),其中
`args` 包括但不限于
[`AscIfType`](https://godoc.org/github.com/hashicorp/go-sockaddr#AscIfType)、
[`AscNetworkSize`](https://godoc.org/github.com/hashicorp/go-sockaddr#AscNetworkSize))
* 排除所有 IPv6 地址
([`IfByType("^(IPv4)$")`](https://godoc.org/github.com/hashicorp/go-sockaddr#IfByType))
* 大于 `/32`
([`IfByMaskSize(32)`](https://godoc.org/github.com/hashicorp/go-sockaddr#IfByMaskSize))
* 不在 `down` 接口上
([`ExcludeIfs("flags", "down")`](https://godoc.org/github.com/hashicorp/go-sockaddr#ExcludeIfs))
* 优先选择 IPv6 地址而不是 IPv4 地址
([`SortIfByType()`](https://godoc.org/github.com/hashicorp/go-sockaddr#SortIfByType) +
[`ReverseIfAddrs()`](https://godoc.org/github.com/hashicorp/go-sockaddr#ReverseIfAddrs));以及
* 排除 RFC6890 地址中的任何 IP
([`IfByRFC("6890")`](https://godoc.org/github.com/hashicorp/go-sockaddr#IfByRFC))
或其中的任何组合与变体。
还有一些简单的辅助函数,例如 `GetPublicIP` 和
`GetPrivateIP`,它们都返回字符串,并分别选择默认接口上的第一个公共或私有
IP 地址。类似地,还有一个
名为 `GetInterfaceIP` 的辅助函数,它返回指定名称接口上的第一个可用 IP
地址。
## `sockaddr` CLI
考虑到 `sockaddr` 库可能存在的复杂性,该库附带了一个 CLI 工具,同样名为
[`sockaddr`](https://github.com/hashicorp/go-sockaddr/tree/master/cmd/sockaddr)。
[`sockaddr`](https://github.com/hashicorp/go-sockaddr/tree/master/cmd/sockaddr)
工具公开了该库的几乎所有功能,可用作
管理工具或测试工具。要安装
[`sockaddr`](https://github.com/hashicorp/go-sockaddr/tree/master/cmd/sockaddr),
请运行:
```
$ go install github.com/hashicorp/go-sockaddr/cmd/sockaddr@latest
```
如果您熟悉 UNIX 的 `sockaddr` 结构体,下图将 C 语言的 `sockaddr`(顶部)映射到 `go-sockaddr` 的结构体(底部)及
接口,这将会对您有所帮助:
```
+-------------------------------------------------------+
| |
| sockaddr |
| SockAddr |
| |
| +--------------+ +----------------------------------+ |
| | sockaddr_un | | | |
| | SockAddrUnix | | sockaddr_in{,6} | |
| +--------------+ | IPAddr | |
| | | |
| | +-------------+ +--------------+ | |
| | | sockaddr_in | | sockaddr_in6 | | |
| | | IPv4Addr | | IPv6Addr | | |
| | +-------------+ +--------------+ | |
| | | |
| +----------------------------------+ |
| |
+-------------------------------------------------------+
```
## 灵感与设计
有许多微妙的灵感促成了这种设计,但过滤语法最直接的灵感来源于
OpenBSD 的
[`pf.conf(5)`](https://www.freebsd.org/cgi/man.cgi?query=pf.conf&apropos=0&sektion=0&arch=default&format=html#PARAMETERS) 防火墙
语法,它允许您选择指定名称接口上的第一个 IP 地址。
最初的问题源于:
* 需要使用 [Packer](https://www.packer.io) 创建不可变镜像,这些镜像运行
[Consul](https://www.consul.io) 进程(Consul 一次只能使用一个 IP
地址);
* 镜像在运行时可能具有也可能没有多个接口或 IP 地址;以及
* 如果虚拟机镜像被用于自动伸缩组,我们不希望依赖配置管理来渲染出正确的
IP 地址。
相反,我们需要某种方法将启发式规则代码化,以便正确选择
正确的 IP 地址,但是在创建镜像时,这些输入参数还是未知的。
标签:EVTX分析, Go, IP地址, Ruby工具, SOC Prime, 套接字, 开发工具, 日志审计, 网络编程