Skip to content

Instantly share code, notes, and snippets.

@luckman212
Last active October 23, 2023 02:38
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luckman212/124a81d5f295dfa5c6d1162aaef55842 to your computer and use it in GitHub Desktop.
Save luckman212/124a81d5f295dfa5c6d1162aaef55842 to your computer and use it in GitHub Desktop.
script for pfSense to detect IPv6 router advertisements coming from a WAN interface
#!/bin/sh
# set the variable below to your FIOS interface
IF=igb0
/usr/bin/timeout 5m /usr/sbin/tcpdump -ni ${IF} 'icmp6 && ip6[40] == 134' >/tmp/${IF}_RAs.out
FSIZE=$(/usr/bin/stat -f '%z' /tmp/${IF}_RAs.out)
if [ "$FSIZE" -gt 1 ]; then
echo '<?php include("notices.inc"); $msg = "IPv6 RAs detected on interface '$IF'"; notify_via_smtp($msg);?>' | /usr/local/bin/php -q
fi
@luckman212
Copy link
Author

luckman212 commented Nov 6, 2018

Instructions

(update: scroll down a bit for an alternate version of the script that should be more efficient)
(update 2: I rewrote the script in PHP, this is probably the best version to use)

  1. save the script above to /root/v6test.sh (use scp, paste into vi etc)

  2. set the IF= varibale on line 4 to the name of the FreeBSD interface connected to your FIOS ONT.

  3. make the script executable
    chmod +x v6test.sh

  4. Install the Cron package if you don't already have it

  5. Set the script to run on whatever schedule you like, e.g. every day at 5:01am
    image

The script will capture packets for 5 minutes and send an email notification to your inbox if RAs are detected. If you feel the need, you can change the timeout 5m on line 6 to something else if needed (15m, 60s etc). The script uses pfSense's native notify_via_smtp() mail function, so naturally you must be sure that the SMTP settings are filled out correctly if you want to receive them.

Related discussions

@luckman212
Copy link
Author

It's been pointed out that it might be better to actively send RS (router solicitations) rather than passively probing for RAs. The script above could be modified to use something like rtsol -DF igb0 and listen for any responses. I'll do some testing and see if I can come up with a more efficient version.

@luckman212
Copy link
Author

luckman212 commented Nov 6, 2018

Here's a different version of the script that actively sends out Router Solicitations using rtsol instead of passively with tcpdump.
I haven't done as much testing with this one, so please give it a try and send any comments.

#!/bin/sh
IF=igb0
RESULT=$(/sbin/rtsol -DF $IF 2>&1 | /usr/bin/grep -E "received RA from [a-f0-9:\.]+ on $IF")
if [ -n "$RESULT" ]; then
  echo '<?php include("notices.inc"); $msg = "IPv6 RAs detected on interface '$IF'"; notify_via_smtp($msg);?>' | /usr/local/bin/php -q
fi

@luckman212
Copy link
Author

Here's yet another version of this that's mostly PHP instead of shell script. This one also accepts an argument to define the interface to be checked. So, instead of modifying the script itself, you can just call it from Cron with e.g. ix0 an arg. This could also allow the same script to be used to check multiple interfaces. Example:

image

(save this script as /root/v6test.php)

<?php

  include("notices.inc");

  if (!empty($argv[1])) {
    $if = $argv[1];
  } else {
    $if = "igb0";
  }

  exec("/sbin/rtsol -DF $if 2>&1", $result, $retval);
  if (($retval == 0) && (count($result))) {
    $haystack = implode("\n", $result);
    $needle = "received RA from [a-f0-9:\.]+ on $if";
    preg_match("/$needle/", $haystack, $matches);
    if (count($matches)) {
      $msg = "IPv6 RAs detected on interface $if";
      notify_via_smtp($msg);
    }
  }

?>

@AllenEllis
Copy link

AllenEllis commented Nov 26, 2019

Thanks! For anyone like me didn't already have them setup, this assumes you've setup SMTP notifications in pfsense (System > Advanced > Notifications). I used my Gmail credentials as outlined in this blog post.

@sectary-want-holly
Copy link

Great script! However, is there a way to tie the notification into Telegram?

@luckman212
Copy link
Author

@sectary-want-holly sure, just edit the notify_via_smtp() line, change it to notify_via_telegram($msg);

@sectary-want-holly
Copy link

@luckman212 well, I feel silly! Muchos gracious!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment