pfSense stat monitor


#1

It took a bit of work to put this together, so I thought I’d share it with the community. pfSense does not have a native API for pulling/pushing information, but with a little work you can get it to send stats to HA and you can also send commands to your pfSense router if you so desire. Be careful, this API is quite powerful. Make sure you don’t mess something up.

How to set up:

  1. Install Faux API for pfSense (PFFA) from here: https://github.com/ndejong/pfsense_fauxapi#installation

    fetch https://raw.githubusercontent.com/ndejong/pfsense_fauxapi/master/package/pfSense-pkg-FauxAPI-1.3_1.txz
    pkg-static install pfSense-pkg-FauxAPI-1.3_1.txz

The UI will load Faux API here:
fauxapi

  1. Update /etc/fauxapi/credentials.ini file after install to add a new user. By default, Faux API has no user… there are two examples, but they are hardcoded not to work for security reasons. @ndejong offers some bash scripts to create your keys, but I had trouble with them for some reason. You don’t have to use them, you just have to make sure to follow the rules:

    The API key + API secret values that you will need to create in /etc/fauxapi/credentials.ini have the following rules:-
    
    <apikey_value> and <apisecret_value> may have alphanumeric chars ONLY!
    <apikey_value> MUST start with the prefix PFFA (pfSense Faux API)
    <apikey_value> MUST be >= 12 chars AND <= 40 chars in total length
    <apisecret_value> MUST be >= 40 chars AND <= 128 chars in length 
    you must not use the sample key/secret in the credentials.ini since they are hard coded to fail.
    

    [PFFAexample01] #<apikey_value>
    secret = abcdefghijklmnopqrstuvwxyz0123456789abcd #<apisecret_value>
    permit = alias_, config_, gateway_, rule_, send_, system_, function_* #authorization
    comment = anything you want can go here. it will be visible in the Faux API in pfSense

You can edit the file using vi in the ssh shell or from the pfSense UI: Diagnostics > Edit File > ‘enter the path /etc/fauxapi/credentials.ini

  1. Set up authorization. This is a really nice feature with Faux API, you can control what the user can actually do and only give permission to that. I was only interested in getting stat information so this is what I used so that my user didn’t have access to do anything but get stats from the router:

    [PFFAexample01]
    secret = abcdefghijklmnopqrstuvwxyz0123456789abcd
    permit = system_stats
    comment = example key PFFAexample01 - hardcoded to be inoperative

  2. GET the JSON formatted information. The Faux API uses a timestamp and a nonce for authorization. Not a simple username and password like most APIs. So you can’t use the JSON Sensor. You’ll have to utilize the provided python library from @ndejong. https://github.com/ndejong/pfsense_fauxapi/blob/master/extras/client-libs/python/fauxapi_lib.py
    Download that file and place it in your /config directory. Then you need a python script to use the library. I used a modified version of this: https://github.com/ndejong/pfsense_fauxapi/blob/master/extras/tests/python-lib-iterate.py

import os, sys, json

sys.path.append(os.path.abspath(os.path.join(os.path.curdir, '../client-libs/python')))     # hack to make this work in-place
from fauxapi_lib import FauxapiLib


# check args exist
if(len(sys.argv) < 4):
    print()
    print('usage: ' + sys.argv[0] + ' <host> <apikey> <apisecret>')
    print()
    print('pipe JSON output through jq for easy pretty print output:-')
    print(' $ ' + sys.argv[0] + ' <host> <apikey> <apisecret> | jq .')
    print()
    sys.exit(1)

# config
fauxapi_host=sys.argv[1]
fauxapi_apikey=sys.argv[2]
fauxapi_apisecret=sys.argv[3]

FauxapiLib = FauxapiLib(fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug=False)


# system_stats
# =============================================================================
print(json.dumps(
    FauxapiLib.system_stats())
)
open('/config/python_scripts/pfSense_stats.json', 'w').close()  # clear data
with open('/config/pfSense_stats.json', 'a') as stat_file:
    print(json.dumps(
    FauxapiLib.system_stats()), file=stat_file)

As you can see. I got rid of all the calls I wasn’t interested in and just kept the system_stats call. I also am dumping the JSON data into a file in my config directory (another directory could also be used if desired.

  1. Set up sensors in config.yaml.
sensor:
   #this will call the python script and store the cpu temp information in a sensor. the script will export 
   #the rest of the data into a file. we cant dump all of the data into 1 sensor since there is a 255 character 
   #limit for the sensor.
 - platform: command_line
    command: "python3 /config/pffa_get_system_stats.py <_host_> <apikey_value> <apisecret_value>"
    name: pfSense_CPU_temp
    value_template: '{{ value_json["data"]["stats"]["temp"] }}'
    unit_of_measurement : 'C'
    
  - platform: file
    file_path: /config/pfSense_stats.json
    name: pfSense_uptime
    value_template: '{{ value_json["data"]["stats"]["uptime"] }}'
  
  - platform: file
    file_path: /config/pfSense_stats.json
    name: pfSense_mem
    value_template: '{{ value_json["data"]["stats"]["mem"] }}'
    unit_of_measurement : '%'
    
  - platform: file
    file_path: /config/pfSense_stats.json
    name: pfSense_cpu
    value_template: '{{ ( ( ((value_json["data"]["stats"]["cpu"].split("|")[0] | float) / (value_json["data"]["stats"]["cpu"].split("|")[1] | float)) - 1.0 ) * 100.0 ) | round(1) }}'
    unit_of_measurement : '%'

  - platform: file
    file_path: /config/pfSense_stats.json
    name: pfSense_mbufpercent
    value_template: '{{ value_json["data"]["stats"]["mbufpercent"] }}'
    unit_of_measurement : '%'
  • Make sure your quote charaters are correct. Sometimes they copy over wrong.
  • Replace <host> with the internal IP of your pfSense router (ie. 192.168.1.1).
  • Replace <apikey_value> with your api_key (ie PFFArandomalphanumeric902)
  • Replace <apisecret_value> with your api_secret (ie abcdefghijklmnopqrstuvwxyz1234567890abcde)
  1. Add a group with your new sensors. They should update every minute.
pfSense Monitor:
  view: no
  entities:
    - sensor.pfSense_cpu
    - sensor.pfsense_cpu_temp
    - sensor.pfsense_mbufpercent
    - sensor.pfsense_mem
    - sensor.pfsense_uptime

I hope this helps someone. You could also use the other calls to perform actions based on HA events. ie, if HA loses internet, you could reboot the router or pull the gateway status… https://github.com/ndejong/pfsense_fauxapi#api-action-summary


Tracking Devices with PfSense router
Tracking Devices with PfSense router
FreeNAS Stat Monitor
#2

Nice work!!


#3

Hey.
I tried to install the package in pfsense but a get a ssl error when I run fetch https://raw.githubusercontent.com/ndejong/pfsense_fauxapi/master/package/pfSense-pkg-FauxAPI-1.3_1.txz in ssh.


#4

Hrm. Just tried mine, did a copy and paste and it downloaded no problem. How are you attempting this? SSH? Or from the web GUI (Diagnostics>Command Prompt)?


#5

Also tried it on another FreeBSD box… worked no problem there too.