I was looking for a way to do a live view of the logs for the firewall. Since I installed the firewall for the first time last week, I probably looked in all the wrong places. I even briefly enabled FreeBSD repositories so I could install lnav, but I could not find anything I liked. And, since I hate coding (and am useless at it), I asked Gemini to write me a script to do live"post-processing" on /var/log/filter/latest.log and I quite like the look of it and figured someone else might find it useful.
Just paste the code into a file and chmod it:
#!/bin/sh
tail -f /var/log/filter/latest.log | awk -F, '
# The BEGIN block runs once before any log lines are processed.
BEGIN {
# --- Color Definitions ---
red="\033[1;31m"; green="\033[1;32m";
src_ip_color="\033[1;36m"; # Bright Cyan for Source IP
dest_ip_color="\033[1;33m"; # Bright Yellow for Destination IP
port_color="\033[1;35m"; # Bright Magenta for Ports
label_color="\033[0;37m"; # White for the label
reset="\033[0m";
# --- Header ---
printf "%-10s %-8s %-5s %-6s %-28s %-28s %s\n", "INTERFACE", "ACTION", "DIR", "PROTO", "SOURCE:PORT", "DESTINATION:PORT", "RULE ID";
print "================================================================================================================================";
}
# This main block runs for every single line of the log file.
{
# --- Field Index Variables ---
idx_rule_id = 4; # The tracker ID for the rule
idx_iface = 5; # The network interface (e.g., igb0)
idx_action = 7; # The firewall action (pass, block)
idx_direction = 8; # The direction of traffic (in, out)
idx_proto = 17; # The protocol name (tcp, udp, icmp)
idx_src_ip = 19; # The source IP address
idx_dst_ip = 20; # The destination IP address
idx_src_port = 21; # The source port (for tcp/udp)
idx_dst_port = 22; # The destination port (for tcp/udp)
# --- Data Processing ---
# Convert direction text to the requested arrow format.
dir_arrow = ($idx_direction == "in") ? "=>" : "<=";
# Choose the correct color for the action.
action_color = ($idx_action == "block") ? red : green;
# --- Output ---
# Print the simple, fixed-width columns first.
printf "%-10s %s%-8s%s %-5s %-6s", \
$idx_iface, \
action_color, $idx_action, reset, \
dir_arrow, \
$idx_proto;
# --- Handle complex Source:Port column ---
# This section builds the colored string, then calculates the
# correct padding needed to keep columns aligned.
# 1. Build the visible and colored strings for Source
visible_source_str = "";
colored_source_str = "";
if ($idx_proto == "tcp" || $idx_proto == "udp") {
visible_source_str = $idx_src_ip ":" $idx_src_port;
colored_source_str = sprintf("%s%s%s:%s%s%s", src_ip_color, $idx_src_ip, reset, port_color, $idx_src_port, reset);
} else {
visible_source_str = $idx_src_ip;
colored_source_str = sprintf("%s%s%s", src_ip_color, $idx_src_ip, reset);
}
# 2. Print the colored string and the calculated padding
printf " %s", colored_source_str;
pad = 28 - length(visible_source_str);
printf "%*s", (pad > 0 ? pad : 1), "";
# --- Handle complex Destination:Port column ---
printf " "; # Separator
# 1. Build the visible and colored strings for Destination
visible_dest_str = "";
colored_dest_str = "";
if ($idx_proto == "tcp" || $idx_proto == "udp") {
visible_dest_str = $idx_dst_ip ":" $idx_dst_port;
colored_dest_str = sprintf("%s%s%s:%s%s%s", dest_ip_color, $idx_dst_ip, reset, port_color, $idx_dst_port, reset);
} else {
visible_dest_str = $idx_dst_ip;
colored_dest_str = sprintf("%s%s%s", dest_ip_color, $idx_dst_ip, reset);
}
# 2. Print the colored string and the calculated padding
printf "%s", colored_dest_str;
pad = 28 - length(visible_dest_str);
printf "%*s", (pad > 0 ? pad : 1), "";
# --- Print the Rule ID and the final newline ---
printf " %s%s%s\n", label_color, $idx_rule_id, reset;
}
'
It might be work trying to figure out how to cross-reference the rid with some file somewhere where the descriptions are stored, but that was not my goal.