pfSense voucher REST API

Today is time to publish a REST API which helps administrators to manage pfSense captive portal vouchers from outside the pfSense admin portal.

Synopsis

pfSense is a very robust open source solution for managing network services. It has got a web interface which centralizes the configuration of all the network services that the solution provides.

The network service that today centers our attention is the captive portal. The intention of the service is to provide access to a network only to users that have been authenticated. The authentification can be done by user/password(this can be from a LDAP) or by voucher. The fact that a voucher can be used for this authentication converts the pfSense captive portal in a guest network doorkeeper, by the means that guest users don’t have a corporate LDAP credential, so a temporal voucher would fix the situation.

So far, so good. The concern arrives when the pfSense administrator realizes that the only way of creating vouchers is from the pfSense admin web portal. This is very problematic if you are thinking of for example, giving to some other regular users the ability of creating vouchers.

With this intent, I’ve developed a small patch on pfSense that delivers a REST API, which enables managing pfSense vouchers from outside pfSense. By installing it, the possibility of developing third party apps which could interact with the voucher database becomes a fact. An example of a third party app could be a web portal meant to enable regular users to issue temporal vouchers for their visiting guests, without the need of requesting the voucher to the IT team.

This patch has been developed for pfSense 2.0.1. Also it has been tested against pfSense version 2.0.2 without errors.

Installation

First of all, the code must be pushed into the pfSense server. Here is explained the way to achieve it.

You can find the code repo at https://github.com/jpardobl/pfsense_vouchers_rest

Here you have a direct link to download de source code, but you can also clone the code project by git clone command.

If you have downloaded the code by the direct link, extract it at any local directory and change to it.

Now its time to change the secret password that protects the patch from being used by unathorized users.

Open the cp.php file and change the value of the SECRET_KEY by another one of your choice. It is at the line.

define("SECRET_KEY", 'michorizo');

Then lets finally push the code into the pfSense server by the following command.

scp cp.php root@<pfSense_server>:/usr/local/www/

Where <pfSense_server> sould be the name or the ip of the pfSense server.

The patch is ready for use. Lets beging.

Easy use of the REST API

The whole api has just one resource, the Roll. The Roll is in pfSense voucher system the concept that holds every voucher. A Roll has the vouchers associated to it, and also the minutes each of its vouchers will last after they are activated.

The API URI for the Roll resource is:

http://<server>/cp.php/roll/

Creating a Roll

Lets start by creating a new roll into the system. To make http requests will be using the curl command. So to create our first roll of 40 minutes time, 4 vouchers and under the number 56 just type the following command.

curl -w "retcode: %{http_code}" -X POST --insecure  https://<server>/cp.php/roll \
--data "number=56&minutes=40&count=4&comment=nocomment" -H "AUTH: michorizo"
Optional parameters

The -w modifier let us see the return code that we get from the request.

The –insecure modifier prevents curl from checking the servers certificate.

Mandatory parameters

The -X POST makes curl send a POST verb with the request

The –data “number=56&minutes=40&count=4&comment=nocomment” arguments with al the info from the roll

The -H “AUTH: michorizo” Is the header that holds the secret key you configured before. As you can imaging, it should be initialized with the secret key you choosed.

Once you issue this command, then if there were any previos roll under the number 56, you should got a http status code of 303 and the location of the just created roll. Also if you go again to the pfSense admin portal there you should find the voucher 56.

Retreiving a Roll info

To get the Roll info it is easy. Lets use the Roll 56. Just send GET request to the URI of the roll 56 as follows:

curl -w "retcode: %{http_code}" -X GET --insecure  https://<server>/cp.php/roll/56 \
--header "AUTH: michorizo"
Optional parameters

The -w modifier let us see the return code that we get from the request.

The –insecure modifier prevents curl from checking the certificate.

Mandatory parameters

The -X GET makes curl send a GET verb with the request

The -H “AUTH: michorizo” Is the header that holds the secret key you configured before. As you can imaging, it should be initialized with the secret key you choosed.

Deleting a Roll info

To finnish the API accepted verbs explanation, lets remove the Roll 56. Just send the following command:

curl -w "retcode: %{http_code}" -X DELETE --insecure  https://<server>/cp.php/roll/56 \
--header "AUTH: michorizo"
Optional parameters

The -w modifier let us see the return code that we get from the request.

The –insecure modifier prevents curl from checking the certificate.

Mandatory parameters

The -X DELETE makes curl send a DELETE verb with the request

The -H “AUTH: michorizo” Is the header that holds the secret key you configured before. As you can imaging, it should be initialized with the secret key you choosed.

And that’s it. Hope it helps you.

