OPNsense Forum

English Forums => 25.1, 25.4 Production Series => Topic started by: c2k on June 07, 2025, 12:52:43 PM

Title: Cli firewall live log viewer
Post by: c2k on June 07, 2025, 12:52:43 PM
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.