From ffd96e60ac776e83fe0624705369943b4fa785ac Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 20 Mar 2019 10:04:59 +0100 Subject: [PATCH 01/25] Enable setting of promiscuous mode --- packetbeat/sniffer/afpacket_linux.go | 61 ++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 3a8cf83ca79..deb6df48e30 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -20,22 +20,41 @@ package sniffer import ( + "bytes" + "errors" + "fmt" + "os/exec" "time" + "github.com/elastic/beats/libbeat/logp" + "github.com/tsg/gopacket" "github.com/tsg/gopacket/afpacket" "github.com/tsg/gopacket/layers" ) type afpacketHandle struct { - TPacket *afpacket.TPacket + TPacket *afpacket.TPacket + promicsPreviousState bool + device string } func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int, timeout time.Duration) (*afpacketHandle, error) { - h := &afpacketHandle{} - var err error + promiscEnabled, err := isPromiscEnabled(device) + if err != nil { + return nil, err + } + + h := &afpacketHandle{ + promicsPreviousState: promiscEnabled, + device: device, + } + + if err := setPromiscMode(device, true); err != nil { + return nil, err + } if device == "any" { h.TPacket, err = afpacket.NewTPacket( @@ -69,4 +88,40 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() + setPromiscMode(h.device, h.promicsPreviousState) +} + +func isPromiscEnabled(device string) (bool, error) { + if device == "any" { + return false, nil + } + + c := exec.Command("ip", "link", "show", device) + out, err := c.CombinedOutput() + if err != nil { + return false, fmt.Errorf(string(out)) + } + + return bytes.Contains(out, []byte("PROMISC")), nil +} + +func setPromiscMode(device string, enabled bool) error { + if device == "any" { + logp.Warn("Cannot set promiscuous mode to device 'any'") + return nil + } + + mode := "off" + if enabled { + mode = "on" + } + + c := exec.Command("ip", "link", "set", device, "promisc", mode) + out, err := c.CombinedOutput() + if err != nil { + logp.Err("Error occurred when setting promisc mode of %s to %v: %v", device, enabled, err) + return errors.New(string(out)) + } + + return nil } From 46db28aa3b45fc7d4a1968b3724d07cf499f2984 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 20 Mar 2019 15:28:43 +0100 Subject: [PATCH 02/25] seccomp disabled --- packetbeat/packetbeat.reference.yml | 4 +++- packetbeat/packetbeat.yml | 7 +++++++ packetbeat/sniffer/afpacket_linux.go | 8 +++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 30a3e7ebb0d..ecd6e245ce7 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1630,7 +1630,9 @@ logging.files: #============================= Process Security ================================ # Enable or disable seccomp system call filtering on Linux. Default is enabled. -#seccomp.enabled: true +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false #================================= Migration ================================== diff --git a/packetbeat/packetbeat.yml b/packetbeat/packetbeat.yml index 02b9db547cf..0e1e191bbc6 100644 --- a/packetbeat/packetbeat.yml +++ b/packetbeat/packetbeat.yml @@ -229,6 +229,13 @@ processors: # following line. #xpack.monitoring.elasticsearch: +#============================= Process Security ================================ + +# Enable or disable seccomp system call filtering on Linux. Default is enabled. +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false + #================================= Migration ================================== # This allows to enable 6.7 migration aliases diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index deb6df48e30..bb046e1967a 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -44,7 +44,7 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in promiscEnabled, err := isPromiscEnabled(device) if err != nil { - return nil, err + logp.Err("Failed to get promiscuous mode for device '%s': %v", device, err) } h := &afpacketHandle{ @@ -53,7 +53,7 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in } if err := setPromiscMode(device, true); err != nil { - return nil, err + logp.Err("Failed to set promiscuous mode for device '%s': %v", device, err) } if device == "any" { @@ -88,7 +88,9 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() - setPromiscMode(h.device, h.promicsPreviousState) + if err := setPromiscMode(h.device, h.promicsPreviousState); err != nil { + logp.Err("Failed to set promiscuous mode for device '%s': %v", device, err) + } } func isPromiscEnabled(device string) (bool, error) { From 637eaabc2e41f5b7dca428519ba515597ae8dc62 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 12:29:47 +0100 Subject: [PATCH 03/25] update faq --- packetbeat/docs/faq.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/packetbeat/docs/faq.asciidoc b/packetbeat/docs/faq.asciidoc index 525d80d114c..2ac2f0b9197 100644 --- a/packetbeat/docs/faq.asciidoc +++ b/packetbeat/docs/faq.asciidoc @@ -22,6 +22,7 @@ ip link set promisc on ---------------------------------------------------------------------- For example: `ip link set enp5s0f1 promisc on` +Packetbeat sets promiscuous mode automatically when seccomp is disabled. [float] [[packetbeat-loopback-interface]] From 1ff481894e247467e52983a12a37a1192903701a Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 12:33:43 +0100 Subject: [PATCH 04/25] changelog --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 22953397fc6..55cfad14fb3 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -111,6 +111,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - `http.response.body` moves to `http.response.body.content` - Changed Packetbeat fields to align with ECS. {issue}7968[7968] - Removed trailing dot from domain names reported by the DNS protocol. {pull}9941[9941] +- Enable setting promiscuous mode automatically. {pull}11366[11366] *Winlogbeat* From 7fc011ea3d1aee455fc437634b709acc658aa903 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 12:45:36 +0100 Subject: [PATCH 05/25] fix --- packetbeat/sniffer/afpacket_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index bb046e1967a..8ca19faa8e4 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -89,7 +89,7 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() if err := setPromiscMode(h.device, h.promicsPreviousState); err != nil { - logp.Err("Failed to set promiscuous mode for device '%s': %v", device, err) + logp.Err("Failed to set promiscuous mode for device '%s': %v", h.device, err) } } From 4e140f3132f505df7ad3bf7832565de80e2d780d Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 13:08:15 +0100 Subject: [PATCH 06/25] mage update --- packetbeat/_meta/beat.reference.yml | 7 +++++++ packetbeat/_meta/beat.yml | 7 +++++++ packetbeat/packetbeat.reference.yml | 11 ++++++++--- packetbeat/packetbeat.yml | 14 +++++++------- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packetbeat/_meta/beat.reference.yml b/packetbeat/_meta/beat.reference.yml index a77690bb8f9..4ffeb49d09d 100644 --- a/packetbeat/_meta/beat.reference.yml +++ b/packetbeat/_meta/beat.reference.yml @@ -478,3 +478,10 @@ packetbeat.procs.enabled: false # duplicates if shippers are installed on multiple servers. Default value is # false. packetbeat.ignore_outgoing: false + +#============================= Process Security ================================ + +# Enable or disable seccomp system call filtering on Linux. Default is enabled. +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false diff --git a/packetbeat/_meta/beat.yml b/packetbeat/_meta/beat.yml index 8c8037a5e7c..75cc439ebd8 100644 --- a/packetbeat/_meta/beat.yml +++ b/packetbeat/_meta/beat.yml @@ -107,3 +107,10 @@ setup.template.settings: index.number_of_shards: 1 #index.codec: best_compression #_source.enabled: false + +#============================= Process Security ================================ + +# Enable or disable seccomp system call filtering on Linux. Default is enabled. +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index ecd6e245ce7..8088b09fc1c 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -479,6 +479,13 @@ packetbeat.procs.enabled: false # false. packetbeat.ignore_outgoing: false +#============================= Process Security ================================ + +# Enable or disable seccomp system call filtering on Linux. Default is enabled. +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false + #================================ General ====================================== # The name of the shipper that publishes the network data. It can be used to group @@ -1630,9 +1637,7 @@ logging.files: #============================= Process Security ================================ # Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false +#seccomp.enabled: true #================================= Migration ================================== diff --git a/packetbeat/packetbeat.yml b/packetbeat/packetbeat.yml index 0e1e191bbc6..b19a87c62a8 100644 --- a/packetbeat/packetbeat.yml +++ b/packetbeat/packetbeat.yml @@ -108,6 +108,13 @@ setup.template.settings: #index.codec: best_compression #_source.enabled: false +#============================= Process Security ================================ + +# Enable or disable seccomp system call filtering on Linux. Default is enabled. +# Seccomp is disabled in order to help with setting of promiscuous mode. +# If you enable seccomp you will need to enable promiscuous on the device manually. +seccomp.enabled: false + #================================ General ===================================== # The name of the shipper that publishes the network data. It can be used to group @@ -229,13 +236,6 @@ processors: # following line. #xpack.monitoring.elasticsearch: -#============================= Process Security ================================ - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false - #================================= Migration ================================== # This allows to enable 6.7 migration aliases From 70dc0cda9d0faf8abe1d482aee55721b4eaa8747 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 17:06:59 +0100 Subject: [PATCH 07/25] syscall --- packetbeat/_meta/beat.reference.yml | 7 ----- packetbeat/_meta/beat.yml | 6 ---- packetbeat/docs/faq.asciidoc | 1 - packetbeat/packetbeat.reference.yml | 7 ----- packetbeat/packetbeat.yml | 6 ---- packetbeat/sniffer/afpacket_linux.go | 41 ++++++++++++++-------------- 6 files changed, 20 insertions(+), 48 deletions(-) diff --git a/packetbeat/_meta/beat.reference.yml b/packetbeat/_meta/beat.reference.yml index 4ffeb49d09d..a77690bb8f9 100644 --- a/packetbeat/_meta/beat.reference.yml +++ b/packetbeat/_meta/beat.reference.yml @@ -478,10 +478,3 @@ packetbeat.procs.enabled: false # duplicates if shippers are installed on multiple servers. Default value is # false. packetbeat.ignore_outgoing: false - -#============================= Process Security ================================ - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false diff --git a/packetbeat/_meta/beat.yml b/packetbeat/_meta/beat.yml index 75cc439ebd8..29bfce3342e 100644 --- a/packetbeat/_meta/beat.yml +++ b/packetbeat/_meta/beat.yml @@ -108,9 +108,3 @@ setup.template.settings: #index.codec: best_compression #_source.enabled: false -#============================= Process Security ================================ - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false diff --git a/packetbeat/docs/faq.asciidoc b/packetbeat/docs/faq.asciidoc index 2ac2f0b9197..525d80d114c 100644 --- a/packetbeat/docs/faq.asciidoc +++ b/packetbeat/docs/faq.asciidoc @@ -22,7 +22,6 @@ ip link set promisc on ---------------------------------------------------------------------- For example: `ip link set enp5s0f1 promisc on` -Packetbeat sets promiscuous mode automatically when seccomp is disabled. [float] [[packetbeat-loopback-interface]] diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 8088b09fc1c..30a3e7ebb0d 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -479,13 +479,6 @@ packetbeat.procs.enabled: false # false. packetbeat.ignore_outgoing: false -#============================= Process Security ================================ - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false - #================================ General ====================================== # The name of the shipper that publishes the network data. It can be used to group diff --git a/packetbeat/packetbeat.yml b/packetbeat/packetbeat.yml index b19a87c62a8..bc1c1615a20 100644 --- a/packetbeat/packetbeat.yml +++ b/packetbeat/packetbeat.yml @@ -108,12 +108,6 @@ setup.template.settings: #index.codec: best_compression #_source.enabled: false -#============================= Process Security ================================ - -# Enable or disable seccomp system call filtering on Linux. Default is enabled. -# Seccomp is disabled in order to help with setting of promiscuous mode. -# If you enable seccomp you will need to enable promiscuous on the device manually. -seccomp.enabled: false #================================ General ===================================== diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 8ca19faa8e4..d7791d84660 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -20,11 +20,10 @@ package sniffer import ( - "bytes" "errors" - "fmt" - "os/exec" + "syscall" "time" + "unsafe" "github.com/elastic/beats/libbeat/logp" @@ -98,13 +97,25 @@ func isPromiscEnabled(device string) (bool, error) { return false, nil } - c := exec.Command("ip", "link", "show", device) - out, err := c.CombinedOutput() - if err != nil { - return false, fmt.Errorf(string(out)) + s, e := Socket(AF_INET, SOCK_DGRAM, 0) + if e != nil { + return false, e + } + + defer Close(s) + + var ifl struct { + name [IFNAMSIZ]byte + flags uint16 + } + + copy(ifl.name[:], []byte(name)) + _, _, ep := syscall.Syscall(SYS_IOCTL, uintptr(s), SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl))) + if ep != 0 { + return false, errors.New("Syscall SIOCGIFFLAGS exited with %v", ep) } - return bytes.Contains(out, []byte("PROMISC")), nil + return ifl.flags&uint16(IFF_PROMISC) != 0, nil } func setPromiscMode(device string, enabled bool) error { @@ -113,17 +124,5 @@ func setPromiscMode(device string, enabled bool) error { return nil } - mode := "off" - if enabled { - mode = "on" - } - - c := exec.Command("ip", "link", "set", device, "promisc", mode) - out, err := c.CombinedOutput() - if err != nil { - logp.Err("Error occurred when setting promisc mode of %s to %v: %v", device, enabled, err) - return errors.New(string(out)) - } - - return nil + return syscall.SetLsfPromisc(device, enabled) } From fbe73981dd1178b1dba25201c8fe78f32a3f8688 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 17:19:49 +0100 Subject: [PATCH 08/25] syscall --- packetbeat/sniffer/afpacket_linux.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index d7791d84660..144ccd9239b 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -20,7 +20,7 @@ package sniffer import ( - "errors" + "fmt" "syscall" "time" "unsafe" @@ -97,25 +97,25 @@ func isPromiscEnabled(device string) (bool, error) { return false, nil } - s, e := Socket(AF_INET, SOCK_DGRAM, 0) + s, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) if e != nil { return false, e } - defer Close(s) + defer syscall.Close(s) var ifl struct { - name [IFNAMSIZ]byte + name [syscall.IFNAMSIZ]byte flags uint16 } - copy(ifl.name[:], []byte(name)) - _, _, ep := syscall.Syscall(SYS_IOCTL, uintptr(s), SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl))) + copy(ifl.name[:], []byte(device)) + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl))) if ep != 0 { - return false, errors.New("Syscall SIOCGIFFLAGS exited with %v", ep) + return false, fmt.Errorf("Syscall SIOCGIFFLAGS exited with %v", ep) } - return ifl.flags&uint16(IFF_PROMISC) != 0, nil + return ifl.flags&uint16(syscall.IFF_PROMISC) != 0, nil } func setPromiscMode(device string, enabled bool) error { From 8c8768721efd47af474cc66b8c7961191b264fff Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 17:21:53 +0100 Subject: [PATCH 09/25] whitespaces --- packetbeat/_meta/beat.yml | 1 - packetbeat/packetbeat.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/packetbeat/_meta/beat.yml b/packetbeat/_meta/beat.yml index 29bfce3342e..8c8037a5e7c 100644 --- a/packetbeat/_meta/beat.yml +++ b/packetbeat/_meta/beat.yml @@ -107,4 +107,3 @@ setup.template.settings: index.number_of_shards: 1 #index.codec: best_compression #_source.enabled: false - diff --git a/packetbeat/packetbeat.yml b/packetbeat/packetbeat.yml index bc1c1615a20..02b9db547cf 100644 --- a/packetbeat/packetbeat.yml +++ b/packetbeat/packetbeat.yml @@ -108,7 +108,6 @@ setup.template.settings: #index.codec: best_compression #_source.enabled: false - #================================ General ===================================== # The name of the shipper that publishes the network data. It can be used to group From c00eb6f982008f478811471d93581b191c39d430 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 17:43:29 +0100 Subject: [PATCH 10/25] typo --- packetbeat/sniffer/afpacket_linux.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 144ccd9239b..01db54f2c05 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -34,7 +34,7 @@ import ( type afpacketHandle struct { TPacket *afpacket.TPacket - promicsPreviousState bool + promiscPreviousState bool device string } @@ -47,7 +47,7 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in } h := &afpacketHandle{ - promicsPreviousState: promiscEnabled, + promiscPreviousState: promiscEnabled, device: device, } @@ -87,7 +87,7 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() - if err := setPromiscMode(h.device, h.promicsPreviousState); err != nil { + if err := setPromiscMode(h.device, h.promiscPreviousState); err != nil { logp.Err("Failed to set promiscuous mode for device '%s': %v", h.device, err) } } From 24db04933f64b48b9e841aca8d7fe04ae8e8b1f9 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Thu, 21 Mar 2019 18:54:45 +0100 Subject: [PATCH 11/25] review round --- packetbeat/sniffer/afpacket_linux.go | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 01db54f2c05..15ca387d454 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -33,9 +33,10 @@ import ( ) type afpacketHandle struct { - TPacket *afpacket.TPacket - promiscPreviousState bool - device string + TPacket *afpacket.TPacket + promiscPreviousState bool + promiscPreviousStateDetected bool + device string } func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int, @@ -47,12 +48,13 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in } h := &afpacketHandle{ - promiscPreviousState: promiscEnabled, - device: device, + promiscPreviousState: promiscEnabled, + device: device, + promiscPreviousStateDetected: err == nil, } if err := setPromiscMode(device, true); err != nil { - logp.Err("Failed to set promiscuous mode for device '%s': %v", device, err) + logp.Warn("Failed to set promiscuous mode for device '%s'. Packetbeat may be unable to see any network traffic. Please follow packetbeat FAQ to learn about mitigation: Error: %v", device, err) } if device == "any" { @@ -87,8 +89,10 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() - if err := setPromiscMode(h.device, h.promiscPreviousState); err != nil { - logp.Err("Failed to set promiscuous mode for device '%s': %v", h.device, err) + if h.promiscPreviousStateDetected { + if err := setPromiscMode(h.device, h.promiscPreviousState); err != nil { + logp.Warn("Failed to reset promiscuous mode for device '%s'. Your device might be in promiscuous mode.: %v", h.device, err) + } } } @@ -104,18 +108,18 @@ func isPromiscEnabled(device string) (bool, error) { defer syscall.Close(s) - var ifl struct { + var ifreq struct { name [syscall.IFNAMSIZ]byte flags uint16 } - copy(ifl.name[:], []byte(device)) - _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl))) + copy(ifreq.name[:], []byte(device)) + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifreq))) if ep != 0 { - return false, fmt.Errorf("Syscall SIOCGIFFLAGS exited with %v", ep) + return false, fmt.Errorf("ioctl command SIOCGIFFLAGS failed to get device flags for %v: return code %d", device, ep) } - return ifl.flags&uint16(syscall.IFF_PROMISC) != 0, nil + return ifreq.flags&uint16(syscall.IFF_PROMISC) != 0, nil } func setPromiscMode(device string, enabled bool) error { From 1d2f6812f9f415fe3848cf281a5de08f9876af8a Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 08:17:28 +0100 Subject: [PATCH 12/25] not breaking --- CHANGELOG.next.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 55cfad14fb3..54eeebedee0 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -111,7 +111,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - `http.response.body` moves to `http.response.body.content` - Changed Packetbeat fields to align with ECS. {issue}7968[7968] - Removed trailing dot from domain names reported by the DNS protocol. {pull}9941[9941] -- Enable setting promiscuous mode automatically. {pull}11366[11366] *Winlogbeat* @@ -220,6 +219,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fixed a crash when using af_packet capture {pull}10477[10477] - Prevent duplicate packet loss error messages in HTTP events. {pull}10709[10709] - Avoid reporting unknown MongoDB opcodes more than once. {pull}10878[10878] +- Enable setting promiscuous mode automatically. {pull}11366[11366] *Winlogbeat* From 8e832621021eb54730b9d913927d48883b7c13e8 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 10:10:32 +0100 Subject: [PATCH 13/25] first attemp for system test --- .../tests/system/config/packetbeat.yml.j2 | 5 ++ .../tests/system/test_0069_af_packet.py | 68 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 packetbeat/tests/system/test_0069_af_packet.py diff --git a/packetbeat/tests/system/config/packetbeat.yml.j2 b/packetbeat/tests/system/config/packetbeat.yml.j2 index e1500ea73e4..394ef449840 100644 --- a/packetbeat/tests/system/config/packetbeat.yml.j2 +++ b/packetbeat/tests/system/config/packetbeat.yml.j2 @@ -4,6 +4,11 @@ # keyword to sniff on all connected interfaces. packetbeat.interfaces.device: {{ iface_device|default("any") }} +{% if af_packet %} +packetbeat.interfaces.type: af_packet +packetbeat.interfaces.buffer_size_mb: 100 +{% endif %} + {% if bpf_filter %} packetbeat.interfaces.bpf_filter: {{ bpf_filter }} {% endif %} diff --git a/packetbeat/tests/system/test_0069_af_packet.py b/packetbeat/tests/system/test_0069_af_packet.py new file mode 100644 index 00000000000..d4f34afdd55 --- /dev/null +++ b/packetbeat/tests/system/test_0069_af_packet.py @@ -0,0 +1,68 @@ +import os +import subprocess +from packetbeat import BaseTest + +""" +Tests for afpacket. +""" + + +class Test(BaseTest): + + @unittest.skipUnless(sys.platform.startswith("linux"), "af_packet only on Linux") + + def test_afpacket_promisc(self): + """ + Should verify whether device was switched to promisc mode and back. + """ + + # get device name, leave out loopback device + devices = [f for f in os.listdir("/sys/class/net") if f != "lo"][0] + if len(devices) == 0 + return + + device = devices[0] + + ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) + o,e = ip_proc.communicate() + assert e == None + + prev_promisc = "PROMISC" in o.decode("utf-8") + + # turn off promics if was on + if prev_promisc == True: + subprocess.run(["ip", "link", "set", device, "promisc", "off"], stdout=subprocess.PIPE) + + self.render_config_template( + af_packet=True, + iface_device=device + ) + packetbeat = self.start_packetbeat() + + # wait for promisc to be turned on, cap(90s) + for x in range(6) + time.sleep(15) + + ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) + o,e = ip_proc.communicate() + + is_promisc = "PROMISC" in o.decode("utf-8") + if is_promisc: + break + + assert is_promisc == True + + # stop packetbeat and check if promisc is set to previous state + packetbeat.kill_and_wait() + + ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) + o,e = ip_proc.communicate() + assert e == None + + is_promisc = "PROMISC" in o.decode("utf-8") + assert is_promisc == False + + #reset device + if prev_promisc == True: + subprocess.run(["ip", "link", "set", device, "promisc", "on"]) + From 22048ece46dbd97dd78e11fbc344eac51d6455f9 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 10:24:41 +0100 Subject: [PATCH 14/25] it's autopep8 style :notes: --- .../tests/system/test_0069_af_packet.py | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/packetbeat/tests/system/test_0069_af_packet.py b/packetbeat/tests/system/test_0069_af_packet.py index d4f34afdd55..eb2d5d32bb8 100644 --- a/packetbeat/tests/system/test_0069_af_packet.py +++ b/packetbeat/tests/system/test_0069_af_packet.py @@ -9,8 +9,9 @@ class Test(BaseTest): - @unittest.skipUnless(sys.platform.startswith("linux"), "af_packet only on Linux") - + @unittest.skipUnless( + sys.platform.startswith("linux"), + "af_packet only on Linux") def test_afpacket_promisc(self): """ Should verify whether device was switched to promisc mode and back. @@ -23,15 +24,17 @@ def test_afpacket_promisc(self): device = devices[0] - ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) - o,e = ip_proc.communicate() - assert e == None + ip_proc = subprocess.Popen( + ["ip", "link", "show", device], stdout=subprocess.PIPE) + o, e = ip_proc.communicate() + assert e is None prev_promisc = "PROMISC" in o.decode("utf-8") # turn off promics if was on - if prev_promisc == True: - subprocess.run(["ip", "link", "set", device, "promisc", "off"], stdout=subprocess.PIPE) + if prev_promisc: + subprocess.run(["ip", "link", "set", device, + "promisc", "off"], stdout=subprocess.PIPE) self.render_config_template( af_packet=True, @@ -43,26 +46,27 @@ def test_afpacket_promisc(self): for x in range(6) time.sleep(15) - ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) - o,e = ip_proc.communicate() + ip_proc = subprocess.Popen( + ["ip", "link", "show", device], stdout=subprocess.PIPE) + o, e = ip_proc.communicate() is_promisc = "PROMISC" in o.decode("utf-8") if is_promisc: break - assert is_promisc == True + assert is_promisc # stop packetbeat and check if promisc is set to previous state packetbeat.kill_and_wait() - ip_proc = subprocess.Popen(["ip", "link", "show", device], stdout=subprocess.PIPE) - o,e = ip_proc.communicate() - assert e == None + ip_proc = subprocess.Popen( + ["ip", "link", "show", device], stdout=subprocess.PIPE) + o, e = ip_proc.communicate() + assert e is None is_promisc = "PROMISC" in o.decode("utf-8") assert is_promisc == False - #reset device - if prev_promisc == True: + # reset device + if prev_promisc: subprocess.run(["ip", "link", "set", device, "promisc", "on"]) - From 49cd7a69c221a4b14b44737059959bc4fb9bbc62 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 10:46:01 +0100 Subject: [PATCH 15/25] more strict for devices count --- packetbeat/tests/system/test_0069_af_packet.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packetbeat/tests/system/test_0069_af_packet.py b/packetbeat/tests/system/test_0069_af_packet.py index eb2d5d32bb8..2050a9cd6e6 100644 --- a/packetbeat/tests/system/test_0069_af_packet.py +++ b/packetbeat/tests/system/test_0069_af_packet.py @@ -14,13 +14,12 @@ class Test(BaseTest): "af_packet only on Linux") def test_afpacket_promisc(self): """ - Should verify whether device was switched to promisc mode and back. + Should switch to promisc mode and back. """ # get device name, leave out loopback device devices = [f for f in os.listdir("/sys/class/net") if f != "lo"][0] - if len(devices) == 0 - return + assert len(devices) > 0 device = devices[0] @@ -43,7 +42,7 @@ def test_afpacket_promisc(self): packetbeat = self.start_packetbeat() # wait for promisc to be turned on, cap(90s) - for x in range(6) + for x in range(6): time.sleep(15) ip_proc = subprocess.Popen( From fa877f57e92d280580aa2c7b5e64bffa35db1da9 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 11:36:33 +0100 Subject: [PATCH 16/25] import unit test --- packetbeat/tests/system/test_0069_af_packet.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packetbeat/tests/system/test_0069_af_packet.py b/packetbeat/tests/system/test_0069_af_packet.py index 2050a9cd6e6..d1ac9c0d1b0 100644 --- a/packetbeat/tests/system/test_0069_af_packet.py +++ b/packetbeat/tests/system/test_0069_af_packet.py @@ -1,5 +1,8 @@ import os import subprocess +import sys +import time +import unittest from packetbeat import BaseTest """ @@ -18,7 +21,7 @@ def test_afpacket_promisc(self): """ # get device name, leave out loopback device - devices = [f for f in os.listdir("/sys/class/net") if f != "lo"][0] + devices = [f for f in os.listdir("/sys/class/net") if f != "lo"] assert len(devices) > 0 device = devices[0] From 2065731d3ca1b49cf23a5324d3366b6a51fc9caf Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Fri, 22 Mar 2019 14:24:10 +0100 Subject: [PATCH 17/25] fixed tests :party: --- .../tests/system/test_0069_af_packet.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packetbeat/tests/system/test_0069_af_packet.py b/packetbeat/tests/system/test_0069_af_packet.py index d1ac9c0d1b0..71e7863a54f 100644 --- a/packetbeat/tests/system/test_0069_af_packet.py +++ b/packetbeat/tests/system/test_0069_af_packet.py @@ -10,18 +10,28 @@ """ +def is_root(): + if 'geteuid' not in dir(os): + return False + euid = os.geteuid() + print("euid is", euid) + return euid == 0 + + class Test(BaseTest): @unittest.skipUnless( sys.platform.startswith("linux"), "af_packet only on Linux") + @unittest.skipUnless(is_root(), "Requires root") def test_afpacket_promisc(self): """ Should switch to promisc mode and back. """ # get device name, leave out loopback device - devices = [f for f in os.listdir("/sys/class/net") if f != "lo"] + devices = [f for f in os.listdir( + "/sys/class/net") if f.startswith("lo")] assert len(devices) > 0 device = devices[0] @@ -35,8 +45,8 @@ def test_afpacket_promisc(self): # turn off promics if was on if prev_promisc: - subprocess.run(["ip", "link", "set", device, - "promisc", "off"], stdout=subprocess.PIPE) + subprocess.call(["ip", "link", "set", device, + "promisc", "off"], stdout=subprocess.PIPE) self.render_config_template( af_packet=True, @@ -45,8 +55,8 @@ def test_afpacket_promisc(self): packetbeat = self.start_packetbeat() # wait for promisc to be turned on, cap(90s) - for x in range(6): - time.sleep(15) + for x in range(10): + time.sleep(5) ip_proc = subprocess.Popen( ["ip", "link", "show", device], stdout=subprocess.PIPE) @@ -71,4 +81,4 @@ def test_afpacket_promisc(self): # reset device if prev_promisc: - subprocess.run(["ip", "link", "set", device, "promisc", "on"]) + subprocess.call(["ip", "link", "set", device, "promisc", "on"]) From 24109ff68e07677206eaeb3cd38bfc9ab89fcefb Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Tue, 26 Mar 2019 08:25:21 +0100 Subject: [PATCH 18/25] use test environment --- packetbeat/Dockerfile | 15 ++++++++++++++ packetbeat/Makefile | 2 +- packetbeat/docker-compose.yml | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 packetbeat/Dockerfile create mode 100644 packetbeat/docker-compose.yml diff --git a/packetbeat/Dockerfile b/packetbeat/Dockerfile new file mode 100644 index 00000000000..2e91e309339 --- /dev/null +++ b/packetbeat/Dockerfile @@ -0,0 +1,15 @@ +FROM golang:1.11.5 + +RUN \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + python-pip \ + virtualenv \ + librpm-dev \ + netcat \ + libpcap-dev \ + && rm -rf /var/lib/apt/lists/* + +RUN pip install --upgrade pip +RUN pip install --upgrade setuptools +RUN pip install --upgrade docker-compose==1.23.2 diff --git a/packetbeat/Makefile b/packetbeat/Makefile index 1ef455d71cf..1ee3b731787 100644 --- a/packetbeat/Makefile +++ b/packetbeat/Makefile @@ -1,7 +1,7 @@ BEAT_NAME?=packetbeat BEAT_TITLE?=Packetbeat SYSTEM_TESTS?=true -TEST_ENVIRONMENT=false +TEST_ENVIRONMENT?=true ES_BEATS?=.. EXCLUDE_COMMON_UPDATE_TARGET=true diff --git a/packetbeat/docker-compose.yml b/packetbeat/docker-compose.yml new file mode 100644 index 00000000000..8abfad19410 --- /dev/null +++ b/packetbeat/docker-compose.yml @@ -0,0 +1,37 @@ +version: '2.3' +services: + beat: + build: ${PWD}/. + depends_on: + - proxy_dep + working_dir: /go/src/github.com/elastic/beats/packetbeat + environment: + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_USER=beats + - ES_PASS=testing + - KIBANA_HOST=kibana + - KIBANA_PORT=5601 + volumes: + - ${PWD}/..:/go/src/github.com/elastic/beats/ + command: make + privileged: true + pid: host + + # This is a proxy used to block beats until all services are healthy. + # See: https://github.com/docker/compose/issues/4369 + proxy_dep: + image: busybox + depends_on: + elasticsearch: { condition: service_healthy } + kibana: { condition: service_healthy } + + elasticsearch: + extends: + file: ../testing/environments/${TESTING_ENVIRONMENT}.yml + service: elasticsearch + + kibana: + extends: + file: ../testing/environments/${TESTING_ENVIRONMENT}.yml + service: kibana From 23d5948331db2b936bec304109977132a5835693 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Mon, 8 Apr 2019 10:37:07 +0200 Subject: [PATCH 19/25] configurable promisc mode --- packetbeat/config/config.go | 23 ++++++++------- packetbeat/docs/packetbeat-options.asciidoc | 18 ++++++++++++ packetbeat/packetbeat.reference.yml | 5 ++++ packetbeat/sniffer/afpacket_linux.go | 29 +++++++++++++------ packetbeat/sniffer/afpacket_nonlinux.go | 2 +- packetbeat/sniffer/sniffer.go | 2 +- .../tests/system/config/packetbeat.yml.j2 | 1 + 7 files changed, 58 insertions(+), 22 deletions(-) diff --git a/packetbeat/config/config.go b/packetbeat/config/config.go index 1c40aa8226e..46f0ba4ff43 100644 --- a/packetbeat/config/config.go +++ b/packetbeat/config/config.go @@ -36,17 +36,18 @@ type Config struct { } type InterfacesConfig struct { - Device string `config:"device"` - Type string `config:"type"` - File string `config:"file"` - WithVlans bool `config:"with_vlans"` - BpfFilter string `config:"bpf_filter"` - Snaplen int `config:"snaplen"` - BufferSizeMb int `config:"buffer_size_mb"` - TopSpeed bool - Dumpfile string - OneAtATime bool - Loop int + Device string `config:"device"` + Type string `config:"type"` + File string `config:"file"` + WithVlans bool `config:"with_vlans"` + BpfFilter string `config:"bpf_filter"` + Snaplen int `config:"snaplen"` + BufferSizeMb int `config:"buffer_size_mb"` + EnableAutoPromiscMode bool `config:"auto_promisc_mode"` + TopSpeed bool + Dumpfile string + OneAtATime bool + Loop int } type Flows struct { diff --git a/packetbeat/docs/packetbeat-options.asciidoc b/packetbeat/docs/packetbeat-options.asciidoc index 09922d62923..a53219ea28d 100644 --- a/packetbeat/docs/packetbeat-options.asciidoc +++ b/packetbeat/docs/packetbeat-options.asciidoc @@ -176,6 +176,24 @@ packetbeat.interfaces.type: af_packet packetbeat.interfaces.buffer_size_mb: 100 ------------------------------------------------------------------------------ +[float] +==== `auto_promisc_mode` + +With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. +This option does not work with `any` interface device. +The default option is false and requires manual set-up of promiscuous mode. + +Example: + +[source,yaml] +------------------------------------------------------------------------------ +packetbeat.interfaces.device: eth0 +packetbeat.interfaces.type: af_packet +packetbeat.interfaces.buffer_size_mb: 100 +packetbeat.interfaces.auto_promisc_mode: true +------------------------------------------------------------------------------ + + [float] ==== `with_vlans` diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 410d56139a1..43eeaa91552 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -40,6 +40,11 @@ packetbeat.interfaces.device: any # Use this setting to override the automatically generated BPF filter. #packetbeat.interfaces.bpf_filter: +# With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. +# This option does not work with `any` interface device. +# The default option is false and requires manual set-up of promiscuous mode. +#packetbeat.interfaces.auto_promisc_mode: true + #================================== Flows ===================================== packetbeat.flows: diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 15ca387d454..d377543c417 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -40,21 +40,28 @@ type afpacketHandle struct { } func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int, - timeout time.Duration) (*afpacketHandle, error) { + timeout time.Duration, autoPromiscMode bool) (*afpacketHandle, error) { - promiscEnabled, err := isPromiscEnabled(device) - if err != nil { - logp.Err("Failed to get promiscuous mode for device '%s': %v", device, err) + var err error + var promiscEnabled bool + + if autoPromiscMode { + promiscEnabled, err = isPromiscEnabled(device) + if err != nil { + logp.Err("Failed to get promiscuous mode for device '%s': %v", device, err) + } + + if !promiscEnabled { + if setPromiscErr := setPromiscMode(device, true); setPromiscErr != nil { + logp.Warn("Failed to set promiscuous mode for device '%s'. Packetbeat may be unable to see any network traffic. Please follow packetbeat FAQ to learn about mitigation: Error: %v", device, err) + } + } } h := &afpacketHandle{ promiscPreviousState: promiscEnabled, device: device, - promiscPreviousStateDetected: err == nil, - } - - if err := setPromiscMode(device, true); err != nil { - logp.Warn("Failed to set promiscuous mode for device '%s'. Packetbeat may be unable to see any network traffic. Please follow packetbeat FAQ to learn about mitigation: Error: %v", device, err) + promiscPreviousStateDetected: autoPromiscMode && err != nil, } if device == "any" { @@ -89,6 +96,7 @@ func (h *afpacketHandle) LinkType() layers.LinkType { func (h *afpacketHandle) Close() { h.TPacket.Close() + // previous state detected only if auto mode was on if h.promiscPreviousStateDetected { if err := setPromiscMode(h.device, h.promiscPreviousState); err != nil { logp.Warn("Failed to reset promiscuous mode for device '%s'. Your device might be in promiscuous mode.: %v", h.device, err) @@ -122,6 +130,9 @@ func isPromiscEnabled(device string) (bool, error) { return ifreq.flags&uint16(syscall.IFF_PROMISC) != 0, nil } +// setPromiscMode enables promisc mode if configured. +// this makes maintenance for user simpler without any additional manual steps +// issue [700](https://github.com/elastic/beats/issues/700) func setPromiscMode(device string, enabled bool) error { if device == "any" { logp.Warn("Cannot set promiscuous mode to device 'any'") diff --git a/packetbeat/sniffer/afpacket_nonlinux.go b/packetbeat/sniffer/afpacket_nonlinux.go index 2daa64520bf..7d1e423c40d 100644 --- a/packetbeat/sniffer/afpacket_nonlinux.go +++ b/packetbeat/sniffer/afpacket_nonlinux.go @@ -31,7 +31,7 @@ type afpacketHandle struct { } func newAfpacketHandle(device string, snaplen int, blockSize int, numBlocks int, - timeout time.Duration) (*afpacketHandle, error) { + timeout time.Duration, enableAutoPromiscMode bool) (*afpacketHandle, error) { return nil, fmt.Errorf("Afpacket MMAP sniffing is only available on Linux") } diff --git a/packetbeat/sniffer/sniffer.go b/packetbeat/sniffer/sniffer.go index 714d2c46d31..d38101c4b20 100644 --- a/packetbeat/sniffer/sniffer.go +++ b/packetbeat/sniffer/sniffer.go @@ -305,7 +305,7 @@ func openAFPacket(filter string, cfg *config.InterfacesConfig) (snifferHandle, e } timeout := 500 * time.Millisecond - h, err := newAfpacketHandle(cfg.Device, szFrame, szBlock, numBlocks, timeout) + h, err := newAfpacketHandle(cfg.Device, szFrame, szBlock, numBlocks, timeout, cfg.EnableAutoPromiscMode) if err != nil { return nil, err } diff --git a/packetbeat/tests/system/config/packetbeat.yml.j2 b/packetbeat/tests/system/config/packetbeat.yml.j2 index 394ef449840..2715634e4e5 100644 --- a/packetbeat/tests/system/config/packetbeat.yml.j2 +++ b/packetbeat/tests/system/config/packetbeat.yml.j2 @@ -7,6 +7,7 @@ packetbeat.interfaces.device: {{ iface_device|default("any") }} {% if af_packet %} packetbeat.interfaces.type: af_packet packetbeat.interfaces.buffer_size_mb: 100 +packetbeat.interfaces.auto_promisc_mode: true {% endif %} {% if bpf_filter %} From 91111210ff1a463aaade6b75410d679c15d17ddf Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Mon, 8 Apr 2019 13:59:12 +0200 Subject: [PATCH 20/25] meta reference --- packetbeat/_meta/beat.reference.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packetbeat/_meta/beat.reference.yml b/packetbeat/_meta/beat.reference.yml index a77690bb8f9..79c75f6bcb6 100644 --- a/packetbeat/_meta/beat.reference.yml +++ b/packetbeat/_meta/beat.reference.yml @@ -40,6 +40,11 @@ packetbeat.interfaces.device: {{ call .device .GOOS }} # Use this setting to override the automatically generated BPF filter. #packetbeat.interfaces.bpf_filter: +# With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. +# This option does not work with `any` interface device. +# The default option is false and requires manual set-up of promiscuous mode. +#packetbeat.interfaces.auto_promisc_mode: true + #================================== Flows ===================================== packetbeat.flows: From 52ce33e8685e0942bec002688c753ec532ad0d08 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Mon, 8 Apr 2019 16:02:48 +0200 Subject: [PATCH 21/25] invalid condition, shame on me --- packetbeat/sniffer/afpacket_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index d377543c417..656c10a9843 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -61,7 +61,7 @@ func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks in h := &afpacketHandle{ promiscPreviousState: promiscEnabled, device: device, - promiscPreviousStateDetected: autoPromiscMode && err != nil, + promiscPreviousStateDetected: autoPromiscMode && err == nil, } if device == "any" { From 7bb2402f7358756c792202b139d5b8569b90a2fd Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 5 Feb 2020 12:14:04 +0100 Subject: [PATCH 22/25] changelog merge fix --- CHANGELOG.next.asciidoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 4c878e98d7c..9494d59cbc3 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -84,8 +84,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Packetbeat* -- Prevent duplicate packet loss error messages in HTTP events. {pull}10709[10709] -- Avoid reporting unknown MongoDB opcodes more than once. {pull}10878[10878] - Enable setting promiscuous mode automatically. {pull}11366[11366] *Winlogbeat* From a00e370f2655228d8c37c28c6736e112e825203d Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 5 Feb 2020 12:15:28 +0100 Subject: [PATCH 23/25] updated dockerfile for packetbeat --- packetbeat/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packetbeat/Dockerfile b/packetbeat/Dockerfile index 2e91e309339..fd609f8e9b2 100644 --- a/packetbeat/Dockerfile +++ b/packetbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.11.5 +FROM golang:1.13.7 RUN \ apt-get update \ From 941f5343e1e40a0b9010baf42621f32d246e212c Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 5 Feb 2020 12:33:36 +0100 Subject: [PATCH 24/25] added comment --- packetbeat/sniffer/afpacket_linux.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packetbeat/sniffer/afpacket_linux.go b/packetbeat/sniffer/afpacket_linux.go index 656c10a9843..005254a4ff4 100644 --- a/packetbeat/sniffer/afpacket_linux.go +++ b/packetbeat/sniffer/afpacket_linux.go @@ -139,5 +139,8 @@ func setPromiscMode(device string, enabled bool) error { return nil } + // SetLsfPromisc is marked as deprecated but used to improve readability (bpf) + // and avoid Cgo (pcap) + // TODO: replace with x/net/bpf or pcap return syscall.SetLsfPromisc(device, enabled) } From bbcc013ea6b50d174c772c513a3767805c495d05 Mon Sep 17 00:00:00 2001 From: Michal Pristas Date: Wed, 5 Feb 2020 12:46:20 +0100 Subject: [PATCH 25/25] updated config file --- packetbeat/_meta/beat.reference.yml | 2 ++ packetbeat/docs/packetbeat-options.asciidoc | 2 ++ packetbeat/packetbeat.reference.yml | 2 ++ 3 files changed, 6 insertions(+) diff --git a/packetbeat/_meta/beat.reference.yml b/packetbeat/_meta/beat.reference.yml index d26f2feb022..6ddd057b4c9 100644 --- a/packetbeat/_meta/beat.reference.yml +++ b/packetbeat/_meta/beat.reference.yml @@ -43,6 +43,8 @@ packetbeat.interfaces.device: {{ call .device .GOOS }} # With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. # This option does not work with `any` interface device. # The default option is false and requires manual set-up of promiscuous mode. +# Warning: under some circumstances (e.g beat crash) promiscuous mode +# can stay enabled even after beat is shut down. #packetbeat.interfaces.auto_promisc_mode: true #================================== Flows ===================================== diff --git a/packetbeat/docs/packetbeat-options.asciidoc b/packetbeat/docs/packetbeat-options.asciidoc index 0dcb196e942..4855cbb773f 100644 --- a/packetbeat/docs/packetbeat-options.asciidoc +++ b/packetbeat/docs/packetbeat-options.asciidoc @@ -182,6 +182,8 @@ packetbeat.interfaces.buffer_size_mb: 100 With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. This option does not work with `any` interface device. The default option is false and requires manual set-up of promiscuous mode. +Warning: under some circumstances (e.g beat crash) promiscuous mode +can stay enabled even after beat is shut down. Example: diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index affda264a0b..b81447896c4 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -43,6 +43,8 @@ packetbeat.interfaces.device: any # With `auto_promisc_mode` Packetbeat puts interface in promiscuous mode automatically on startup. # This option does not work with `any` interface device. # The default option is false and requires manual set-up of promiscuous mode. +# Warning: under some circumstances (e.g beat crash) promiscuous mode +# can stay enabled even after beat is shut down. #packetbeat.interfaces.auto_promisc_mode: true #================================== Flows =====================================