# Using systemd deployment method with PF\_RING

**URL:** <https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055>\
**Category:** Zeek\
**Tags:** pf-ring, systemd\
**Created:** [August 24, 2026, 12:56pm UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055 "2026-08-24T12:56:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![redbaron](https://avatars.discourse-cdn.com/v4/letter/r/3bc359/32.png) [@redbaron](https://community.zeek.org/u/redbaron)\
**Post date:** [August 24, 2026, 12:56pm UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/1 "2026-08-24T12:56:26Z")

</div>

Hi,

Zeek-8.1 has added a Systemd generator deployment method and the [docs](https://docs.zeek.org/en/master/advanced/deployment/systemd.html#single-host-walkthrough) show how to deploy Zeek cluster on a single node.

We have been using zeekctl to deploy Zeek using PF\_RING as load balancer till now. However, from the docs it is not clear to me how to translate PF\_RING specific `node.cfg` options (`lb_method` and `lb_procs`) to `zeek.conf`?

Additionally, In our deployment we use use `/opt/zeek` as prefix with logs going to a separate `/zeeklog`mount point. We disable PF\_RING’s ld\_so.conf entries so that all programs that link to libpcap (like tcpdump or snort) do not link to PF\_RING’s libpcap. For Zeek, we create a wrapper around `zeekctl` at `/usr/bin/zeekctl` explicitly linking it to PF\_RING

```auto
#!/bin/bash
PATH=/opt/zeek/bin:$PATH LD_LIBRARY_PATH=/opt/zeek/lib64/:/usr/local/lib:$LD_LIBRARY_PATH /usr/bin/python3.11 /opt/zeek/bin/zeekctl $*

```

And then call zeekctl normally. To replicate the above (only Zeek gets linked to PF\_RING’s libraries), how to proceed when using Zeek’s systemd generator?

Any insights will be helpful.

Thanks

---

<div class="post-metadata">

**Author:** ![awelzel](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/awelzel/32/609_2.png) [@awelzel](https://community.zeek.org/u/awelzel)\
**Post date:** [August 25, 2026, 1:37pm UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/2 "2026-08-25T13:37:23Z")

</div>

Hey @redbaron 👋

> We have been using zeekctl to deploy Zeek using PF\_RING as load balancer till now. However, from the docs it is not clear to me how to translate PF\_RING specific `node.cfg` options (`lb_method` and `lb_procs`) to `zeek.conf`?

Haven’t tested PF\_RING yet, but should mostly be setting a few environment variables. I’ll try it out in the coming days and post here and/or update instructions.

> Additionally, In our deployment we use use `/opt/zeek` as prefix with logs going to a separate `/zeeklog`mount point.

The log rotation setup for the zeek-systemd-generator is only using a basic [zeek-archiver](https://github.com/zeek/zeek-aux/tree/master/zeek-archiver) setup, rotating logs from `logger-X` spool directories into `<PREFIX>/var/log/zeek/<date>` directories. One thought would be to mount/bind-mount `/zeeklogs` to `/opt/zeek/var/log/zeek/` and see if that would work for you?

Thanks for you interest! Besides @dopheide, you’re part of the early adopter group 🙂

---

<div class="post-metadata">

**Author:** ![awelzel](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/awelzel/32/609_2.png) [@awelzel](https://community.zeek.org/u/awelzel)\
**Post date:** [August 26, 2026, 11:48am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/3 "2026-08-26T11:48:08Z")

</div>

@redbaron - mind checking out the [proposed changes to the docs?](https://github.com/zeek/zeek/pull/5837)

The following should work:

```auto
[zeek]
manager = 1
loggers = 1
proxies = 2

[interface enp8s0]
interface = enp8s0
workers = 4
# Preload PF_RING's libpcap.so library and setup the environment for
# flow-balancing on inner five tuples. Find more environment variables
# recognized by PF_RING's libpcap version here:
#
# https://www.ntop.org/guides/pf_ring/api/libpcap.html
#
worker_env =
  LD_PRELOAD=/usr/local/lib/libpcap.so
  PCAP_PF_RING_APPNAME=zeek-${interface_section_name}
  PCAP_PF_RING_CLUSTER_ID=42
  PCAP_PF_RING_USE_CLUSTER_PER_INNER_FLOW_5_TUPLE=1

```

Instead of `LD_PRELOAD`, can compile Zeek using `--with-pcap`. Find more details in the proposed docs changes.

Let us know if you have more questions or run into and blockers. Feedback is appreciated!

---

<div class="post-metadata">

**Author:** ![redbaron](https://avatars.discourse-cdn.com/v4/letter/r/3bc359/32.png) [@redbaron](https://community.zeek.org/u/redbaron)\
**Post date:** [August 27, 2026, 6:53am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/4 "2026-08-27T06:53:54Z")

</div>

Hi @awelzel

Thanks for looking at this and providing the info.

I am still trying to figure out systemd-generator (first without PF\_RING) so I am not sure if I can be called an ‘early adopter’ 🙂 .

Looking at the code of systemd-generator, I cannot find any mention of `worker_env`. Our custom zeek package dumps zeek libs at `/opt/zeek/lib64` so when I start `zeek-target` all zeek processes (except archiver) fail with `libbinpac.so not found` . In zeekctl, I overcome this using the custom wrapper I mentioned, but when I use the following `zeek.conf`, the error does not go away. I can’t see any Environment changes in generated units too

```auto
interface = enp1s0
workers = 1
loggers = 1
proxies = 1
base_dir = /opt/zeek
archiver = 1
user = root
group = zeek
worker_env =
  LD_LIBRARY_PATH=/opt/zeek/lib64/:$LD_LIBRARY_PATH

```

The generated worker unit

```auto
# cat /run/systemd/generator/zeek-worker@.service 
# Auto-generated, do not edit. Use drop-in files instead!
[Unit]
Description=Zeek Worker %i
SourcePath=/opt/zeek/etc/zeek/zeek.conf
After=zeek-setup.service
After=zeek-manager.service
After=zeek-logger@.service
After=zeek-proxy@.service
StopPropagatedFrom=zeek.target
StartLimitIntervalSec=0

[Service]
SyslogIdentifier=zeek-worker-%i
Type=exec
Nice=0
MemoryMax=
User=root
Group=zeek
WorkingDirectory=/opt/zeek/var/spool/zeek/worker-%i
ReadWritePaths=/opt/zeek/var/spool/zeek/worker-%i 
CapabilityBoundingSet=CAP_NET_RAW
AmbientCapabilities=CAP_NET_RAW
Environment=PATH=/opt/zeek/bin:/usr/local/bin:/usr/bin:/bin
Environment=ZEEKPATH=/opt/zeek/var/spool/zeek/generated-scripts:/opt/zeek/share/zeek:/opt/zeek/share/zeek/policy:/opt/zeek/share/zeek/site:/opt/zeek/share/zeek/builtin-plugins
Environment=CLUSTER_NODE=worker-%i
ExecStart=/opt/zeek/bin/zeek -i ${INTERFACE} policy/misc/systemd-generator local frameworks/cluster/backend/zeromq
Slice=zeek-workers.slice
Restart=always
RestartSec=1

```

If I can get Zeek to start without PF\_RING, I will look at the PF\_RING based environment changes you mentioned.

---

<div class="post-metadata">

**Author:** ![awelzel](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/awelzel/32/609_2.png) [@awelzel](https://community.zeek.org/u/awelzel)\
**Post date:** [August 27, 2026, 7:43am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/5 "2026-08-27T07:43:50Z")

</div>

> I am still trying to figure out systemd-generator (first without PF\_RING) so I am not sure if I can be called an ‘early adopter’ 🙂 .

Then thanks for testing 🙂

> Looking at the code of systemd-generator, I cannot find any mention of `worker_env`

Which version are you testing with? `worker_env`will only become available in 9.0, so recommend you build from git using the `release/9.0` branch or wait until the `rc2` tarball is out.

The `worker_env` settings will be rendered into individual drop-in files. For example, the first worker of `enp8s0` here has the following drop-in unit file generated (they are worker specific, because you can use [basic templating](https://docs.zeek.org/en/master/advanced/deployment/systemd.html#worker-interface-and-environment-templating) for the environment variables).

```auto
$ cat /run/systemd/generator/zeek-worker-enp8s0@1.service.d/10-zeek-systemd-generator.conf
[Unit]
SourcePath=/opt/zeek/etc/zeek/cluster/ubuntu-01.zeek.conf

[Service]
Environment=INTERFACE=enp8s0
Environment=LD_PRELOAD=/usr/local/lib/libpcap.so
Environment=PCAP_PF_RING_APPNAME=zeek-enp8s0
Environment=PCAP_PF_RING_CLUSTER_ID=42
Environment=PCAP_PF_RING_USE_CLUSTER_PER_INNER_FLOW_5_TUPLE=1

```

> fail with `libbinpac.so not found`

Hmm, hmm, hmm… Do you use `--binary-package` at `configure` time for your build? Any chance you could drop that? Alternatively, you could add `/etc/ld.so.conf/zeek.conf` that includes `/opt/zeek/lib64` and run `ldconfig`, but maybe you opted against doing that?

---

<div class="post-metadata">

**Author:** ![redbaron](https://avatars.discourse-cdn.com/v4/letter/r/3bc359/32.png) [@redbaron](https://community.zeek.org/u/redbaron)\
**Post date:** [August 27, 2026, 8:17am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/6 "2026-08-27T08:17:02Z")

</div>

> [@awelzel](#):
>
> Which version are you testing with? `worker_env`will only become available in 9.0

Ah that explains it. I am on 8.2.2, hence couldn’t find it. I’ll wait for 9.0 (stable) for further testing.

For `libbinpac.so` I usually rely on setting LD\_LIBRARY\_PATH but I can also add and `ld.so` for zeek. That too I’ll try when trying to build RPM for 9.0 but my guess is that LD\_LIBRARY\_PATH set via `env` should work too?

---

<div class="post-metadata">

**Author:** ![awelzel](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/awelzel/32/609_2.png) [@awelzel](https://community.zeek.org/u/awelzel)\
**Post date:** [August 27, 2026, 8:45am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/7 "2026-08-27T08:45:04Z")

</div>

> I’ll wait for 9.0 (stable) for further testing.

Thanks!

> LD\_LIBRARY\_PATH set via `env` should work too?

Yeah, it should. It’s just a bit unusual, maybe? And if you just want to run `/opt/zeek/bin/zeek` , you always need to set `LD_LIBRARY_PATH`?

There’s a mention in the docs about file-based capabilities: If you use `setcap` on the `zeek` executable, the`LD_LIBRARY_PATH`, `LD_PRELOAD` and some other dynamic linker environment variables as well as `MALLOC_CONF` will be ignored, that’s why I’d think using `ld.so.conf`or dropping `--binary-package` might be easiest.

---

<div class="post-metadata">

**Author:** ![redbaron](https://avatars.discourse-cdn.com/v4/letter/r/3bc359/32.png) [@redbaron](https://community.zeek.org/u/redbaron)\
**Post date:** [August 27, 2026, 9:11am UTC](https://community.zeek.org/t/using-systemd-deployment-method-with-pf-ring/8055/8 "2026-08-27T09:11:12Z")

</div>

Thanks @awelzel for those pointers. I think `ld.so.conf` path is the best.

Only problem is that I need `LD_LIBRARY_PATH` for `PF_RING` . I had once (Zeek-3.0 or so) tried using `--with-pcap` when building Zeek and providing PF\_RING’s libpcap but it had caused some problems (don’t remember as it was long back). I don’t need PF\_RING’s libpcap to get used for other tools (there’s a bunch of them on the sensor), just for Zeek so `LD_LIBRARY_PATH` or `LD_PRELOAD` was what I chose. Maybe I’ll give it a try with 9.0 when I try to overhaul my archaic build process.
