--- date: 2021-07-28T00:13:24+02:00 description: "Install pfstat to analyze stream on IPv4, IPv6 through the firewall PF (Packet Filter), on OpenBSD!" draft: false tags: ['Monitoring','dataviz','pfstat','OpenBSD','httpd'] title: "pfstat on OpenBSD: analyze stream on IPv4 and IPv6 through PF" translationKey: "monitor-pfstat-openbsd" --- ## Description **pfstat** is a project made by Daniel Hartmeir to generate graphic statistiques about the network stream through the firewall PF. - Official website: https://www.benzedrine.ch/pfstat.html --- ⇒ Environnement: * OpenBSD : 6.9 ⇒ 7.1 ## Installation Usual: `# pkg_add pfstat pfstatd` **pfstatd** is not essential for a simpliest configuration. It becomes interesting to run with dedicated user. ## Configuration ### PF Assuming that the network interface is **em0**, we need to modify `/etc/pf.conf` to add: ```cfg set loginterface em0 ``` {{< note info >}} If you have several network interfaces, it is possible to analyze all; add them line by line. {{}} ### pfstat Configure **pfstat** is not complicated. By installing the package, the file config is created, as instance on `/etc/pfstat.conf`. You need to change the web directory where the future images will be create. ```sh # sed -i -e 's/sis0/em0/g;s/benzedrine.cx/pfstat/g' /etc/pfstat.conf ``` This change all lines where: - **sis0** interface by **em0** - the folder *benzedrine.cx* by our future directory *pfstat*. --- Next, you need to configure the crontab of root to run **pftstat**. ```cfg * * * * * -ns /usr/local/bin/pfstat -q -d /var/db/pfstat/pfstat.db */15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db 30 0 * * * -ns /usr/local/bin/pfstat -t 30 -d /var/db/pfstat/pfstat.db ``` - first line executed every minute to analyze the network stream and save on database - second line generate the images every 15 minutes - third will delete every data, at 0:30, datas older than thirty days. ⇒ Create the future folder of the database: ```sh # mkdir -p /var/db/pfstat/ ``` {{< note info >}} FYI, you can create a folder when you wish. It's up to you! {{}} --- Voila: a minimum functional configuration. Now, we will create a user system, without right, no password to manage both daemon and package. ### _pfstat Create the user **_pfstat** is usefull to start daemon **pfstatd** and after to use the binary **pfstat**: ```sh # useradd -s /sbin/nologin -d /var/db/pfstat _pfstat # chown _pfstat /var/db/pfstat ``` #### pfstatd Just enable, set, and active the daemon: ```sh # rcctl enable pfstatd # rcctl set pfstatd flags -u _pfstat -a 127.0.0.1 # rcctl start pfstatd ``` We have not set port number; by default is 9999. Tools, like nc, help to assume service is run correctly, like:
`nc localhost 9999` — normally, stats are displayed, line by line; *if not the case, you have one problem…* ##### pfstatd and PF I strongly encourage you to block into OpenBSD firewall, all connections on the pfstatd service! A rule like the following should be sufficient: ```cfg block drop in on ! lo0 proto tcp to port 9999 ``` #### pfstat and _pfstat Now, we need to reconfigure how using **pfstat** with the user **_pfstat**. 1. First time, we need to comment or delete all writings into the crontab of the root. 2. and set that of the user **_pfstat** : - create a filenamed **crontab4pfstat**, with those rules: ```conf * * * * * -ns /usr/local/bin/pfstat -q -d /var/db/pfstat/pfstat.db -r 127.0.0.1 */15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db 30 0 * * * -ns /usr/local/bin/pfstat -t 30 -d /var/db/pfstat/pfstat.db ``` Little explaination: - option `-r` followed by the loopback address: to remote the statistics and save them on the database. Now, add the file content **crontab4pfstat** into the **_pfstat** user crontab: ```sh # crontab -u _pfstat crontab4pfstat ``` #### Monitoring _pfstat It exists differents ways to monitoring the **_pfstat** user activity: - `top -U _pfstat` : ```sh load averages: 0.05, 0.38, 0.38 56 processes: 54 idle, 2 on processor CPU0 states: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle Memory: Real: 84M/5985M act/tot Free: 9778M Cache: 2757M Swap: 0K/32G PID USERNAME PRI NICE SIZE RES STATE WAIT TIME CPU COMMAND 16833 _pfstat 2 0 700K 984K sleep/6 netcon 0:00 0.00% pfstatd ``` --- ```sh $ fstat -u _pfstat -n USER CMD PID FD DEV INUM MODE R/W SZ|DV _pfstat pfstatd 16833 wd 4,0 2 40755 r 512 _pfstat pfstatd 16833 0 4,0 27162 20666 rw 2,2 _pfstat pfstatd 16833 1 4,0 27162 20666 rw 2,2 _pfstat pfstatd 16833 2 4,0 27162 20666 rw 2,2 _pfstat pfstatd 16833 3 4,0 27028 20600 r 73,0 _pfstat pfstatd 16833 4* internet stream tcp 0x0 127.0.0.1:9999 $ ps aux -U _pfstat USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND _pfstat 16833 0.0 0.0 700 984 ?? I 1:19AM 0:00.02 /usr/local/bin/pfstatd -u _pfstat -a 127.0.0.1 ``` Those commands confirm that: - **pfstatd** is started and managed by the user **_pfstat**. - the daemon listen on local interface, on number port 9999, is waiting a connection — *on these examples*. --- Now, configure httpd: ### httpd Start to create the needed folder: ```sh # mkdir -p /var/www/htdocs/pfstat/ ``` Next, add the following directives to the file configuration `/etc/httpd.conf`, as: ```cfg types { include "/usr/share/misc/mime.types" } server "pfstat" { listen on 127.0.0.1 port 80 location "/pfstat/" { directory auto index root "/htdocs/" } } ``` Check the configuration, and enable and start the service: ```sh # rcctl enable httpd # httpd -n && rcctl start httpd ``` Now, we can consult locally, at: http://localhost/pfstat --- Voila! *(another time… but it's not the final time of)* #### httpd and _pfstat Add the **_pfstat** user to the web group and change the user rights on the web directory: ```sh # usermod -G www _pfstat # chown -R _pfstat:www /var/www/htdocs/pfstat ``` --- ## PFstats **PFstats** is my little projet: create a responsive webpage to consult easier the created images by pfstat. It is designed to analyze hourly, daily, weekly, monthly and even yearly statistics. - Git depot: https://tildegit.org/hucste/pfstats - See [README.md](https://tildegit.org/hucste/pfstats/src/branch/main/README.md) - [Modified BSD License](https://tildegit.org/hucste/pfstats/src/branch/main/LICENSE) Here one screenshot: {{< img a="Screenshot of 'pfstat.hml' webpage" s="openbsd/pfstats.html.png" w="250" >}} --- Explainations: ### pfstat.conf ⇒ **pfstat.conf** is configured: - to analyze IPv4 and IPv6, with the interface **em0** - to view the hourly, daily, weekly, monthly graphics - to publish on web directory: `/var/www/htdocs/pfstat`. You need to copy into `/etc`. --- {{< note info >}} I comment all queues directives; by default, it's not supported. {{}} ### pfstat.html Copy all .css, .js and .html files on the web directory. ### convert-img.sh ⇒ The shell script transform/convert images JPEG to the Avif and Webp format. You need to install **libavif**, and **libwebp** packages. Finally: - add **_pfstat** user to your user group, and - chmod needed rights to the script ```sh # usermod -G userid _pfstat # chmod 0750 /home/userid/folder/pfstats/convert-img.sh ``` {{< note info >}} Generate AVIF images can be slow; this is not the case for Webp. Too, depend on your machine. {{}} ### pfstats and crontab You need to modify the second line on the **_pfstat** crontab: ```cfg 15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db; /dir/convert-img.sh ``` ### pfstats and httpd To manage correctly both images format (avif and webp), it may be necessary to slightly modify the configuration of httpd, to add: ```cfg image/avif avif ``` Like: ```cfg types { include "/usr/share/misc/mime.types" image/avif avif } ``` ⇒ To check the support of the webp format: ```sh $ grep webp /usr/share/misc/mime.types image/webp webp ``` If the command not display result, we nee to add `image/webp webp` into the directive **types**. *Since OpenBSD 6.9, it's normally not needed!* --- ## Troubleshots ### ALTQ-style queues not supported anymore The complete message is: `/etc/pfstat.conf:61: ALTQ-style queues not supported anymore` It seems, by default, that the queues analyze is not possible. Delete or comment all relevent lines. ### dbopen: /var/db/pfstat/pfstat.db: No such file or directory Check if the folder is created! --- Voila! *(the final count… is down!
the final countdown!)* --- ## Documentations ⇒ Those formats are supported by: - https://caniuse.com/avif - https://caniuse.com/webp