Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

packetbeat: Enable setting promiscuous mode automatically #11366

Merged
merged 36 commits into from
Feb 5, 2020

Conversation

michalpristas
Copy link
Contributor

@michalpristas michalpristas commented Mar 21, 2019

This PR tries to enable promiscuous mode when using af_packet.

Few things to mention

  • when it fails it does not panic just logs the failure, mostly because of and backward compatibility
  • on exit: it resets promisc mode to whatever it was before
  • when any is used it does not set the mode to promiscuous - following pcap

Fixes #700

Manual testing guide:

Basic check:

  • check promisc mode is disabled on your device (e.g. ip link show {device}) (look for PROMISC keyword)
  • enable promisc mode by including packetbeat.interfaces.auto_promisc_mode: true into packetbeat config
  • check promisc mode is enabled (e.g. ip link show {device})
  • stop packetbeat
  • check promisc mode is disabled (e.g. ip link show {device})

Already on promisc check:

  • enable promisc mode on your devide (e.g. ifconfig {device} promisc or ip link set {device} promisc on
  • enable promisc mode by including packetbeat.interfaces.auto_promisc_mode: true into packetbeat config
  • check promisc mode is enabled (e.g. ip link show {device})
  • stop packetbeat
  • check promisc mode is still enabled (e.g. ip link show {device})

@michalpristas michalpristas requested a review from a team as a code owner March 21, 2019 11:32
@michalpristas michalpristas changed the title Fix 700 packetbeat: enable setting promiscous mode automatically Mar 21, 2019
@michalpristas michalpristas changed the title packetbeat: enable setting promiscous mode automatically packetbeat: Enable setting promiscous mode automatically Mar 21, 2019
@michalpristas michalpristas changed the title packetbeat: Enable setting promiscous mode automatically packetbeat: Enable setting promiscuous mode automatically Mar 21, 2019
@andrewkroh
Copy link
Member

Thanks for looking into this issue.

I definitely don't want to disable the seccomp protections to get this feature. Is there a way to directly set the promisc mode? How does this ip command do it? Maybe run that command in strace to see what it does. It might be using ioctl with IFF_PROMISC. Or maybe it's some kind of netlink msg being sent to the kernel.

@michalpristas
Copy link
Contributor Author

i believe it will definitely call ioctl. i will take a closer look at it and come with a possible workaround

@michalpristas
Copy link
Contributor Author

@andrewkroh changed it to call SIOCGIFFLAGS syscall directly. tested with Ubuntu and seems to work


"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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in promics.

var err error
promiscEnabled, err := isPromiscEnabled(device)
if err != nil {
logp.Err("Failed to get promiscuous mode for device '%s': %v", device, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it fails here then when closing we don't really know what the previous state was so we should not try to restore it based on this value.

}

if err := setPromiscMode(device, true); err != nil {
logp.Err("Failed to set promiscuous mode for device '%s': %v", device, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to inform users what the impact is and what a possible workaround is.

If Packetbeat is going to continue operating then I'd probably go for the Warn level.


defer syscall.Close(s)

var ifl struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's ifl stand for? I'm thinking using ifreq might make this more recognizable to some familiar with ioctl and network device programming. Or perhaps some comments here explaining that this is the ifreq structure from linux/if.h.

copy(ifl.name[:], []byte(device))
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl)))
if ep != 0 {
return false, fmt.Errorf("Syscall SIOCGIFFLAGS exited with %v", ep)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

fmt.Errorf("ioctl command SIOCGIFFLAGS failed to get device flags for %v: return code %d", device, ep)

return nil
}

return syscall.SetLsfPromisc(device, enabled)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function says its deprecated. Have you checked out what it recommends to use?

Copy link
Contributor Author

@michalpristas michalpristas Mar 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it says x/net where I did not find anything useful. so, for now, I went with this with a possible rewrite to direct syscalls

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's at least add a code comment here explaining the issue + follow up issue in repo.

Copy link
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code LGTM. Now my only concern is testing. Does Packetbeat have any tests that use af_packet (maybe something in the tests/system dir)?

I think ideally we'd have a test in place that externally checks the interface promisc flag with ip, then runs packetbeat using af_packet, verifies that it puts the interface into promisc mode, stops packetbeat, and checks the promisc flag a third time.

Copy link

@urso urso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it's nice to improve the out of the box experience, I think we should make this optional. We're changing a devices settings (a global resource) and there is no guarantee that we can do the change. For example if packetbeat crashes (e.g. OOM due to bad state after packet loss), then all state is lost and after restart we assume promisc mode was always set.

promiscPreviousStateDetected: err == nil,
}

if err := setPromiscMode(device, true); err != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change mode if it's already enabled?

return nil
}

return syscall.SetLsfPromisc(device, enabled)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's at least add a code comment here explaining the issue + follow up issue in repo.

@michalpristas
Copy link
Contributor Author

👍 on doing this optional

@andrewkroh
Copy link
Member

@michalpristas This feature is still on my wish list. 🙏 😄

@urso
Copy link

urso commented Dec 6, 2019

@michalpristas @andrewkroh We want to continue with this PR? What is missing?

@michalpristas
Copy link
Contributor Author

@urso brought even with master and updated to answer your comments. do you think something is missing?

@urso urso added test-plan Add this PR to be manual test plan v7.7.0 labels Feb 5, 2020
@michalpristas michalpristas merged commit 49b0eb9 into elastic:master Feb 5, 2020
michalpristas added a commit to michalpristas/beats that referenced this pull request Feb 5, 2020
)

packetbeat: Enable setting promiscuous mode automatically  (elastic#11366)
(cherry picked from commit 49b0eb9)
michalpristas added a commit that referenced this pull request Feb 5, 2020
…16104)

packetbeat: Enable setting promiscuous mode automatically  (#11366)
(cherry picked from commit 49b0eb9)
@andresrc andresrc added the Team:Integrations Label for the Integrations team label Mar 6, 2020
@andresrc andresrc removed the Team:Integrations Label for the Integrations team label Mar 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Packetbeat: af_packet doesn't put interface in promiscuous mode
4 participants