Documentation
¶
Overview ¶
Package protocol contains functions for performing protocol detection.
Confidence scores ¶
All registered detectors in this package shall output a confidence score. If there are multiple matching protocols, the protocol with the highest confidence score will be returned to the caller.
Confidence scores should be between 0 and 0.99, but there is no hard enforcement of this range in this package.
Protocol matching ¶
The first level matching happens with magic strings, as inspired by Go's image.RegisterFormat function. The only addition that this package has made, is that you can also use the '*' character for wildcard matching.
The supported magic strings input is documented in the Match function.
Strict mode ¶
Some parser also allow for strict parsing of the protocol, which results in a higher confidence score, but it also may lead to more false negatives. If Strict mode is enabled, then only the detectors that support strict checking will be used for protocol detections.
Index ¶
- Constants
- Variables
- func Limit(conn net.Conn, accept AcceptFunc) net.Conn
- func Match(magic string, input []byte) bool
- func Register(dir Direction, magic string, detect DetectFunc)
- type AcceptFunc
- type DetectFunc
- type Direction
- type Intercepted
- type Interceptor
- type Protocol
- func Detect(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64, err error)
- func Probe(network, address string) (proto *Protocol, confidence float64, err error)
- func ProbeContext(ctx context.Context, network, address string) (proto *Protocol, confidence float64, err error)
- func ProbeTLS(network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)
- func ProbeTLSContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)
- func ProbeTLSTimeout(network, address string, tlsConfig *tls.Config, timeout time.Duration) (proto *Protocol, confidence float64, err error)
- func ProbeTimeout(network, address string, timeout time.Duration) (proto *Protocol, confidence float64, err error)
- type Version
Examples ¶
Constants ¶
const ( TypeACME = "ACME" TypeCoAP = "CoAP" TypeDNS = "DNS" TypeFTP = "FTP" TypeHTTP = "HTTP" TypeIRC = "IRC" TypeIMAP = "IMAP" TypeJabber = TypeXMPP TypeManageSieve = "ManageSieve" TypeMosquitto = TypeMQTT TypeMQTT = "MQTT" TypeMySQL = "MySQL" TypeNNTP = "NNTP" TypePOP3 = "POP3" TypePgSQL = TypePostgreSQL TypePostgreSQL = "PostgreSQL" TypeRADIUS = "RADIUS" TypeSamba = TypeSMB TypeSIP = "SIP" TypeSMB = "SMB" TypeSSH = "SSH" TypeSSL = "SSL" TypeSTUN = "STUN" TypeSunRPC = "SunRPC" TypeTLS = "TLS" TypeWebRTC = "WebRTC" TypeXMPP = "XMPP" )
Protocols supported by this package.
Variables ¶
var ( ErrTimeout = errors.New("timeout") ErrUnknown = errors.New("unknown protocol") )
Common errors.
var ALPNProtocol = map[string]*Protocol{ "acme-tls/1": {Type: TypeACME, Encapsulation: TypeTLS, Version: Version{Major: 1}}, "co": {Type: TypeCoAP, Encapsulation: TypeTLS}, "coap": {Type: TypeCoAP, Encapsulation: TypeTLS}, "c-webrtc": {Type: TypeWebRTC, Encapsulation: TypeTLS}, "dot": {Type: TypeDNS, Encapsulation: TypeTLS}, "ftp": {Type: TypeFTP, Encapsulation: TypeTLS}, "http/0.9": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 0, Minor: 9, Patch: -1}}, "http/1.0": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 0, Patch: -1}}, "http/1.1": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 1, Patch: -1}}, "h2": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}}, "h2c": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}}, "h3": {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 3, Minor: -1, Patch: -1}}, "irc": {Type: TypeIRC, Encapsulation: TypeTLS}, "imap": {Type: TypeIMAP, Encapsulation: TypeTLS}, "managesieve": {Type: TypeManageSieve, Encapsulation: TypeTLS}, "mqtt": {Type: TypeMQTT, Encapsulation: TypeTLS}, "nntp": {Type: TypeNNTP, Encapsulation: TypeTLS}, "nnsp": {Type: TypeNNTP, Encapsulation: TypeTLS}, "postgresql": {Type: TypePostgreSQL, Encapsulation: TypeTLS}, "pop3": {Type: TypePOP3, Encapsulation: TypeTLS}, "radius/1.0": {Type: TypeRADIUS, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 0, Patch: -1}}, "radius/1.1": {Type: TypeRADIUS, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 1, Patch: -1}}, "smb": {Type: TypeSMB, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}}, "stun.nat-discovery": {Type: TypeSTUN, Encapsulation: TypeTLS}, "stun.turn": {Type: TypeSTUN, Encapsulation: TypeTLS}, "sunrpc": {Type: TypeSunRPC, Encapsulation: TypeTLS}, "webrtc": {Type: TypeWebRTC, Encapsulation: TypeTLS}, "xmpp-client": {Type: TypeXMPP, Encapsulation: TypeTLS}, "xmpp-server": {Type: TypeXMPP, Encapsulation: TypeTLS}, }
ALPNProtocol is a map of TLS Application-Layer Protocol Negotiation (ALPN) Protocol identifier to Protocol.
var Dialer net.Dialer
Dialer used by probes to establish a connection.
var Strict bool
Strict mode requires a full, compliant packet to be captured. This is only implemented by some detectors.
Functions ¶
func Limit ¶
func Limit(conn net.Conn, accept AcceptFunc) net.Conn
Limit the connection protocol, by running a detection after either side sends a banner within timeout.
If no protocol could be detected, the accept function is called with a nil argument to check if we should proceed.
If the accept function returns an error, all future reads and writes on the returned connection will return that error.
func Match ¶
Match the input against the magic string pattern.
- '?' matches any single character
- '*' matches zero or more characters
- '\' escapes special characters ('?', '*', '\')
- all other characters must match exactly
Returns true if all magic bytes are matched, even if the input has extra bytes.
Example ¶
package main
import (
"fmt"
"git.maze.io/go/dpi/protocol"
)
func main() {
fmt.Println(protocol.Match("t?s?", []byte("test")))
fmt.Println(protocol.Match("t?s?", []byte("test with more data")))
fmt.Println(protocol.Match("t?s?", []byte("text with more data")))
fmt.Println(protocol.Match("select * from user", []byte("select an apple from user")))
fmt.Println(protocol.Match("select * from user", []byte("select an apple from the user")))
}
Output: true true false true false
func Register ¶
func Register(dir Direction, magic string, detect DetectFunc)
Register a new protocol detector.
The direction indicates in what direction we'll inspect the []byte slice passed to the Detect function. Passing an invalid direction or None will be discarded.
The magic string is used to quickly analyze if the []byte slice passed to Detect qualifies for further inspection by the DetectFunc. See the Match function documentation for how magic strings are matched against the input.
Types ¶
type AcceptFunc ¶
AcceptFunc receives a direction and a detected protocol.
type DetectFunc ¶
type DetectFunc func(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64)
DetectFunc is a function which runs the in-depth protcol detection logic.
The confidence score should be between 0 and 0.99. Score boundaries are not hard enforced by this library.
type Direction ¶
type Direction int
Direction indicates the communcation direction.
const ( // Unknown direction is the default value and is not a valid Direction. Unknown Direction = iota // Client initiated. Client // Server initiated. Server // Both is either client or server initiated. Both )
Directions supported by this package.
func (Direction) Contains ¶
Contains checks if the provided other direction is included in this direction.
type Intercepted ¶
Intercepted is the result returned by Interceptor.Detect.
type Interceptor ¶
type Interceptor struct {
// contains filtered or unexported fields
}
Interceptor intercepts reads from client or server.
func NewInterceptor ¶
func NewInterceptor() *Interceptor
NewInterceptor creates a new (transparent) protocol interceptor.
func (*Interceptor) Client ¶
func (i *Interceptor) Client(c net.Conn) net.Conn
Client binds the client connection to the interceptor.
func (*Interceptor) Detect ¶
func (i *Interceptor) Detect(timeout time.Duration) <-chan *Intercepted
Detect runs protocol detection on the previously bound Client and Server connection.
It waits until either the client or the server performs a read operation, which is then used for running protocol detection. If the read operation takes longer than timeout, an error is returned.
The returned channel always yields one result and is then closed.
type Protocol ¶
type Protocol struct {
// Type of protocol, usually one of the constants defined in this package.
Type string
// Encapsulation type, usually one of the constants defined in this package.
//
// Empty if there is no encapsulation.
Encapsulation string
// Version of the protocol. Unknown versions are marked with [UnknownVersion].
Version Version
}
Protocol description.
func Detect ¶
func Detect(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64, err error)
Detect a protocol based on the provided data.
func ProbeContext ¶
func ProbeContext(ctx context.Context, network, address string) (proto *Protocol, confidence float64, err error)
ProbeContext is like Probe with a context.Context.
func ProbeTLS ¶
func ProbeTLS(network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)
ProbeTLS is like Probe but first establishes a TLS connection.
func ProbeTLSContext ¶
func ProbeTLSContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)
ProbeTLSContext is like ProbeTLS with a context.Context.
func ProbeTLSTimeout ¶
func ProbeTLSTimeout(network, address string, tlsConfig *tls.Config, timeout time.Duration) (proto *Protocol, confidence float64, err error)
ProbeTLSTimeout is like ProbeTLS but with a fixed timeout.