Documentation
¶
Overview ¶
* Copyright 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
Index ¶
- Constants
- Variables
- func APIping(appName string, boottime time.Time) func(w http.ResponseWriter, r *http.Request)
- func Chomp(s string) string
- func CreateDawg(sortedDomains []string, outfile string) error
- func DropDNSSECZONEMDp(rrtype uint16) bool
- func DropDNSSECp(rrtype uint16) bool
- func FetchMqttSigningKey(topic, filename string) (*ecdsa.PrivateKey, error)
- func FetchTapirClientCert(lg *log.Logger, statusch chan<- ComponentStatusUpdate) (string, *x509.CertPool, *tls.Certificate, error)
- func HasTag(b, tag TagMask) bool
- func InBailiwick(zone string, ns *dns.NS) bool
- func ListDawg(df dawg.Finder) (int, []string)
- func MqttTopic(commonName string, viperkey string) (string, error)
- func NewClientConfig(caFile, keyFile, certFile string) (*tls.Config, error)
- func NewServerConfig(caFile string, clientAuth tls.ClientAuthType) (*tls.Config, error)
- func NewSimpleClientConfig(caFile string) (*tls.Config, error)
- func ParseCSV(srcfile string, dstmap map[string]TapirName, dontsort bool) ([]string, error)
- func ParseDNSTime(t uint32) time.Time
- func ParseText(srcfile string, dstmap map[string]TapirName, dontsort bool) ([]string, error)
- func PrintRR(rr dns.RR)
- func PrintRRs(rrs []dns.RR)
- func PrintTapirMqttPkg(pkg MqttPkgIn, lg *log.Logger)
- func PrintTapirMsg(tm TapirMsg, lg *log.Logger)
- func SetupLogging(logfile string) error
- func SetupTapirMqttSubPrinter(inbox chan MqttPkgIn)
- func TtyIntQuestion(query string, oldval int, force bool) int
- func TtyQuestion(query, oldval string, force bool) string
- func TtyRadioButtonQ(query, defval string, choices []string) string
- func TtyYesNo(query, defval string) string
- type Action
- type Api
- type ApiClient
- func (api *ApiClient) AddAuthHeader(req *http.Request)
- func (api *ApiClient) RequestNG(method, endpoint string, data interface{}, dieOnError bool) (int, []byte, error)
- func (api *ApiClient) SendPing(pingcount int, dieOnError bool) (PingResponse, error)
- func (api *ApiClient) Setup() error
- func (api *ApiClient) SetupTLS(tlsConfig *tls.Config) error
- func (api *ApiClient) ShowApi()
- func (api *ApiClient) UrlReport(method, endpoint string, data []byte)
- type BootstrapPost
- type BootstrapResponse
- type CliFlags
- type CommandPost
- type CommandResponse
- type ComponentStatus
- type ComponentStatusUpdate
- type Config
- type DebugPost
- type DebugResponse
- type Domain
- type GlobalConfig
- type GlobalConfigTopic
- type MqttData
- type MqttDetails
- type MqttEngine
- func (me *MqttEngine) FetchTopicData(topic string) (TopicData, error)
- func (me *MqttEngine) PubToTopic(topic string, signingkey *ecdsa.PrivateKey, mode string, sign bool) error
- func (me *MqttEngine) RemoveTopic(topic string) error
- func (me *MqttEngine) RestartEngine() (chan MqttEngineCmd, error)
- func (me *MqttEngine) SetupInterruptHandler()
- func (me *MqttEngine) StartEngine() (chan MqttEngineCmd, chan MqttPkgOut, chan MqttPkgIn, error)
- func (me *MqttEngine) Stats() map[string]TopicData
- func (me *MqttEngine) StopEngine() (chan MqttEngineCmd, error)
- func (me *MqttEngine) SubToTopic(topic string, subscriberCh chan MqttPkgIn, mode string, validate bool) error
- type MqttEngineCmd
- type MqttEngineResponse
- type MqttPkgIn
- type MqttPkgOut
- type MqttStats
- type OwnerData
- type Owners
- type PingPost
- type PingResponse
- type PubKeyUpload
- type RRArray
- type RRset
- type RpzName
- type ShowAPIresponse
- type SimpleConfig
- type SloggerCmdPost
- type SloggerCmdResponse
- type StatusUpdaterResponse
- type TagMask
- type TapirComponentStatus
- type TapirFunctionStatus
- type TapirMsg
- type TapirName
- type TapirPubKey
- type TopicData
- type WBGlist
- type ZoneData
- func (zd *ZoneData) ComputeIndices()
- func (zd *ZoneData) DoTransfer(upstream string) (bool, uint32, uint32, error)
- func (zd *ZoneData) FetchFromUpstream(upstream string, current_serial uint32, verbose bool) error
- func (zd *ZoneData) FindGlue(nsrrs RRset) *RRset
- func (zd *ZoneData) PrintOwners()
- func (zd *ZoneData) PrintRRs()
- func (zd *ZoneData) RRSortFunc(rr dns.RR, first_soa *dns.SOA)
- func (zd *ZoneData) ReadZone(r io.Reader) (uint32, error)
- func (zd *ZoneData) ReadZoneFile(filename string) (uint32, error)
- func (zd *ZoneData) ReadZoneString(s string) (uint32, error)
- func (zd *ZoneData) Refresh(upstream string) (bool, error)
- func (zd *ZoneData) Sync() error
- func (zd *ZoneData) WriteFile(filename string, lg *log.Logger) (string, error)
- func (zd *ZoneData) WriteTmpFile(lg *log.Logger) (string, error)
- func (zd *ZoneData) WriteZoneToFile(f *os.File) error
- func (zd *ZoneData) ZoneTransferIn(upstream string, serial uint32, ttype string) (uint32, error)
- type ZoneType
Constants ¶
const ( DefaultPopCfgFile = "/etc/dnstapir/dnstapir-pop.yaml" PopSourcesCfgFile = "/etc/dnstapir/pop-sources.yaml" PopOutputsCfgFile = "/etc/dnstapir/pop-outputs.yaml" PopPolicyCfgFile = "/etc/dnstapir/pop-policy.yaml" )
const ( TapirPub uint8 = 1 << iota TapirSub )
const DefaultSloggerCfgFile = "/etc/dnstapir/slogger.yaml"
const DefaultTapirCliCfgFile = "/etc/dnstapir/dnstapir-cli.yaml"
const (
TimeLayout = "2006-01-02 15:04:05"
)
Variables ¶
var ActionToCNAMETarget = map[Action]string{ NXDOMAIN: ".", NODATA: "*.", DROP: "rpz-drop.", ALLOWLIST: "rpz-passthru.", REDIRECT: "what-to-do-about-this", }
var ActionToString = map[Action]string{ NXDOMAIN: "NXDOMAIN", NODATA: "NODATA", DROP: "DROP", ALLOWLIST: "ALLOWLIST", REDIRECT: "WHAT-TO-DO-ABOUT-REDIRECTS", }
var DefinedTags = []string{
"newname", "highvolume", "badip", "cdntracker", "likelymalware", "likelybotnetcc",
"foo", "bar", "baz", "gazonk", "frotz",
}
var StatusToString = map[ComponentStatus]string{ StatusOK: "ok", StatusWarn: "warn", StatusFail: "fail", StatusReport: "report", }
var StringToStatus = map[string]ComponentStatus{ "ok": StatusOK, "warn": StatusWarn, "fail": StatusFail, "report": StatusReport, }
Functions ¶
func CreateDawg ¶
func DropDNSSECZONEMDp ¶
func DropDNSSECp ¶
func FetchMqttSigningKey ¶
func FetchMqttSigningKey(topic, filename string) (*ecdsa.PrivateKey, error)
func FetchTapirClientCert ¶
func FetchTapirClientCert(lg *log.Logger, statusch chan<- ComponentStatusUpdate) (string, *x509.CertPool, *tls.Certificate, error)
func MqttTopic ¶
MqttTopic returns the MQTT topic for a given common name and viper key. The raw topic is something like "status/up/{EdgeId}/tapir-pop" and is specified in the tapir-pop.yaml config file. The common name is the common name of the TAPIR Edge cert.
func NewServerConfig ¶
Create a tls.Config for a server. clientAuth: tls.NoClientCert => Accept any client. clientAuth: tls.RequireAndVerifyClientCert => Only accept client with valid cert.
func NewSimpleClientConfig ¶
NewSimpleClientConfig creates a TLS config with a common CA cert, specified in caFile, but without a client certificate.
func ParseDNSTime ¶
func ParseText ¶
Two modes of operation: either return a (potentially large) []string with sorted output *or* update the dstmap of TapirNames directly and don't return the result
func PrintTapirMqttPkg ¶
XXX: Only used for debugging
func PrintTapirMsg ¶
func SetupLogging ¶
func SetupTapirMqttSubPrinter ¶
func SetupTapirMqttSubPrinter(inbox chan MqttPkgIn)
XXX: Only used for debugging
func TtyQuestion ¶
func TtyRadioButtonQ ¶
Types ¶
type ApiClient ¶
type ApiClient struct {
BaseUrl string
AuthMethod string
ApiKey string
Timeout int
ClientName string // ClientName is used to figure out which client cert to use for TLS setup.
UseTLS bool
Verbose bool
Debug bool
HttpClient *http.Client
}
func (*ApiClient) AddAuthHeader ¶
this function will die when we kill the individual request functions.
func (*ApiClient) SendPing ¶
func (api *ApiClient) SendPing(pingcount int, dieOnError bool) (PingResponse, error)
type BootstrapPost ¶
type BootstrapResponse ¶
type CliFlags ¶
type CliFlags struct {
ShowHdr bool
Verbose bool
Debug bool
UseTLS bool
Api *ApiClient
PingCount int
Zone string
// TODO cleaner solution:
// Moved "certname" from slogger.go here so it can know what cert to look
// for. "certname" was previously declared globally in "root.go", but since
// the move to the tapir lib, slogger.go no longer sees that variable.
Certname string
}
var GlobalCF CliFlags
type CommandPost ¶
type CommandPost struct {
Command string
Zone string
Name string // Domain name to add/remove an RPZ action for
ListType string
ListName string // used in the export-doubtlist command
Policy string // RPZ policy
Action string // RPZ action (OBE)
RpzSource string // corresponds with the sourceid in tem.yaml
}
type CommandResponse ¶
type ComponentStatus ¶
type ComponentStatus uint8
Status alternatives known to StatusUpdater()
const ( StatusFail ComponentStatus = iota StatusWarn StatusOK StatusReport // Not a component status, but a request for a status report )
type ComponentStatusUpdate ¶
type ComponentStatusUpdate struct {
Status ComponentStatus
Function string // tapir-pop | tapir-edm | ...
Component string // downstream | rpz | mqtt | config | ...
Msg string
TimeStamp time.Time
Response chan StatusUpdaterResponse
}
ComponentStatusUpdate is used to send status updates for a single component of a "function" (tapir-pop, tapir-edm, etc)
type DebugResponse ¶
type DebugResponse struct {
Time time.Time
Status string
Zone string
// ZoneData ZoneData
OwnerIndex map[string]int
RRset RRset
Lists map[string]map[string]*WBGlist
Allowlists map[string]*WBGlist
Denylists map[string]*WBGlist
Doubtlists map[string]*WBGlist
DenylistedNames map[string]bool
DoubtlistedNames map[string]*TapirName
RpzOutput []RpzName
MqttStats MqttStats
TopicData map[string]TopicData
ReaperStats map[string]map[time.Time][]string
Msg string
Error bool
ErrorMsg string
}
type GlobalConfig ¶
type GlobalConfig struct {
TapirConfigVersion string
Rpz struct {
EnvelopeSize int // Number of dns.RRs per zone transfer envelope
}
Bootstrap struct {
Servers []string
BaseUrl string
ApiToken string
}
ObservationTopics []GlobalConfigTopic
StatusTopics []GlobalConfigTopic
}
Things we need to have in the global config include: - dns-tapir bootstrap server details - number of RRs to send in a dns.Envelope{}
type GlobalConfigTopic ¶
type MqttData ¶
OBE! MqttData is what is returned from the MQTT Engine for unparsed messages. The payload is left as []byte because it can be of arbitrary type, not just TapirMsg.
type MqttDetails ¶
type MqttEngine ¶
type MqttEngine struct {
Running bool
Creator string
ClientID string
Server string
QoS int
ConnectionManager *autopaho.ConnectionManager
ClientCert tls.Certificate
CaCertPool *x509.CertPool
MsgChan chan paho.PublishReceived
CmdChan chan MqttEngineCmd
PublishChan chan MqttPkgOut
SubscribeChan chan MqttPkgIn
DataMu sync.Mutex
TopicData map[string]TopicData // map[topic]TopicData
PrefixTopics map[string]bool // eg. "pubkey/up/" is a prefix topic if we subscribe to pubkey/up/#
CanPublish bool // can publish to all topics
CanSubscribe bool // can subscribe to all topics
Logger *log.Logger
Cancel context.CancelFunc
Keystore jwk.Set
}
func NewMqttEngine ¶
func NewMqttEngine(creator, clientid string, pubsub uint8, statusch chan ComponentStatusUpdate, lg *log.Logger) (*MqttEngine, error)
func (*MqttEngine) FetchTopicData ¶
func (me *MqttEngine) FetchTopicData(topic string) (TopicData, error)
func (*MqttEngine) PubToTopic ¶
func (me *MqttEngine) PubToTopic(topic string, signingkey *ecdsa.PrivateKey, mode string, sign bool) error
func (*MqttEngine) RemoveTopic ¶
func (me *MqttEngine) RemoveTopic(topic string) error
func (*MqttEngine) RestartEngine ¶
func (me *MqttEngine) RestartEngine() (chan MqttEngineCmd, error)
func (*MqttEngine) SetupInterruptHandler ¶
func (me *MqttEngine) SetupInterruptHandler()
Trivial interrupt handler to catch SIGTERM and stop the MQTT engine nicely
func (*MqttEngine) StartEngine ¶
func (me *MqttEngine) StartEngine() (chan MqttEngineCmd, chan MqttPkgOut, chan MqttPkgIn, error)
func (*MqttEngine) Stats ¶
func (me *MqttEngine) Stats() map[string]TopicData
func (*MqttEngine) StopEngine ¶
func (me *MqttEngine) StopEngine() (chan MqttEngineCmd, error)
func (*MqttEngine) SubToTopic ¶
type MqttEngineCmd ¶
type MqttEngineCmd struct {
Cmd string
Resp chan MqttEngineResponse
}
type MqttEngineResponse ¶
type MqttPkgIn ¶
type MqttPkgIn struct {
Type string // text | data, only used on sender side
Error bool // only used for sub.
ErrorMsg string // only used for sub.
Msg string
Topic string // topic on which this message arrived
Retain bool
// Data TapirMsg
// RawData interface{} // outgoing data, an unparsed struct
Payload []byte // incoming data, as received from the network
Validated bool
TimeStamp time.Time // time mqtt packet was sent or received, mgmt by MQTT Engine
}
type MqttPkgOut ¶
type MqttPkgOut struct {
Type string // text | data, only used on sender side
Error bool // only used for sub.
ErrorMsg string // only used for sub.
Msg string
Topic string // topic on which this message arrived
Retain bool
Data TapirMsg
RawData interface{} // outgoing data, an unparsed struct
TimeStamp time.Time // time mqtt packet was sent or received, mgmt by MQTT Engine
}
MqttPkg is what is sent to the MQTT Engine and returned when an incoming message is parsed.
type PingResponse ¶
type PubKeyUpload ¶
type RRArray ¶
RRArray represents an array of rrs It implements Swapper interface, and is sortable.
func (RRArray) Less ¶
Less returns true if the element in the position i of RRArray is less than the element in position j of RRArray.
type ShowAPIresponse ¶
type SimpleConfig ¶
type SimpleConfig struct {
CAFile string `validate:"existing-file-ro"`
}
type SloggerCmdPost ¶
type SloggerCmdPost struct {
Command string
}
type SloggerCmdResponse ¶
type SloggerCmdResponse struct {
Time time.Time
// TapirFunctionStatus TapirFunctionStatus
PopStatus map[string]TapirFunctionStatus
EdmStatus map[string]TapirFunctionStatus
Msg string
Error bool
ErrorMsg string
}
type StatusUpdaterResponse ¶
type StatusUpdaterResponse struct {
FunctionStatus TapirFunctionStatus
KnownComponents []string
Msg string
Error bool
ErrorMsg string
}
type TapirComponentStatus ¶
type TapirComponentStatus struct {
Component string
Status ComponentStatus
ErrorMsg string
WarningMsg string
Msg string
NumFails int
NumWarnings int
LastFail time.Time
LastWarn time.Time
LastSuccess time.Time
}
TapirComponentStatus contains the status for a single component of a "function" (tapir-pop, tapir-edm, etc)
type TapirFunctionStatus ¶
type TapirFunctionStatus struct {
Function string // tapir-pop | tapir-edm | ...
FunctionID string
ComponentStatus map[string]TapirComponentStatus // downstreamnotify | downstreamixfr | rpzupdate | mqttmsg | config | ...
NumFailures int
LastFailure time.Time
}
TapirFunctionStatus contains the status for all components of this "function" (tapir-pop, tapir-edm, etc)
type TapirMsg ¶
type TapirMsg struct {
SrcName string `json:"src_name"` // must match a defined source
Creator string `json:"creator"` // "spark" || "tapir-cli"
MsgType string `json:"msg_type"` // "observation", "reset", "global-config"...
ListType string `json:"list_type"` // "{allow|deny|doubt}list"
Added []Domain `json:"added"`
Removed []Domain `json:"removed"`
Msg string `json:"msg"`
// GlobalConfig GlobalConfig
// TapirFunctionStatus TapirFunctionStatus
TimeStamp time.Time `json:"timestamp"` // time encoded in the payload by the sender, not touched by MQTT
TimeStr string `json:"time_str"` // time string encoded in the payload by the sender, not touched by MQTT
}
TapirMsg is what is recieved over the MQTT bus.
type TapirName ¶
type TapirName struct {
// SrcFormat string // "tapir-feed-v1" | ...
Name string
TimeAdded time.Time
TTL time.Duration
// Tags []string // XXX: extremely wasteful, a bitfield would be better,
TagMask TagMask // bitfield
NumTags uint8
// but don't know how many tags there can be
Action Action // bitfield NXDOMAIN|NODATA|DROP|...
}
type TapirPubKey ¶
type TapirPubKey struct {
Pubkey string
}
type TopicData ¶
type TopicData struct {
Topic string // topic must be in the TopicData, because sometimes we change it, and we need to keep the TopicData entry.
SigningKey *ecdsa.PrivateKey
Sign bool
Validate bool // should incoming messages be validated by the validator key?
PubMode string // "raw" indicates that the data should just be passed through untouched
SubMode string // "raw" indicates that the data should just be passed through untouched
SubscriberCh chan MqttPkgIn
PubMsgs uint32
SubMsgs uint32
LatestPub time.Time
LatestSub time.Time
}
type WBGlist ¶
type WBGlist struct {
Name string
Description string
Type string // allowlist | denylist | doubtlist
Immutable bool // true = won't be updated by globalconfig topic.
SrcFormat string // Format of external source: dawg | rpz | tapir-mqtt-v1 | ...
Format string // Format of internal storage: dawg | map | slice | trie | rbtree | ...
Datasource string // file | xfr | mqtt | https | api | ...
Filename string
Upstream string
Dawgf dawg.Finder
MqttDetails *MqttDetails
// doubtlist sources needs more complex stuff here:
// DoubtNames map[string]DoubtName
RpzZoneName string
RpzUpstream string
RpzSerial int
Names map[string]TapirName // XXX: same data as in ZoneData.RpzData, should only keep one
ReaperData map[time.Time]map[string]bool
}
type ZoneData ¶
type ZoneData struct {
ZoneName string
ZoneType ZoneType // 1 = "xfr", 2 = "map", 3 = "slice". An xfr zone only supports xfr related ops
Owners Owners
OwnerIndex map[string]int
ApexLen int // # RRs that are stored separately
SOA dns.SOA
NSrrs []dns.RR // apex NS RRs
// Rest of zone
BodyRRs RRArray
RRs RRArray // BodyRRs + ApexRRs
// Data map[string]map[uint16][]dns.RR // map[owner]map[rrtype][]dns.RR
Data map[string]OwnerData // map[owner]map[rrtype][]dns.RR
RpzMap map[string]*RpzName // map[owner]map[rrtype][]dns.RR
// Other stuff
DroppedRRs int
KeptRRs int
XfrType string // axfr | ixfr
Logger *log.Logger
IncomingSerial uint32
// RRKeepFunc func(uint16) bool
RRParseFunc func(*dns.RR, *ZoneData) bool
Verbose bool
Debug bool
}
func (*ZoneData) ComputeIndices ¶
func (zd *ZoneData) ComputeIndices()
func (*ZoneData) DoTransfer ¶
func (*ZoneData) FetchFromUpstream ¶
func (*ZoneData) PrintOwners ¶
func (zd *ZoneData) PrintOwners()