A full fledged web server (Apache?) on pfSense?
-
Hi everybody.
I'm relatively new to pfSense, so please forgive any triviality I my say.
What I'm trying to set up is a Captive Portal. So far I've managed to reach a functioning configuration by following deajan's excellent tutorial (https://forum.pfsense.org/index.php?topic=108493.0). What I'd need now is to add some sort of additional web page for configuring CaptivePortal custom/specific parameters (actually, I need to manipulate FreeRADIUS' mysql tables directly). Again, so far I managed to write a PHP page, which I placed in folder /usr/local/www and is doing what I need.
My problem now, is with page reload. Let me explain, step by step.- I navigate with my browser to my "custom" interface, i.e. https://pfsense.local/userconfig.php
- The page opens up, so that I can fill the different fields with the values I need.
- I hit the "submit" button.
- My form gets submitted and the FreeRADIUS' (mysql) database is updated accordingly.
So far, so good. The problem comes now.
- I hit the "reload" button of my browser, and the form is submitted a second time!
I'm trying to avoid/prevent this by using the PRG (Post/Redirect/Get) Pattern. As an example, I'm using code like this:
session_start(); $message = ""; if(count($_POST) > 0) { $_SESSION['_post'] = serialize($_POST); header("HTTP/1.1 303 See Other"); header("Location: https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); die(); } else if (isset($_SESSION['_post'])){ $_myPost = unserialize($_SESSION['_post']); $message = var_export($_myPost, true); /* Put database-affecting code here (based on contents of $_myPost). */ session_unset(); session_destroy(); } ?> <title>PRG Pattern Demonstration</title> $message" ?>which is working fine on my local development server (PHP 5.6, Apache 2.4, MySQL 5.6) but is failing miserably on pfSense (latest version). If I leave the die() in place the scripts fails silently with no hint at all (it dies?). If I remove the die() instruction, redirection doesn't work at all. Apparently, the die() instructions simply kills the script before any output/header is sent to the browser, whereas, by not using the die() instruction, the header is sent but the script doesn't stop and redirection doesn't take place.
My question, then: is there a way to adjust the above quoted code? Am I missing something? Or, alternatively, is it possible to install Apache as a web-server in place of the (unknown? mysterious?) version pfSense is using by default (and is breaking the 303 redirect mechanism)?
Thanks everybody for the help.
-
pfSense 2.3.x uses nginx.
I'm not a web dev but it seems to me that this is standard behaviour. If you submit a form and then refresh, the browser will warn you if you want to submit again.
-
Of course this is standard behavior, but browser's behavior. That's precisely the reason why PRG patterns have been invented (http://wordsideasandthings.blogspot.it/2013/04/post-redirect-get-pattern-in-php.html) and that's why my set-up requires additional PHP code.
What is NON-standard is this weird NGINX behavior, or at least the behavior of the NGINX version used by pfSense.
It's definitely a problem of the web server not outputting the headers (which is clearly against HTTP 1.1 specifications about 303 return code). I've done additional test. If I leave the die() instruction in place, the PHP script simply (and silently) stops, leaving me with a totally blank page in the browser.
(code like this:if(count($_POST) > 0) { $_SESSION['_post'] = serialize($_POST); header("HTTP/1.1 303 See Other"); header("Location: https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); die(); // <<--------------------- ONLY die() script ends silently, no output at all. } else if (isset($_SESSION['_post'])){ $_myPost = unserialize($_SESSION['_post']); $message = var_export($_myPost, true); /* Put database-affecting code here (based on contents of $_myPost). */ session_unset(); session_destroy(); } ```) If I omit the _die()_ instruction, or if I add a _flush()_ before the _die()_, the script doesn't stop, the html is output but absolutely _no redirect_ takes place, again, which is against HTTP 1.1 specifications! It looks like if headers with response code of type 303 are simply not output at all! (code like thisif(count($_POST) > 0) {
$_SESSION['_post'] = serialize($_POST);header("HTTP/1.1 303 See Other");
header("Location: https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
flush(); // <<---+--------- flush() + die() the script runs to the end but NO REDIRECTION AT ALL takes place.
die(); // <<----|
}
else if (isset($_SESSION['_post'])){
$_myPost = unserialize($_SESSION['_post']);$message = var_export($_myPost, true);
/*
Put database-affecting code here (based on contents of $_myPost).
*/session_unset();
session_destroy();
}) I repeat, this type of code works fantastically in my local web dev environment (apache 2.4, PHP 5.6, MySQL 5.6). The only difference is the web server, that's why I asked if it's possible to replace the webserver. I think I'm going to file a bug report against NGINX/pfSense. In any case, thanks for the reply. -
The web server on pfSense is not intended to be used for anything but pfSense, not for hosting custom pages/code.
If you absolutely must host a web server on the firewall, you'll have to setup a separate instance manually with whatever custom config you want. Dig around the forum and you'll find some examples where people have done just that.