How to daemonize tcpdump

Here wizards, magicians, sorcerers and everybody can rest a bit and talk about anything they like.

Just remember to respect the rules.

How to daemonize tcpdump

Postby jiml8 » Feb 4th, '20, 07:06

Running tcpdump as a daemon turns out to be incredibly difficult.

I need to connect tcpdump to a virtual interface, have it capture data basically forever, then ship that data to a pipe where another program will use the data. To do this, a thread in a program I am writing needs to fork() then spawn tcpdump in the child process.

Usually, getting a program to work after a fork() is not too big a problem; the syntax for execv/execl will vary by program but it isn't hard to figure out. For tcpdump, it was pretty awful to figure it out.

I googled on it and ran across lots of people saying: "you can't daemonize tcpdump". Find another way.

Well, I did it. This code works. I am providing it here (and likely in other places) just so people can find it and benefit from it.
Code: Select all
void daemonize_tcpdumpr()
{
    pid_t pid;
    int rtn;

    pid = fork();
    if(pid == 0) {
        setsid();
        freopen("/tmp/tmpfile", "w", stdout);
        freopen( "/dev/null", "w", stderr);
        rtn = execl("/usr/bin/nice", "-0", "/usr/sbin/tcpdump", "-n", "-e", "-s", "0", "-i", "eth0",  NULL);
        printf( "Failed to start tcpdump.  Error is %d\n", rtn);
        _exit(rtn);
    }
}


I needed these particular tcpdump options; other users might want other options.

Note that this code outputs to /tmp/tmpfile, which is identified by redirecting stdout. If you close stdout before calling this function (if the caller is daemonized), then you need to save the handle using dup so you can restore it here in order to reopen it.

This code works on linux and on freebsd. I actually need it for freebsd, but debugged it on linux because the tools are better.
jiml8
 
Posts: 1079
Joined: Jul 7th, '13, 18:09

Re: How to daemonize tcpdump

Postby fopenp » Feb 5th, '20, 14:04

If you want to use log files, you can just create a tcpdump.log file into /var/log/ :
Code: Select all
  tcpdump -n > /var/log/tcpdump.log

In every serious distribution there is a log rotator ("logrotate") which limits the files size placed into /var/log/, and creates compressed files for older messages. You can create your own custom rules by adding a configuration file in /etc/logrotate.d/ directory (see some other file in there).
You can remotely get that log file in various way: scp, web server, internal mail...

If you actually need something in C or C++ and the persistence is not important, you could use a "ring buffer".
Something like this:
https://gist.github.com/fopenp/83e4bcda ... b178a0ba19

This code creates a TCP HTTP server which let you get the last 100 thousand lines (taken from stdin).
You can use it in this way:
Code: Select all
  # In a first terminal
  tcpdump -n | ./ringbuffer

  # In a second terminal
  wget -O /dev/stdout http://127.0.0.1:12345/

This is just an example, which does not consider security issues. You should use a login mechanism and some firewall rule for avoiding to spread tcpdump's output to every local and remote user!

Ooh, and... it's not tested in FreeBSD! :D
User avatar
fopenp
 
Posts: 8
Joined: Jan 20th, '20, 23:55
Location: EU/ Italy

Re: How to daemonize tcpdump

Postby jiml8 » Feb 5th, '20, 16:15

Yes, of course that syntax works in freebsd.

Now, try it when you don't have a console.
jiml8
 
Posts: 1079
Joined: Jul 7th, '13, 18:09

Re: How to daemonize tcpdump

Postby fopenp » Feb 5th, '20, 16:24

Nothing simpler!

Code: Select all
#!/usr/bin/env sh

( tcpdump -n > /var/log/tcpdump.log ) &


If you set the above script with 755 permissions and you execute it with root, the process will survive to the console closing.
Please note that the terminal could be polluted by tcpdump stderr text, but the process is detached! So please press ENTER button a couple of times.

You can verify it in this way:
Code: Select all
# Verify tcpdump process
pidof tcpdump

# Terminate tcpdump
killall tcpdump


Alternatively, you can open a "tmux" session, which is studied to survive in remote servers.
User avatar
fopenp
 
Posts: 8
Joined: Jan 20th, '20, 23:55
Location: EU/ Italy

Re: How to daemonize tcpdump

Postby jiml8 » Feb 5th, '20, 21:17

No, no, no. You are not listening.

Start it WITHOUT A CONSOLE. You started it WITH a console. Start it WITHOUT one. At all. Period. On a device that does not have a console, that does not have a user interface, that does not have a keyboard, a mouse, or any other way for the user to directly interact with the device.


