ufs_dirbad panic with mangled entries on FreeBSD

FreeBSD UFS makes usually a very good job in staying sane and repairing itself. However, it can happen that UFS is not capable of repairing and some “mangled entries” appear which result in kernel panics. Unfortunatlely these are not repairable by fsck. How do they look like?

/: bad dir ino 32578 AT OFFSET 33812: MANGLED ENTRY
panic: ufs_dirbad: bad dir

So what should we do if i encounter one of these lookalike messages? Well…

Reboot your machiine in single user mode, usually option 2 in the boot menu. After bootup start a filesystem check with repairing:

$ fsck -y /
** Last Mounted on /
** Root file system
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
112346 files, 42158044 used, 59151489 free (9993 frags, 7392687 blocks, 0.0% fragmentation)

Even if no error was found and the disk was marked clean, there can be problems with some inodes/files. You may bring your system back up without any further work, however if it panics again with the same message (check out the inode number -> ino), you are likely to have unfixable corruption.

Now how can you fix it? Use the filesystem debugger fsdb. Please note that in our example the concerned inode is 32578 (ino 32578 in our error message), this is likely to change in your error.

$ fsdb /dev/da0p2
** /dev/da0p2
Editing file system '/dev/da0p2'
Last mounted on /
...
fsdb (inum: 2)>

Now go to the inode mentioned in the panic and delete it: WARNING: you will lose data when you clear the inode! Keep it in mind.

fsdb (inum: 2)> inode 32578
...
fsdb (inum: 32578)> clri 32578
fsdb (inum: 32578)> quit

**** FILE SYSTEM STILL DIRTY *****
*** FILE SYSTEM MARKED DIRTY
*** BE SURE TO RUN FSDK TO CLEAN UP ANY DAMAGE
*** IF IT WAS MOUNTED, RE-MOUNT WITH -u -o reload

Now start fsck again like in the beginning of this article. Run it until no more errors are shown and it is MARKED AS CLEAN.

That’s it. Reboot normally and hope that not more inodes are faulty. If so, repeat this for every inode throwing the initial error/panic.

Configure NGINX as RMTP server on FreeBSD 12

Unfortunately the Nginx package for FreeBSD does not contain the RTMP module, so you need to compile it either from upstream sources or use the FreeBSD ports and enable the RTMP module before compiling:

# portsnap auto
# cd /usr/ports/www/nginx
# make config
# make
# make install

now create a new file name rtmp.conf in /usr/local/etc/nginx using your favorite editor, i use neovim:

# cd /usr/local/etc/nginx
# nvim rtmp.conf

now paste following code to rtmp.conf:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        application hlslive {
            live on;
            hls on;
            hls_path /usr/local/www/nginx-dist/hlslive;
            hls_fragment 3s;
            hls_playlist_length 18s;
        }
    }
}

save it and open nginx.conf and add the following:

load_module /usr/local/libexec/nginx/ngx_rtmp_module.so;  # <-- must be loaded at the top of the file
include rtmp.conf; # <-- can be at the end of the file

check if the config is valid:

# nginx -t

if valid you can start your Nginx/RTMP server and send the first RTMP to it.

Use SSL with MariaDB/MySQL

Basically you need to create 3 different certificates:

mariadb-ca.crt (Certificate Authority CA)
mariadb-server.crt (Server certificates)
mariadb-client.crt (Client certificate)

Server and client certificate need to be signed by the same CA. Now let’s start with the CA certificate and key:

# cd /var/db/mysql
# openssl genrsa -out mariadb-CA.key 1024
# openssl req -new -x509 -extensions v3_ca -key mariadb-CA.key -days 10950 -out mariadb-CA.crt

Now that the CA part have been generated it is time to generate the server certificate and key:

# openssl genrsa -out mariadb-server.key 1024
# openssl req -new -key mariadb-server.key -out mariadb-server.csr​
# openssl x509 -req -in mariadb-server.csr -CA mariadb-CA.crt -CAkey mariadb-CA.key -CAcreateserial -out mariadb-server.crt -days 10950

Well then, let0s go to the client part, shall we:

# openssl genrsa -out mariadb-client.key 1024
# openssl req -new -key mariadb-client.key -out mariadb-client.csr​
# openssl x509 -req -in mariadb-client.csr -CA mariadb-CA.crt -CAkey mariadb-CA.key -CAcreateserial -out mariadb-client.crt -days 10950

Now that we have our certificates ready, we need to edit our my.cnf. put following lines under the [mysqld] section:

ssl-ca=/var/db/mysql/mariadb-CA.crt
ssl-cert=/var/db/mysql/mariadb-server.crt
ssl-key=/var/db/mysql/mariadb-server.key

and for the client put this when doing the conneciton:

ssl-ca=/path/to/mariadb-CA.pem
ssl-cert=/path/to/mariadb-client.crt
ssl-key=/path/to/mariadb-client.key

Last security related step (but not mandatory) is to update permissions so that only mysql has read permissions:

# chown mysql:mysql mariadb-CA.* mariadb-server.* mariadb-client.*
# chmod 640 mariadb-CA.* mariadb-server.* mariadb-client.*

Important notes:

  • Note that you need to copy the mariadb-CA.crt to the client machine
  • The CN field must be different on server and client
  • I chose a certificate period of 30 years, adopt the paths and period to your needs
  • Make sure that the certs and keys are readable by the server
  • I chose a key length of 1024-bit because the longer the key gets, the drastically slower the connections will be. (https://dzone.com/articles/ssl-performance-overhead-mysql)