netsec

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2020 License: MIT Imports: 3 Imported by: 0

README

netsec CircleCI Go Report Card GoDoc

Home of code related to security of network systems.

Motivation

As we grow as a product and a company we have increasing needs to build secure network services. This can be quite a challenging task as security issues can be hard to anticipate and often depend on complex interactions in distributed systems. The netsec package contains code which helps build and maintain secure Go applications.

Restricting connections to private networks

A common problem that services face is preventing unauthorized access to private networks. This often comes up when the public endpoints of those services are configured dynamically (like a webhook for example).

The netsec package helps protect against malicious use of those kinds of applications by providing a decorator for the typical dial functions used to establish network connections, which can be configured to allow or deny certain IP network ranges.

Here is an example of how a program can leverage the netsec package to prevent HTTP requests from going to private network addresses:

import (
    "net/http"

    "github.com/segmentio/netsec"
)

func init() {
    t := http.DefaultTransport.(*http.Transport)
    // Modifies the dial function used by the default http transport to deny
    // requests that would reach private IP addresses.
    t.DialContext = netsec.RestrictedDial(t.DialContext,
        netsec.Denylist(netsec.PrivateIPNetworks),
    )
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// PrivateIPNetworks lists standard IP networks used for private networks.
	PrivateIPNetworks = []*net.IPNet{
		CIDR("0.0.0.0/32"),
		CIDR("10.0.0.0/8"),
		CIDR("100.64.0.0/10"),
		CIDR("127.0.0.0/8"),
		CIDR("169.254.0.0/16"),
		CIDR("172.16.0.0/12"),
		CIDR("192.168.0.0/16"),
		CIDR("fc00::/7"),
		CIDR("fd00::/8"),
		CIDR("fe80::/10"),
		CIDR("::1/128"),
	}
)

Functions

func CIDR

func CIDR(cidr string) *net.IPNet

CIDR is like net.ParseCIDR but panics if the input is invalid. This function is useful to initialize lists of CIDRs without having to check errors.

func HasRestrictedNetworkBypass added in v1.0.0

func HasRestrictedNetworkBypass(ctx context.Context) bool

HasRestrictedNetworkBypass checks whether or not the context has the value set to bypass restricting connections.

func IPAddressOf

func IPAddressOf(addr net.Addr) net.IP

IPAddressOf extracts the IP address of addr, or returns nil if none were found.

func WithRestrictedNetworkBypass added in v1.0.0

func WithRestrictedNetworkBypass(ctx context.Context) context.Context

WithRestrictedNetworkBypass returns a copy of the parent context with the bypass value set.

Types

type AddrCheck

type AddrCheck interface {
	// Check validates the address passed as argument, returning a non-nil error
	// if it did not pass.
	Check(net.Addr) error
}

AddrCheck is an interface used to abstract the logic of validating network addresses.

Implementations of AddrCheck must be safe to use concurrently from multiple goroutines.

type Allowlist added in v1.0.0

type Allowlist []*net.IPNet

Allowlist is an implementation of the AddrCheck interface which verifies that addresses belong to one of the IP networks it contains.

func (Allowlist) Check added in v1.0.0

func (ipNetList Allowlist) Check(addr net.Addr) error

Check satisfies the AddrCheck interface.

type Denylist added in v1.0.0

type Denylist []*net.IPNet

Denylist is an implementation of the AddrCheck interface which verifies that addresses don't belong to one of the IP networks it contains.

func (Denylist) Check added in v1.0.0

func (ipNetList Denylist) Check(addr net.Addr) error

Check satisfies the AddrCheck interface.

type DialFunc

type DialFunc = func(context.Context, string, string) (net.Conn, error)

DialFunc is an alias for the signature of the functions used to establish network connections.

func RestrictedDial

func RestrictedDial(dial DialFunc, checks ...AddrCheck) DialFunc

RestrictedDial constructs a dial function which validates the address that it establishes connections to.

A typical use case for this function is to pass checks that either allowlists or denylists IP networks, to prevent access to private networks for example:

transport := http.DefaultTransport.(*http.Transport)
transport.DialContext = netsec.RestrictedDial(transport.DialContext,
	netsec.Denylist(netset.PrivateIPAddresses),
)

The implementation protects the program from DNS rebinding attacks because it calls the underlying dial function with the address that it validated, not the address that the program originally dialed.

type RestrictedDialer

type RestrictedDialer struct {
	// The dial function used to establish network connections.
	DialFunc func(context.Context, string, string) (net.Conn, error)

	// List of checks that the dialer is going to apply to the network
	// addresses that it's attempting to connect to.
	Checks []AddrCheck

	// The resolver used to translate host names into network addresses.
	//
	// If nil, net.DefaultResolver is used.
	Resolver interface {
		LookupIPAddr(context.Context, string) ([]net.IPAddr, error)
	}
}

RestrictedDialer

func (*RestrictedDialer) Dial

func (d *RestrictedDialer) Dial(ctx context.Context, network, address string) (net.Conn, error)

Dial resolves the address and applies the list of checks before delegating to the dial function configured on d.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL