Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login
    Introducing Netgate Nexus: Multi-Instance Management at Your Fingertips.

    States are still showing after over 12 hours of the computer being disconnected from the network.

    Scheduled Pinned Locked Moved General pfSense Questions
    9 Posts 5 Posters 420 Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M Offline
      mikek
      last edited by

      background:
      i have a network that cannot access other internal network or the internet, it is a physically separated network connected to it's own switch and a port on my 4200. rules state that lan can initiate connection to that network but that network cannot initiate connections to anything.

      i use this network for stuff like i did yesterday. my elderly neighbor got a virus on his computer and brought it to me for help.
      i connected the device and cleaned the virus and browser highjacks from the machine.
      i then added a rule allowing the machine access to the internet over a vpn link and ran any updated needed.
      i then deleted the rule related to the machine.
      i disconnected the machine and returned it to him over 12 hours ago.

      Then i notice this this morning:
      ada6f7a1-667d-4aa4-916c-afad759da80f-image.png

      How can i still have an open established state from an IP that has not been in use for over 12 hours? i am confused.

      tinfoilmattT 1 Reply Last reply Reply Quote 0
      • tinfoilmattT Offline
        tinfoilmatt LAYER 8 @mikek
        last edited by

        See this table: https://docs.netgate.com/pfsense/en/latest/config/advanced-firewall-nat.html#firewall-optimization-options

        M 1 Reply Last reply Reply Quote 0
        • M Offline
          mikek @tinfoilmatt
          last edited by

          @tinfoilmatt DOH, guess i should read the book more.

          I am set to normal, so established should last up to 24hrs.
          71cf6ec9-457d-44d4-bc51-b3cf2b9582bb-image.png

          thanks for replying.

          Mike

          1 Reply Last reply Reply Quote 0
          • stephenw10S Offline
            stephenw10 Netgate Administrator
            last edited by

            Mmm, usually you don't see that because TCP connections close out when they are finished. But if that doesn't happen, the firewall doesn't see the FIN packets. they will remain in the table as you see there.

            1 Reply Last reply Reply Quote 0
            • JonathanLeeJ Offline
              JonathanLee
              last edited by JonathanLee

              I had that issue also. I made a cron job to ping devices and clear their states if they don't reply — it was messing with my LED light customizations. It would happen when someone closed a laptop and left the house; states would stick around for many hours.
              Here's a trimmed version of what I run on a cron every few minutes:

              sh#!/bin/sh
              DEVICE_IP="10.0.1.42"
              DEVICE_MAC="aa:bb:cc:dd:ee:ff"
              
              # Check ARP table first, fall back to ping
              if arp -an | grep -qi "($DEVICE_IP).*$DEVICE_MAC"; then
                  exit 0  # device is online, leave states alone
              fi
              if ping -c 1 -W 1000 "$DEVICE_IP" >/dev/null 2>&1; then
                  exit 0  # responded to ping, still alive
              fi
              
              # Device is gone — kill states both directions
              pfctl -k "$DEVICE_IP" >/dev/null 2>&1
              pfctl -k 0.0.0.0/0 -k "$DEVICE_IP" >/dev/null 2>&1
              

              The key thing I found is that pfctl -k <IP> alone only kills states where the device is the source. If anything was sending to that device, those states survive. The two-argument form covers both directions.
              Also worth knowing: if the device had any IPv6 addresses, those states are completely separate. Pull the addresses from the NDP table and kill those too:

              shndp -an | grep -i "$DEVICE_MAC" | awk '{print $1}' | while read ip6; do
                  pfctl -k "$ip6" >/dev/null 2>&1
                  pfctl -k 0.0.0.0/0 -k "$ip6" >/dev/null 2>&1
              

              done
              In your case since you deleted the rule, Diagnostics > States in the GUI lets you filter by IP and reset them manually — but the above is the right approach if you want it automated.

              Make sure to upvote

              johnpozJ 1 Reply Last reply Reply Quote 1
              • johnpozJ Offline
                johnpoz LAYER 8 Global Moderator @JonathanLee
                last edited by

                @JonathanLee said in States are still showing after over 12 hours of the computer being disconnected from the network.:

                I made a cron job to ping devices and clear their states if they don't reply

                For what possible reason?? Utter pointlessness..

                An intelligent man is sometimes forced to be drunk to spend time with his fools
                If you get confused: Listen to the Music Play
                Please don't Chat/PM me for help, unless mod related
                SG-4860 26.03.1 | Lab VMs 2.8.1, 26.07

                JonathanLeeJ 2 Replies Last reply Reply Quote 0
                • JonathanLeeJ Offline
                  JonathanLee @johnpoz
                  last edited by

                  @johnpoz so my led traffic light turns off correctly … before it would act like stuff was still running.. originally would let me know when I could work on the firewall and take it down if it was in purple mode … no go epic!! You know you’re gonna do it check out this code … I’ll send the whole one

                  Make sure to upvote

                  tinfoilmattT 1 Reply Last reply Reply Quote 2
                  • JonathanLeeJ Offline
                    JonathanLee @johnpoz
                    last edited by

                    @johnpoz

                    This is why..

                    #!/bin/sh
                    # ==============================================================================
                    # LED Monitor for pfSense - RAM Lock + Pico Offline Alert + Active Device Check
                    # ==============================================================================
                    PI_IP="192.168.1.17"
                    LOCKFILE="/var/run/deviceonlineday.lock"
                    STATEFILE="/var/run/pico_offline.state"
                    GPIO_DEV="/dev/gpioc2"
                    
                    # Device definitions - IP and MAC for validation
                    XBOX_IP="10.0.0.4"
                    FIRE_IP="192.168.1.11"
                    FIRE_MAC="xx:xx:xx:xx:xx:xx"
                    TASHA_IP="192.168.1.15"
                    TASHA_MAC="xx:xx:xx:xx:xx:xx"
                    
                    if [ "$1" != "--locked" ]; then
                        exec lockf -t 0 "$LOCKFILE" "$0" --locked
                    fi
                    shift
                    
                    # --- Function: Check if device is actually online (IPv4 and IPv6) ---
                    is_device_online() {
                        local ip="$1"
                        local mac="$2"
                        
                        # Method 1: Check DHCP lease (IPv4)
                        if grep -q "$ip.*$mac" /var/dhcpd/var/db/dhcpd.leases 2>/dev/null; then
                            return 0
                        fi
                        
                        # Method 2: Check ARP table (IPv4)
                        if arp -an | grep -qi "($ip).*$mac"; then
                            return 0
                        fi
                        
                        # Method 3: Check NDP table (IPv6)
                        if ndp -an 2>/dev/null | grep -qi "$mac"; then
                            return 0
                        fi
                        
                        # Method 4: Quick ping test (last resort)
                        if ping -c 1 -W 1000 "$ip" >/dev/null 2>&1; then
                            return 0
                        fi
                        
                        return 1
                    }
                    
                    # --- Function: Kill all states for a device (IPv4 + all IPv6) ---
                    kill_device_states() {
                        local mac="$1"
                        local ip4="$2"
                        
                        # Kill IPv4 states
                        pfctl -k "$ip4" >/dev/null 2>&1
                        
                        # Kill all IPv6 states for this MAC
                        ndp -an 2>/dev/null | grep -i "$mac" | awk '{print $1}' | tr -d '()%' | while read ip6; do
                            if [ -n "$ip6" ] && [ "$ip6" != "Neighbor" ]; then
                                pfctl -k "$ip6" >/dev/null 2>&1
                            fi
                        done
                    }
                    
                    # --- Ping Pico ---
                    if ! ping -c 3 -W 1000 "$PI_IP" >/dev/null 2>&1; then
                        sleep 5
                        if ! ping -c 3 -W 1000 "$PI_IP" >/dev/null 2>&1; then
                            PICO_ONLINE=0
                        else
                            PICO_ONLINE=1
                        fi
                    else
                        PICO_ONLINE=1
                    fi
                    
                    # --- Pico offline EMERGENCY MODE ---
                    if [ "$PICO_ONLINE" -eq 0 ]; then
                        if [ ! -e "$STATEFILE" ]; then
                            date +%s > "$STATEFILE"
                            
                            php -r '
                              require_once("/etc/inc/util.inc");
                              require_once("/etc/inc/notices.inc");
                              $msg = "EMERGENCY: Raspberry Pi Pico alarm panel at '"$PI_IP"' is offline as of " . date("Y-m-d H:i:s");
                              log_error($msg);
                              notify_all_remote($msg);
                            '
                        fi
                        
                        # BLINKING RED ALERT
                        sysctl -q dev.gpio.2.led.0.pwm=0
                        gpioctl -f "$GPIO_DEV" 0 duty 200 >/dev/null 2>&1
                        sysctl -q dev.gpio.2.led.1.pwm=0
                        gpioctl -f "$GPIO_DEV" 3 duty 200 >/dev/null 2>&1
                        sysctl -q dev.gpio.2.led.2.pwm=0
                        gpioctl -f "$GPIO_DEV" 6 duty 200 >/dev/null 2>&1
                        
                    else
                        # Recovery notification
                        if [ -e "$STATEFILE" ]; then
                            OFFLINE_START=$(cat "$STATEFILE")
                            ONLINE_TIME=$(date +%s)
                            DURATION=$((ONLINE_TIME - OFFLINE_START))
                            HOURS=$((DURATION / 3600))
                            MINUTES=$(((DURATION % 3600) / 60))
                            SECONDS=$((DURATION % 60))
                            php -r '
                              require_once("/etc/inc/util.inc");
                              require_once("/etc/inc/notices.inc");
                              $msg = "RECOVERY: Raspberry Pi Pico alarm panel at '"$PI_IP"' is back online. Offline duration: '"$HOURS"' hours '"$MINUTES"' minutes '"$SECONDS"' seconds.";
                              log_error($msg);
                              notify_all_remote($msg);
                            '
                            
                            rm -f "$STATEFILE"
                        fi
                    fi
                    
                    # --- Check PF states ---
                    check_current_states=$( pfctl -vss | grep \
                        -e '10.0.0.4:3074' \
                        -e ', rule 116' \
                        -e '192.168.1.11' \
                        -e '192.168.1.15' )
                    
                    res=1  # Xbox
                    resb=1 # Fire tablet
                    resc=1 # Tasha laptop
                    resd=1 # Rule 116
                    
                    # Check Xbox
                    case "$check_current_states" in *"10.0.0.4:3074"*) res=0;; esac
                    
                    # Check Fire tablet - only if actually online AND in state table
                    if is_device_online "$FIRE_IP" "$FIRE_MAC"; then
                        case "$check_current_states" in *"192.168.1.11"*) resb=0;; esac
                    fi
                    
                    # Check Tasha laptop - only if actually online AND in state table
                    if is_device_online "$TASHA_IP" "$TASHA_MAC"; then
                        case "$check_current_states" in *"192.168.1.15"*) resc=0;; esac
                    fi
                    
                    # Check rule 116
                    case "$check_current_states" in *", rule 116"*) resd=0;; esac
                    
                    # --- Clean up stale connections for offline devices (IPv4 + IPv6) ---
                    if [ "$resc" -eq 1 ]; then
                        # Tasha's laptop is offline, kill all stale states (IPv4 and IPv6)
                        kill_device_states "$TASHA_MAC" "$TASHA_IP"
                    fi
                    
                    if [ "$resb" -eq 1 ]; then
                        # Fire tablet is offline, kill all stale states (IPv4 and IPv6)
                        kill_device_states "$FIRE_MAC" "$FIRE_IP"
                    fi
                    
                    # --- LED control (unchanged) ---
                    if [ "$res" -eq 0 ] && [ "$resb" -eq 0 ]; then
                        sysctl -q dev.gpio.2.led.1.pwm=1
                        gpioctl -f "$GPIO_DEV" 3 duty 50 >/dev/null
                        gpioctl -f "$GPIO_DEV" 4 duty 15 >/dev/null
                        sysctl -q dev.gpio.2.led.2.pwm=0
                        gpioctl -f "$GPIO_DEV" 6 duty 55 >/dev/null
                        gpioctl -f "$GPIO_DEV" 7 duty 20 >/dev/null
                        gpioctl -f "$GPIO_DEV" 8 duty 15 >/dev/null
                    elif [ "$res" -eq 0 ]; then
                        sysctl -q dev.gpio.2.led.1.pwm=1
                        gpioctl -f "$GPIO_DEV" 3 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 4 duty 0 >/dev/null
                        sysctl -q dev.gpio.2.led.2.pwm=0
                        gpioctl -f "$GPIO_DEV" 6 duty 55 >/dev/null
                        gpioctl -f "$GPIO_DEV" 7 duty 20 >/dev/null
                        gpioctl -f "$GPIO_DEV" 8 duty 15 >/dev/null
                    elif [ "$resb" -eq 0 ]; then
                        sysctl -q dev.gpio.2.led.2.pwm=1
                        gpioctl -f "$GPIO_DEV" 6 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 7 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 8 duty 0 >/dev/null
                        sysctl -q dev.gpio.2.led.1.pwm=1
                        gpioctl -f "$GPIO_DEV" 3 duty 50 >/dev/null
                        gpioctl -f "$GPIO_DEV" 4 duty 15 >/dev/null
                    else
                        sysctl -q dev.gpio.2.led.1.pwm=1
                        gpioctl -f "$GPIO_DEV" 3 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 4 duty 0 >/dev/null
                        sysctl -q dev.gpio.2.led.2.pwm=1
                        gpioctl -f "$GPIO_DEV" 6 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 7 duty 50 >/dev/null
                        gpioctl -f "$GPIO_DEV" 8 duty 0 >/dev/null
                    fi
                    
                    if [ "$resc" -eq 0 ] || [ "$resd" -eq 0 ]; then
                        sysctl -q dev.gpio.2.led.0.pwm=1
                        gpioctl -f "$GPIO_DEV" 2 duty 50 >/dev/null
                        gpioctl -f "$GPIO_DEV" 0 duty 50 >/dev/null
                    else
                        sysctl -q dev.gpio.2.led.0.pwm=1
                        gpioctl -f "$GPIO_DEV" 2 duty 0 >/dev/null
                        gpioctl -f "$GPIO_DEV" 0 duty 0 >/dev/null
                    fi
                    

                    Again, most people don't attempt to utilize customizations of the LEDs

                    Make sure to upvote

                    1 Reply Last reply Reply Quote 0
                    • tinfoilmattT Offline
                      tinfoilmatt LAYER 8 @JonathanLee
                      last edited by

                      no go epic!! You know you’re gonna do it check out this code

                      😂

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post
                      Copyright 2026 Rubicon Communications LLC (Netgate). All rights reserved.
                      Privacy Policy · Cookie Policy