26 thoughts on “pfSense voucher REST API

  1. I’m astounded at how easy you make this topic look thanks to your articles, but I must admit I still don’t quite understand it.

    It seems too complex and extremely exhaustive
    for me personally. However, I’m excited to see what you have to say in next posts: hopefully I’ll be able to
    grasp it at some point.

  2. Please let me know if you’re looking for a author for your weblog. You have some really good articles and I believe I would be a good asset. If you ever want to take some of the load off, I’d absolutely love
    to write some articles for your blog in exchange for a link back to mine.
    Please shoot me an e-mail if interested. Thanks!

  3. the use of api curl: Command not found. Curl error After installing pfSense is closed and opened. Is there a way to get around this problem?
    PfSense version: 2.0.3-RELEASE (amd64)

  4. I wanted to create a rule instance is that you like. But I got the following error.
    “Curl: Command not found”.

    I installed curl package.
    PfSense booted again. This time I got the following error pfSense automatic update. I ignore this error later.
    “Fatal error: Call to undefined function curl_init() in /etc/inc/pfsense-utils.inc on line 1491”

    ran the curl command again. This time I got another error message.
    /libexec/ld-elf.so.1: Shared object “libz.so.6” not found, required by “curl”

    I’m over this issue with the following commands.
    cd /usr/lib/
    ln -s libz.so libz.so.6

    I got a different error message.
    /libexec/ld-elf.so.1: /usr/lib/libz.so.6: version ZLIB_1.2.4.0 required by /usr/local/bin/curl not defined

    I can’t find ZLIB_1.2.4.0 package. I found the source code for version 1.2.8. But don’t make and gmake commands for security reasons.

    Thanks…

    • Do you need curl to be installed at pfsense machine? Why don’t you install it in another machine? When I mention curl on my post I don’t mean that it needs to be executed from the pfsense machine.

  5. Hi,
    I running your api another machine. i got “411 length required” error massage. When I add “Content-Length:0” ,I got “CSRF check failed.” erro message.
    A must have done wrong. I’ll keep trying.
    Thank you for your help.

  6. hi,
    The API doesn’t work with pfSense 2.1. The error is :
    Notice: Undefined index: booting in /etc/inc/config.inc on line 45
    Notice: Undefined variable: ARCH in /etc/inc/config.inc on line 54
    Notice: Undefined index: booting in /etc/inc/config.inc on line 65
    Notice: Undefined index: booting in /etc/inc/config.inc on line 67
    Notice: Undefined index: booting in /etc/inc/config.inc on line 69
    Notice: Undefined index: booting in /etc/inc/config.inc on line 71
    Notice: Undefined index: booting in /etc/inc/config.inc on line 76
    Notice: Undefined index: booting in /etc/inc/config.inc on line 80
    Notice: Undefined index: booting in /etc/inc/config.inc on line 94
    Notice: Undefined index: booting in /etc/inc/config.inc on line 95
    Notice: Undefined index: booting in /etc/inc/config.inc on line 113
    Notice: Undefined index: booting in /etc/inc/config.inc on line 208
    Notice: Undefined index: booting in /etc/inc/config.lib.inc on line 114
    Notice: Undefined index: booting in /etc/inc/config.lib.inc on line 60
    Notice: Undefined index: booting in /etc/inc/config.lib.inc on line 157
    Warning: Cannot modify header information – headers already sent by (output started at /etc/inc/config.inc:45) in /usr/local/www/cp.php on line 57

    Do you have any solution ?

    Best regads,

  7. I’m having trouble using your script.

    When I perform a GET or POST, it says it has failed. Also, a curl just sits there and seems to timeout. Are there any server side settings I need to perform before this works properly?

  8. Wow, was searching like this now for my pfsense for a small cafe…
    I’m trying to build up a small website where the customer goes on and clicks on to create new vouchers and get the vouchers generated and displayed on a pdf or similar.
    But, i’m not the best programmer, how do i have to make the call to the api through PHP`?

    Regards
    Philipp

  9. All examples i found required a username and a password, didn’t get it running with only the secretkey 😦

    I’m running the 2.1 release on the wall, is that version supported by your api?

    Philipp

  10. When i send this:
    #####
    number=3&minutes=40&count=4&comment=nocomment
    #####
    to the api i get this as a result 😦
    #####
    no existe info de roles
    Warning: Cannot modify header information – headers already sent by (output started at /usr/local/www/cp.php:200) in /usr/local/www/cp.php on line 180
    Roll number is missingRoll vouchers count is missingRoll minutes is missingRoll number must be numeric and less than 0A roll has at least one voucher and less than 0.Each voucher must be good for at least 1 minute.
    ####

  11. in the end it was pretty easy, just these few lines php code:
    curl_setopt($ch, CURLOPT_URL,$path);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER,array(‘Auth: n’));
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$postdata);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    my mistake was that i didn’t set these both ssl url options…

    Will you update the api to run with the latest pfsense version?

    Philipp

Leave a comment