Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
133
plugins/inputs/iptables/README.md
Normal file
133
plugins/inputs/iptables/README.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
# Iptables Input Plugin
|
||||
|
||||
This plugin gathers packets and bytes counters for rules within a set of table
|
||||
and chain from the Linux's iptables firewall.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Rules are identified through associated comment, so you must ensure that the
|
||||
> rules you want to monitor do have a **unique** comment using the `--comment`
|
||||
> flag when adding them. Rules without comments are ignored.
|
||||
|
||||
The rule number cannot be used as identifier as it is not constant and
|
||||
may vary when rules are inserted/deleted at start-up or by automatic tools
|
||||
(interactive firewalls, fail2ban, ...).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The `iptables` command requires `CAP_NET_ADMIN` and `CAP_NET_RAW`
|
||||
> capabilities. Check the [permissions section](#permissions) for ways to
|
||||
> grant them.
|
||||
|
||||
⭐ Telegraf v1.1.0
|
||||
🏷️ network, system
|
||||
💻 linux
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Gather packets and bytes throughput from iptables
|
||||
# This plugin ONLY supports Linux
|
||||
[[inputs.iptables]]
|
||||
## iptables require root access on most systems.
|
||||
## Setting 'use_sudo' to true will make use of sudo to run iptables.
|
||||
## Users must configure sudo to allow telegraf user to run iptables with
|
||||
## no password.
|
||||
## iptables can be restricted to only list command "iptables -nvL".
|
||||
# use_sudo = false
|
||||
|
||||
## Setting 'use_lock' to true runs iptables with the "-w" option.
|
||||
## Adjust your sudo settings appropriately if using this option
|
||||
## ("iptables -w 5 -nvl")
|
||||
# use_lock = false
|
||||
|
||||
## Define an alternate executable, such as "ip6tables". Default is "iptables".
|
||||
# binary = "ip6tables"
|
||||
## defines the table to monitor:
|
||||
table = "filter"
|
||||
|
||||
## defines the chains to monitor.
|
||||
## NOTE: iptables rules without a comment will not be monitored.
|
||||
## Read the plugin documentation for more information.
|
||||
chains = [ "INPUT" ]
|
||||
```
|
||||
|
||||
### Permissions
|
||||
|
||||
The `iptables` command requires `CAP_NET_ADMIN` and `CAP_NET_RAW capabilities`.
|
||||
You have several options to grant permissions to telegraf:
|
||||
|
||||
- Run telegraf as root. This is strongly discouraged.
|
||||
- Configure systemd to run telegraf with CAP_NET_ADMIN and CAP_NET_RAW. This is
|
||||
the simplest and recommended option.
|
||||
- Configure sudo to grant telegraf to run iptables. This is the most
|
||||
restrictive option, but require sudo setup.
|
||||
|
||||
#### Using systemd capabilities
|
||||
|
||||
You may run `systemctl edit telegraf.service` and add the following:
|
||||
|
||||
```shell
|
||||
[Service]
|
||||
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
|
||||
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
|
||||
```
|
||||
|
||||
Since telegraf will fork a process to run iptables, `AmbientCapabilities` is
|
||||
required to transmit the capabilities bounding set to the forked process.
|
||||
|
||||
#### Using sudo
|
||||
|
||||
To use sudo set the `use_sudo` option to `true` and update your sudoers file:
|
||||
|
||||
```bash
|
||||
$ visudo
|
||||
# Add the following line:
|
||||
Cmnd_Alias IPTABLESSHOW = /usr/bin/iptables -nvL *
|
||||
telegraf ALL=(root) NOPASSWD: IPTABLESSHOW
|
||||
Defaults!IPTABLESSHOW !logfile, !syslog, !pam_session
|
||||
```
|
||||
|
||||
### Using IPtables lock feature
|
||||
|
||||
Defining multiple instances of this plugin in telegraf.conf can lead to
|
||||
concurrent IPtables access resulting in "ERROR in input [inputs.iptables]: exit
|
||||
status 4" messages in telegraf.log and missing metrics. Setting 'use_lock =
|
||||
true' in the plugin configuration will run IPtables with the '-w' switch,
|
||||
allowing a lock usage to prevent this error.
|
||||
|
||||
## Metrics
|
||||
|
||||
- iptables
|
||||
- tags:
|
||||
- table
|
||||
- chain
|
||||
- ruleid (comment associated to the rule)
|
||||
- fields:
|
||||
- pkts (integer, count)
|
||||
- bytes (integer, bytes)
|
||||
|
||||
## Example Output
|
||||
|
||||
```shell
|
||||
iptables -nvL INPUT
|
||||
```
|
||||
|
||||
```text
|
||||
Chain INPUT (policy DROP 0 packets, 0 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
100 1024 ACCEPT tcp -- * * 192.168.0.0/24 0.0.0.0/0 tcp dpt:22 /* ssh */
|
||||
42 2048 ACCEPT tcp -- * * 192.168.0.0/24 0.0.0.0/0 tcp dpt:80 /* httpd */
|
||||
```
|
||||
|
||||
```text
|
||||
iptables,table=filter,chain=INPUT,ruleid=ssh pkts=100i,bytes=1024i 1453831884664956455
|
||||
iptables,table=filter,chain=INPUT,ruleid=httpd pkts=42i,bytes=2048i 1453831884664956455
|
||||
```
|
139
plugins/inputs/iptables/iptables.go
Normal file
139
plugins/inputs/iptables/iptables.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
//go:build linux
|
||||
|
||||
package iptables
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
var (
|
||||
errParse = errors.New("cannot parse iptables list information")
|
||||
chainNameRe = regexp.MustCompile(`^Chain\s+(\S+)`)
|
||||
fieldsHeaderRe = regexp.MustCompile(`^\s*pkts\s+bytes\s+target`)
|
||||
valuesRe = regexp.MustCompile(`^\s*(\d+)\s+(\d+)\s+(\w+).*?/\*\s*(.+?)\s*\*/\s*`)
|
||||
)
|
||||
|
||||
const measurement = "iptables"
|
||||
|
||||
type Iptables struct {
|
||||
UseSudo bool `toml:"use_sudo"`
|
||||
UseLock bool `toml:"use_lock"`
|
||||
Binary string `toml:"binary"`
|
||||
Table string `toml:"table"`
|
||||
Chains []string `toml:"chains"`
|
||||
|
||||
lister chainLister
|
||||
}
|
||||
|
||||
type chainLister func(table, chain string) (string, error)
|
||||
|
||||
func (*Iptables) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (ipt *Iptables) Gather(acc telegraf.Accumulator) error {
|
||||
if ipt.Table == "" || len(ipt.Chains) == 0 {
|
||||
return nil
|
||||
}
|
||||
// best effort : we continue through the chains even if an error is encountered,
|
||||
// but we keep track of the last error.
|
||||
for _, chain := range ipt.Chains {
|
||||
data, e := ipt.lister(ipt.Table, chain)
|
||||
if e != nil {
|
||||
acc.AddError(e)
|
||||
continue
|
||||
}
|
||||
e = ipt.parseAndGather(data, acc)
|
||||
if e != nil {
|
||||
acc.AddError(e)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ipt *Iptables) chainList(table, chain string) (string, error) {
|
||||
var binary string
|
||||
if ipt.Binary != "" {
|
||||
binary = ipt.Binary
|
||||
} else {
|
||||
binary = "iptables"
|
||||
}
|
||||
iptablePath, err := exec.LookPath(binary)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var args []string
|
||||
name := iptablePath
|
||||
if ipt.UseSudo {
|
||||
name = "sudo"
|
||||
args = append(args, iptablePath)
|
||||
}
|
||||
if ipt.UseLock {
|
||||
args = append(args, "-w", "5")
|
||||
}
|
||||
args = append(args, "-nvL", chain, "-t", table, "-x")
|
||||
c := exec.Command(name, args...)
|
||||
out, err := c.Output()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
func (ipt *Iptables) parseAndGather(data string, acc telegraf.Accumulator) error {
|
||||
lines := strings.Split(data, "\n")
|
||||
if len(lines) < 3 {
|
||||
return nil
|
||||
}
|
||||
mchain := chainNameRe.FindStringSubmatch(lines[0])
|
||||
if mchain == nil {
|
||||
return errParse
|
||||
}
|
||||
if !fieldsHeaderRe.MatchString(lines[1]) {
|
||||
return errParse
|
||||
}
|
||||
for _, line := range lines[2:] {
|
||||
matches := valuesRe.FindStringSubmatch(line)
|
||||
if len(matches) != 5 {
|
||||
continue
|
||||
}
|
||||
|
||||
pkts := matches[1]
|
||||
bytes := matches[2]
|
||||
target := matches[3]
|
||||
comment := matches[4]
|
||||
|
||||
tags := map[string]string{"table": ipt.Table, "chain": mchain[1], "target": target, "ruleid": comment}
|
||||
fields := make(map[string]interface{})
|
||||
|
||||
var err error
|
||||
fields["pkts"], err = strconv.ParseUint(pkts, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
fields["bytes"], err = strconv.ParseUint(bytes, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
acc.AddFields(measurement, fields, tags)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("iptables", func() telegraf.Input {
|
||||
ipt := &Iptables{}
|
||||
ipt.lister = ipt.chainList
|
||||
return ipt
|
||||
})
|
||||
}
|
33
plugins/inputs/iptables/iptables_notlinux.go
Normal file
33
plugins/inputs/iptables/iptables_notlinux.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
//go:build !linux
|
||||
|
||||
package iptables
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type Iptables struct {
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
}
|
||||
|
||||
func (*Iptables) SampleConfig() string { return sampleConfig }
|
||||
|
||||
func (i *Iptables) Init() error {
|
||||
i.Log.Warn("Current platform is not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*Iptables) Gather(_ telegraf.Accumulator) error { return nil }
|
||||
|
||||
func init() {
|
||||
inputs.Add("iptables", func() telegraf.Input {
|
||||
return &Iptables{}
|
||||
})
|
||||
}
|
251
plugins/inputs/iptables/iptables_test.go
Normal file
251
plugins/inputs/iptables/iptables_test.go
Normal file
|
@ -0,0 +1,251 @@
|
|||
//go:build linux
|
||||
|
||||
package iptables
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestIptables_Gather(t *testing.T) {
|
||||
tests := []struct {
|
||||
table string
|
||||
chains []string
|
||||
values []string
|
||||
tags []map[string]string
|
||||
fields [][]map[string]interface{}
|
||||
err error
|
||||
}{
|
||||
{ // 1 - no configured table => no results
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
`},
|
||||
},
|
||||
{ // 2 - no configured chains => no results
|
||||
table: "filter",
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
`},
|
||||
},
|
||||
{ // 3 - pkts and bytes are gathered as integers
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* foobar */
|
||||
`},
|
||||
tags: []map[string]string{{"table": "filter", "chain": "INPUT", "target": "RETURN", "ruleid": "foobar"}},
|
||||
fields: [][]map[string]interface{}{
|
||||
{map[string]interface{}{"pkts": uint64(57), "bytes": uint64(4520)}},
|
||||
},
|
||||
},
|
||||
{ // 4 - missing fields header => no results
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)`},
|
||||
},
|
||||
{ // 5 - invalid chain header => error
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{
|
||||
`INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
`},
|
||||
err: errParse,
|
||||
},
|
||||
{ // 6 - invalid fields header => error
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
`},
|
||||
err: errParse,
|
||||
},
|
||||
{ // 7 - invalid integer value => best effort, no error
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
K 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
`},
|
||||
},
|
||||
{ // 8 - Multiple rows, multiple chains => no error
|
||||
table: "filter",
|
||||
chains: []string{"INPUT", "FORWARD"},
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
100 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
200 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* foo */
|
||||
`,
|
||||
`Chain FORWARD (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
300 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* bar */
|
||||
400 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
500 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* foobar */
|
||||
`,
|
||||
},
|
||||
tags: []map[string]string{
|
||||
{"table": "filter", "chain": "INPUT", "target": "RETURN", "ruleid": "foo"},
|
||||
{"table": "filter", "chain": "FORWARD", "target": "RETURN", "ruleid": "bar"},
|
||||
{"table": "filter", "chain": "FORWARD", "target": "RETURN", "ruleid": "foobar"},
|
||||
},
|
||||
fields: [][]map[string]interface{}{
|
||||
{map[string]interface{}{"pkts": uint64(200), "bytes": uint64(4520)}},
|
||||
{map[string]interface{}{"pkts": uint64(300), "bytes": uint64(4520)}},
|
||||
{map[string]interface{}{"pkts": uint64(500), "bytes": uint64(4520)}},
|
||||
},
|
||||
},
|
||||
{ // 9 - comments are used as ruleid if any
|
||||
table: "filter",
|
||||
chains: []string{"INPUT"},
|
||||
values: []string{
|
||||
`Chain INPUT (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
57 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 /* foobar */
|
||||
100 4520 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
|
||||
`},
|
||||
tags: []map[string]string{
|
||||
{"table": "filter", "chain": "INPUT", "target": "RETURN", "ruleid": "foobar"},
|
||||
},
|
||||
fields: [][]map[string]interface{}{
|
||||
{map[string]interface{}{"pkts": uint64(57), "bytes": uint64(4520)}},
|
||||
},
|
||||
},
|
||||
{ // 10 - allow trailing text
|
||||
table: "mangle",
|
||||
chains: []string{"SHAPER"},
|
||||
values: []string{
|
||||
`Chain SHAPER (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
0 0 ACCEPT all -- * * 1.3.5.7 0.0.0.0/0 /* test */
|
||||
0 0 CLASSIFY all -- * * 1.3.5.7 0.0.0.0/0 /* test2 */ CLASSIFY set 1:4
|
||||
`},
|
||||
tags: []map[string]string{
|
||||
{"table": "mangle", "chain": "SHAPER", "target": "ACCEPT", "ruleid": "test"},
|
||||
{"table": "mangle", "chain": "SHAPER", "target": "CLASSIFY", "ruleid": "test2"},
|
||||
},
|
||||
fields: [][]map[string]interface{}{
|
||||
{map[string]interface{}{"pkts": uint64(0), "bytes": uint64(0)}},
|
||||
{map[string]interface{}{"pkts": uint64(0), "bytes": uint64(0)}},
|
||||
},
|
||||
},
|
||||
{ // 11 - invalid pkts/bytes
|
||||
table: "mangle",
|
||||
chains: []string{"SHAPER"},
|
||||
values: []string{
|
||||
`Chain SHAPER (policy ACCEPT 58 packets, 5096 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
a a ACCEPT all -- * * 1.3.5.7 0.0.0.0/0 /* test */
|
||||
a a CLASSIFY all -- * * 1.3.5.7 0.0.0.0/0 /* test2 */ CLASSIFY set 1:4
|
||||
`},
|
||||
},
|
||||
{ // 11 - all target and ports
|
||||
table: "all_recv",
|
||||
chains: []string{"accountfwd"},
|
||||
values: []string{
|
||||
`Chain accountfwd (1 references)
|
||||
pkts bytes target prot opt in out source destination
|
||||
123 456 all -- eth0 * 0.0.0.0/0 0.0.0.0/0 /* all_recv */
|
||||
`},
|
||||
tags: []map[string]string{
|
||||
{"table": "all_recv", "chain": "accountfwd", "target": "all", "ruleid": "all_recv"},
|
||||
},
|
||||
fields: [][]map[string]interface{}{
|
||||
{map[string]interface{}{"pkts": uint64(123), "bytes": uint64(456)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.table, func(t *testing.T) {
|
||||
i++
|
||||
ipt := &Iptables{
|
||||
Table: tt.table,
|
||||
Chains: tt.chains,
|
||||
lister: func(string, string) (string, error) {
|
||||
if len(tt.values) > 0 {
|
||||
v := tt.values[0]
|
||||
tt.values = tt.values[1:]
|
||||
return v, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
acc := new(testutil.Accumulator)
|
||||
err := acc.GatherError(ipt.Gather)
|
||||
if !reflect.DeepEqual(tt.err, err) {
|
||||
t.Errorf("%d: expected error '%#v' got '%#v'", i, tt.err, err)
|
||||
}
|
||||
if tt.table == "" {
|
||||
n := acc.NFields()
|
||||
if n != 0 {
|
||||
t.Errorf("%d: expected 0 fields if empty table got %d", i, n)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(tt.chains) == 0 {
|
||||
n := acc.NFields()
|
||||
if n != 0 {
|
||||
t.Errorf("%d: expected 0 fields if empty chains got %d", i, n)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(tt.tags) == 0 {
|
||||
n := acc.NFields()
|
||||
if n != 0 {
|
||||
t.Errorf("%d: expected 0 values got %d", i, n)
|
||||
}
|
||||
return
|
||||
}
|
||||
n := 0
|
||||
for j, tags := range tt.tags {
|
||||
for k, fields := range tt.fields[j] {
|
||||
if len(acc.Metrics) < n+1 {
|
||||
t.Errorf("%d: expected at least %d values got %d", i, n+1, len(acc.Metrics))
|
||||
break
|
||||
}
|
||||
m := acc.Metrics[n]
|
||||
if !reflect.DeepEqual(m.Measurement, measurement) {
|
||||
t.Errorf("%d %d %d: expected measurement '%#v' got '%#v'\n", i, j, k, measurement, m.Measurement)
|
||||
}
|
||||
if !reflect.DeepEqual(m.Tags, tags) {
|
||||
t.Errorf("%d %d %d: expected tags\n%#v got\n%#v\n", i, j, k, tags, m.Tags)
|
||||
}
|
||||
if !reflect.DeepEqual(m.Fields, fields) {
|
||||
t.Errorf("%d %d %d: expected fields\n%#v got\n%#v\n", i, j, k, fields, m.Fields)
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIptables_Gather_listerError(t *testing.T) {
|
||||
errFoo := errors.New("error foobar")
|
||||
ipt := &Iptables{
|
||||
Table: "nat",
|
||||
Chains: []string{"foo", "bar"},
|
||||
lister: func(string, string) (string, error) {
|
||||
return "", errFoo
|
||||
},
|
||||
}
|
||||
acc := new(testutil.Accumulator)
|
||||
err := acc.GatherError(ipt.Gather)
|
||||
if !reflect.DeepEqual(err, errFoo) {
|
||||
t.Errorf("Expected error %#v got\n%#v\n", errFoo, err)
|
||||
}
|
||||
}
|
24
plugins/inputs/iptables/sample.conf
Normal file
24
plugins/inputs/iptables/sample.conf
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Gather packets and bytes throughput from iptables
|
||||
# This plugin ONLY supports Linux
|
||||
[[inputs.iptables]]
|
||||
## iptables require root access on most systems.
|
||||
## Setting 'use_sudo' to true will make use of sudo to run iptables.
|
||||
## Users must configure sudo to allow telegraf user to run iptables with
|
||||
## no password.
|
||||
## iptables can be restricted to only list command "iptables -nvL".
|
||||
# use_sudo = false
|
||||
|
||||
## Setting 'use_lock' to true runs iptables with the "-w" option.
|
||||
## Adjust your sudo settings appropriately if using this option
|
||||
## ("iptables -w 5 -nvl")
|
||||
# use_lock = false
|
||||
|
||||
## Define an alternate executable, such as "ip6tables". Default is "iptables".
|
||||
# binary = "ip6tables"
|
||||
## defines the table to monitor:
|
||||
table = "filter"
|
||||
|
||||
## defines the chains to monitor.
|
||||
## NOTE: iptables rules without a comment will not be monitored.
|
||||
## Read the plugin documentation for more information.
|
||||
chains = [ "INPUT" ]
|
Loading…
Add table
Add a link
Reference in a new issue