In fact, the real application requires tcpdump to be started from a daemon, and to run completely detached from that daemon.

Hint: you cannot use ssh because that gives you a console, and is not available on the target system anyway. Ditto telnet, or any other way you might cheat on the "no console" requirement.

Oh...and...

If you want to debug it using a console, that is fine. But show how to start it in a fashion that completely detaches it from the console and from the user session that started it, so that it not only continues running when you close the console window, but it continues to run when that user logs out.

I'll give you another hint. The way you are describing simply does not accomplish that; tcpdump is NOT daemonized in your examples.

Oh, one final hint. It is OK for you to give tcpdump a console to run in; it actually needs to have one defined one way or another...that is part of the problem. But you cannot have a console available when you start it.
jiml8
 
Posts: 1079
Joined: Jul 7th, '13, 18:09

Re: How to daemonize tcpdump

Postby fopenp » Feb 5th, '20, 21:49

You are talking about "console", but in linux there is the "terminals" and "shells" concepts. The real "console" is a physical location where you have a screen, a keyboard and a mouse.

If you have putty, screen, sh or bash executable, you can make load that script into an init script. Bash will correctly create a subprocess, because linux have multitasking, multithreading and multiprocess functionalities.

Personally I never seen a real-world linux box without any kind of terminal. Even routers and switches have a telnet-based interface which have a terminal that can execute tasks through a shell-like software. After spawned the process, the process will be scheduled in an indipendent way.

If you have a minimal IoT you should always provide a terminal and shell IMHO. An alternative could be a kernel module, but it's an overkill.

What's your exact usage case and purpose?
User avatar
fopenp
 
Posts: 8
Joined: Jan 20th, '20, 23:55
Location: EU/ Italy

Re: How to daemonize tcpdump

Postby jiml8 » Feb 5th, '20, 22:13

fopenp wrote:Personally I never seen a real-world linux box without any kind of terminal. Even routers and switches have a telnet-based interface which have a terminal that can execute tasks through a shell-like software. After spawned the process, the process will be scheduled in an indipendent way.


There are more things 'twixt heav'n and earth, Horatio, than are dream't of in your philosophy.

With the rise of The Cloud, devices lacking user interfaces are becoming more common. Removing the user interface is a great security enhancement; it vastly reduces the attack surface of the device. Additionally, cloud management facilitates remote management while not compromising device (and hence target network) security. MSPs are beginning to love it.

And shells, terminals, blah blah blah. They're all forms of consoles. Don't split hairs. Virtual consoles are still consoles.

The particular device is a piece of networking infrastructure, an SD-WAN device, and it is cloud managed. It has routing, firewalling, peer to peer networking, and a lot of network monitoring capabilities built in, and is not directly user configurable. The user logs onto the dashboard, which is a cloud-based website, to manage the device. He sets his configuration there, and the configuration is downloaded by the server to the device, which then implements it.

Cloud management gives us one-click deployment of identical configs to multiple sites (if that is desirable), one-click networking of multiple sites, the ability to collect and aggregate network performance statistics for an entire multi-site business, and the capability to identify attackers in real time, and to push firewall rules blocking those attackers to all of the devices.

This greatly reduces the time that IT personnel (or, more likely) MSP personnel spend managing sites while enhancing security for the end-user businesses.
jiml8
 
Posts: 1079
Joined: Jul 7th, '13, 18:09

Re: How to daemonize tcpdump

Postby jiml8 » Feb 5th, '20, 22:20

OH, and...

We have a word for routers and switches with telnet interfaces.

That word is "hacked".
jiml8
 
Posts: 1079
Joined: Jul 7th, '13, 18:09

Re: How to daemonize tcpdump

Postby doktor5000 » Feb 5th, '20, 23:31

fopenp wrote:You are talking about "console", but in linux there is the "terminals" and "shells" concepts. The real "console" is a physical location where you have a screen, a keyboard and a mouse.


"terminals" and "shells" concepts are not enough. You basically cannot have a terminal with a shell inside without a console subsystem, it would not be usable at all. You may want to read up on that:
http://linusakesson.net/programming/tty/index.php
https://unix.stackexchange.com/question ... -and-a-con
Cauldron is not for the faint of heart!
Caution: Hot, bubbling magic inside. May explode or cook your kittens!
----
Disclaimer: Beware of allergic reactions in answer to unconstructive complaint-type posts
User avatar
doktor5000
 
Posts: 15354
Joined: Jun 4th, '11, 10:10
Location: Leipzig, Germany


Return to The Wizards Lair

Who is online

Users browsing this forum: No registered users and 1 guest

cron