Documentation
¶
Overview ¶
Package sgfilter evaluates EC2 security-group rules against network flows and fronts container-published ports with a TCP proxy that admits or refuses clients by those rules. Enforcement is opt-in: a nil *Enforcer admits everything.
Index ¶
- Constants
- func AddrOf(a net.Addr) netip.Addr
- func AllowEgress(groups []Group, f Flow) bool
- func AllowIngress(groups []Group, f Flow) bool
- func Guard(ln net.Listener, admit Admitter) net.Listener
- func NormalizeProtocol(p string) string
- func Pipe(client, up net.Conn)
- type Admitter
- type DefaultGroupSource
- type Dialer
- type Enforcer
- func (e *Enforcer) AdmitIngress(sgIDs []string, proto string, port int, remote net.Addr) bool
- func (e *Enforcer) AdmitIngressInVPC(vpcID string, sgIDs []string, proto string, port int, remote net.Addr) bool
- func (e *Enforcer) Ingress(sgIDs func() []string, proto string, port int) Admitter
- func (e *Enforcer) SetSource(s Source)
- type Flow
- type Group
- type Peer
- type Proxy
- type Rule
- type Source
Constants ¶
const ( ProtoTCP = "tcp" ProtoUDP = "udp" ProtoICMP = "icmp" )
Protocol names used by flows.
const DialTimeout = 10 * time.Second
DialTimeout bounds each upstream dial.
const ProtoAll = "-1"
ProtoAll is the security-group protocol that matches every IP protocol and ignores ports.
Variables ¶
This section is empty.
Functions ¶
func AllowEgress ¶
AllowEgress reports whether any group's egress rule admits the flow; with no matching rule it is denied.
func AllowIngress ¶
AllowIngress reports whether any group admits the flow; with no groups, or no matching rule, it is denied.
func Guard ¶
Guard wraps ln so Accept drops clients admit rejects; a nil admit returns ln unchanged.
func NormalizeProtocol ¶
NormalizeProtocol maps protocol numbers and mixed-case names onto "tcp", "udp" and "icmp"; "-1" and unknown values pass through lower-cased.
Types ¶
type DefaultGroupSource ¶
type DefaultGroupSource interface {
// DefaultGroupID returns the default group of vpcID; an empty vpcID means the default VPC.
DefaultGroupID(vpcID string) string
}
DefaultGroupSource is optionally implemented by a Source that knows each VPC's default security group, which AWS attaches to resources created without one.
type Dialer ¶
type Dialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
Dialer opens upstream connections; *net.Dialer satisfies it and tests inject a fake.
type Enforcer ¶
type Enforcer struct {
// contains filtered or unexported fields
}
Enforcer evaluates flows against the groups its Source reports. A nil Enforcer admits everything, so services hold one unconditionally and the operator flag decides whether it is set.
func New ¶
func New() *Enforcer
New returns an Enforcer with no Source; until SetSource, every group is empty and ingress is denied.
func (*Enforcer) AdmitIngress ¶
AdmitIngress reports whether a client at remote may open proto/port on a target carrying sgIDs.
func (*Enforcer) AdmitIngressInVPC ¶
func (e *Enforcer) AdmitIngressInVPC(vpcID string, sgIDs []string, proto string, port int, remote net.Addr) bool
AdmitIngressInVPC is AdmitIngress for a target in vpcID; with no sgIDs the VPC's default group applies, as AWS does for a resource created without one. An empty vpcID means the default VPC.
type Peer ¶
Peer is the far end of a flow: its address and the security groups attached to it, if known.
type Proxy ¶
type Proxy struct {
// contains filtered or unexported fields
}
Proxy relays accepted connections to one upstream address, refusing clients its Admitter rejects.
func Front ¶
Front listens on bind and relays accepted clients to upstream, refusing those admit rejects; Close stops it.
func NewProxy ¶
NewProxy fronts upstream on ln. A nil admit admits every client; a nil dialer uses a plain net.Dialer.
type Rule ¶
Rule is one ingress or egress permission. A rule matches a peer when any CIDR contains its address or any referenced group is attached to it.
type Source ¶
type Source interface {
// SecurityGroups returns the named groups; unknown IDs are omitted.
SecurityGroups(ids []string) []Group
// GroupsOfAddr lists the security groups attached to the interface owning addr.
GroupsOfAddr(addr netip.Addr) []string
}
Source resolves live security-group state; EC2 implements it so rule changes take effect on the next connection without any push.