Contents of My Custom HTML Page not Showing/ You are Connect

  • Hi there I am a newbie to Psense. I tried configuring a custom captive portal after installing Pfsense, the captive portal redirects users to the custom captive portal as expected. However, the background page and the css styling on my html page does not show when loaded by the user. Instead the empty html skeleton shows up. Can anyone here help me on how to solve this please.
    In addition, after connecting a user to the internet and the user disconnects from it (either because they went to a place far away from the internet or they switch off the wifi). If they try to connect to the internet again, the captive portal notification shows up on the notification bar for the user to authenticate. If the user navigates to the login page it prints out a message "You are Connected", but the user cannot get accesss to the internet. Is there anything wrong I am doing that I do not know? Can someone help me out here.
    Your help is highly appreciated and thanks in advance.
    Please find attached below the html code, css, the default Netgate php code and the background image I used to configure the custom captive portal.

    HTML Code

    <!DOCTYPE html>
    <!-- saved from url=(0043) -->
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <link href="class.css" rel="stylesheet" type="text/css" />
    <title>Manneh kunda wifi</title>
    <div id="content">
      <div class="header">
    <h1>  <div class="logo"> WELCOME TO MANNEH KUNDA WIFI </d> </h1>
     <h2> <div class="logo1"> For more Info and code purchase, call 3182025 / 7535414 </div></h2>
    <h3> <div class="logo2">Enter your voucher code and click Login to access the Internet</div></h3>
       <div class="login-card">
        <div id="error-message" >
      <form name="login_form" method="post" action="#PORTAL_ACTION#">   
            <div class="auth_head_div">
            <h6 class="auth_head"><strong>Customer SignIn</strong></h6>
          <div class="auth_source">
            <input name="auth_voucher" type="text" placeholder="Enter code, small letters">
        <input name="redirurl" type="hidden" value="">
        <input type="submit" name="accept" class="login login-submit" value="SignIn" id="login" >

    CSS Code

     #content,.login,.login-card a,.login-card h1,.login-help{text-align:center}body,html{margin:0;padding:0;width:100%;height:100%; font-weight:100;
    	  display:table}#content{font-family:'Source Sans Pro',sans-serif;background-color:#1C1275;background:url(barley.jpg)
    	  center center no-repeat fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:100% 100%; color:#fff;
    	  display:table-cell;vertical-align:middle}.login-card{padding:40px;width:210px;background-color:#F7F7F7;margin:10px auto 10px;
    	  border-radius:100px;box-shadow:0 2px 2px rgba(0,0,0,.3);overflow:hidden; opacity: 0.9}.login-card h1{font-weight:400;
    	  font-size:2.3em;color:#000705}.login-card h1 span{color:#f26721}.login-card img{width:70%;height:70%}.login-card input[type=submit]{width:100%;
    	  display:block;margin-bottom:10px;position:relative; border-radius: 90px}.login-card input[type=text],input[type=password]{height:44px;font-size:16px;
    	  width:100%;margin-bottom:10px;-webkit-appearance:none;background:#fff;border:1px solid #d9d9d9;border-top:1px solid silver;
    	  padding:0 8px;box-sizing:border-box; border-radius: 90px; -moz-box-sizing:border-box}.login-card input[type=text]:hover,input[type=password]
    	  :hover{border:1px solid #b9b9b9;border-top:1px solid #a0a0a0;-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);
    	  -webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.login{font-size:14px;font-family:Arial,sans-serif;
    	  font-weight:700;height:36px;padding:0 8px}.login-submit{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;color:#fff;
    	  text-shadow:0 1px rgba(0,0,0,.1);background-color:#90ee90}.login-submit:disabled{opacity:.6}.login-submit:hover{border:0;
    	  text-shadow:0 1px rgba(0,0,0,.3);background-color:#33353a}.login-card a{text-decoration:none;color:#222;font-weight:400;
    	  display:inline-block;opacity:.6;transition:opacity ease .5s}.login-card a:hover{opacity:1}.login-help{width:100%;font-size:12px}.
    	  list{list-style-type:none;padding:0}.list__item{margin:0 0 .7rem;padding:0}label{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;
    	  flex:none;margin-right:10px;float:left}@media screen and (max-width:450px){.login-card{width:70%!important}.login-card img{width:30%;height:30%}}
    	  padding-top:100px;padding-bottom:300px;}.auth_source{border: 1px solid lightgray; padding:20px 8px 0px 8px; margin-top: -2em; 
    	  border-radius: 50px; }.auth_head{background-color:#f7f7f7;display:inline-block; font-size: 0.90em }.auth_head_div{text-align:center;
    	  }#error-message{text-align:center;color:#f80a0a;font-style:oblique;} .header{border-bottom:1px solid #fff; width:100%; padding:10px;} .logo{ display: inline; font-size:45px; text-align:right; color:black;}
          .logo1{color: black} .logo2{color: black}

    Netgate defualt PHP code

     * index.php
     * part of pfSense (
     * Copyright (c) 2004-2013 BSD Perimeter
     * Copyright (c) 2013-2016 Electric Sheep Fencing
     * Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate)
     * All rights reserved.
     * Originally part of m0n0wall (
     * Copyright (c) 2003-2006 Manuel Kasper <>.
     * All rights reserved.
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
    header("Expires: 0");
    header("Cache-Control: no-cache, no-store, must-revalidate");
    header("Pragma: no-cache");
    header("Connection: close");
    global $cpzone, $cpzoneid;
    $cpzone = strtolower($_REQUEST['zone']);
    $cpcfg = $config['captiveportal'][$cpzone];
    if (empty($cpcfg)) {
    	log_error("Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
    	portal_reply_page($redirurl, "error", gettext("Internal error"));
    $cpzoneid = $cpcfg['zoneid'];
    $orig_host = $_SERVER['HTTP_HOST'];
    /* NOTE: IE 8/9 is buggy and that is why this is needed */
    $orig_request = trim($_REQUEST['redirurl'], " /");
    $clientip = $_SERVER['REMOTE_ADDR'];
    if (!$clientip) {
    	/* not good - bail out */
    	log_error("Zone: {$cpzone} - Captive portal could not determine client's IP address.");
    	$errormsg = gettext("An error occurred.  Please check the system logs for more information.");
    	portal_reply_page($redirurl, "error", $errormsg);
    $cpsession = captiveportal_isip_logged($clientip);
    $ourhostname = portal_hostname_from_client_ip($clientip);
    /* Automatically switching to the logout page requires a custom logout page to be present. */
    if ((!empty($cpsession)) && (! $_POST['logout_id']) && (!empty($cpcfg['page']['logouttext']))) {
    	/* if client already connected and a custom logout page is set : show logout page */
    	$protocol = (isset($config['captiveportal'][$cpzone]['httpslogin'])) ? 'https://' : 'http://';
    	$logouturl = "{$protocol}{$ourhostname}/";
    	$sessionid = $cpsession['sessionid'];
    	$attributes = array();
    	if (!empty($cpsession['session_timeout']))
    		$attributes['session_timeout'] = $cpsession['session_timeout'];
    	if (!empty($cpsession['session_terminate_time']))
    		$attributes['session_terminate_time'] = $cpsession['session_terminate_time'];
    } elseif (!empty($cpsession) && (!isset($_POST['logout_id']) || !isset($config['captiveportal'][$cpzone]['logoutwin_enable']))) {
    	/* If client try to access captive portal page while already connected, 
    		but no custom logout page does exist and logout popup is disabled */	
    	echo gettext("You are connected.<br/>");
    	if ($_GET['redirurl'] || $_POST['redirurl']) {
    		$redirurl = $_GET['redirurl'] ? $_GET['redirurl'] : $_POST['redirurl'];
    		$redirurl = htmlspecialchars($redirurl);
    		echo ("You can proceed to: <a href='{$redirurl}'>{$redirurl}</a>");
    } elseif ($orig_host != $ourhostname) {
    	/* the client thinks it's connected to the desired web server, but instead
    	   it's connected to us. Issue a redirect... */
    	$protocol = (isset($cpcfg['httpslogin'])) ? 'https://' : 'http://';
    	header("Location: {$protocol}{$ourhostname}/index.php?zone={$cpzone}&redirurl=" . urlencode("http://{$orig_host}/{$orig_request}"));
    if (preg_match("/redirurl=(.*)/", $orig_request, $matches)) {
    	$redirurl = urldecode($matches[1]);
    } elseif ($_REQUEST['redirurl']) {
    	$redirurl = $_REQUEST['redirurl'];
    } elseif (!empty($cpcfg['redirurl'])) {
    	$redirurl = $cpcfg['redirurl'];
    $macfilter = !isset($cpcfg['nomacfilter']);
    /* find MAC address for client */
    if ($macfilter || isset($cpcfg['passthrumacadd'])) {
    	$tmpres = pfSense_ip_to_mac($clientip);
    	if (!is_array($tmpres)) {
    		/* unable to find MAC address - shouldn't happen! - bail out */
    		captiveportal_logportalauth("unauthenticated", "noclientmac", $clientip, "ERROR");
    		echo "An error occurred.  Please check the system logs for more information.";
    		log_error("Zone: {$cpzone} - Captive portal could not determine client's MAC address.  Disable MAC address filtering in captive portal if you do not need this functionality.");
    	$clientmac = $tmpres['macaddr'];
    if ($_POST['logout_id']) {
    	echo <<<EOD
    <body bgcolor="#435370">
    <span style="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
    <b>You have been disconnected.</b>
    <script type="text/javascript">
    setTimeout('window.close();',5000) ;
    	$safe_logout_id = SQLite3::escapeString($_POST['logout_id']);
    } elseif (($_POST['accept'] || $cpcfg['auth_method'] === 'radmac' || !empty($cpcfg['blockedmacsurl'])) && $macfilter && $clientmac && captiveportal_blocked_mac($clientmac)) {
    	captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Blocked MAC address");
    	if (!empty($cpcfg['blockedmacsurl'])) {
    		portal_reply_page($cpcfg['blockedmacsurl'], "redir");
    	} else {
    		if ($cpcfg['auth_method'] === 'radmac') {
    			echo gettext("This MAC address has been blocked");
    		} else {
    			portal_reply_page($redirurl, "error", "This MAC address has been blocked");
    } elseif (portal_consume_passthrough_credit($clientmac)) {
    	/* allow the client through if it had a pass-through credit for its MAC */
    	captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
    	portal_allow($clientip, $clientmac, "unauthenticated", null, $redirurl);
    } elseif (isset($config['voucher'][$cpzone]['enable']) && ($_POST['accept'] && $_POST['auth_voucher']) || $_GET['voucher']) {
    	if (isset($_POST['auth_voucher'])) {
    		$voucher = trim($_POST['auth_voucher']);
    	} else {
    		/* submit voucher via URL, see */
    		$voucher = trim($_GET['voucher']);
    		portal_reply_page($redirurl, "login", null, $clientmac, $clientip, null, null, $voucher);
    	$errormsg = gettext("Invalid credentials specified.");
    	$timecredit = voucher_auth($voucher);
    	// $timecredit contains either a credit in minutes or an error message
    	if ($timecredit > 0) {  // voucher is valid. Remaining minutes returned
    		// if multiple vouchers given, use the first as username
    		$a_vouchers = preg_split("/[\t\n\r ]+/s", $voucher);
    		$voucher = $a_vouchers[0];
    		$attr = array(
    			'voucher' => 1,
    			'session_timeout' => $timecredit*60,
    			'session_terminate_time' => 0);
    		if (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher') === 2) {
    			portal_reply_page($redirurl, "error", "Reuse of identification not allowed.");
    		} elseif (portal_allow($clientip, $clientmac, $voucher, null, $redirurl, $attr, null, 'voucher', 'voucher')) {
    			// YES: user is good for $timecredit minutes.
    			captiveportal_logportalauth($voucher, $clientmac, $clientip, "Voucher login good for $timecredit min.");
    		} else {
    			portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgexpired'] ? $config['voucher'][$cpzone]['descrmsgexpired']: $errormsg);
    	} elseif (-1 == $timecredit) {  // valid but expired
    		captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE", "voucher expired");
    		portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgexpired'] ? $config['voucher'][$cpzone]['descrmsgexpired']: $errormsg);
    	} else {
    		captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE");
    		portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgnoaccess'] ? $config['voucher'][$cpzone]['descrmsgnoaccess'] : $errormsg);
    } elseif ($_POST['accept'] || $cpcfg['auth_method'] === 'radmac') {
    		if ($cpcfg['auth_method'] === 'radmac' && !isset($_POST['accept'])) {
    			$user = $clientmac; 
    			$passwd = $cpcfg['radmac_secret'];
    			$context = 'radmac'; // Radius MAC authentication
    		} elseif (!empty(trim($_POST['auth_user2']))) { 
    			$user = trim($_POST['auth_user2']);
    			$passwd = $_POST['auth_pass2'];
    			$context = 'second'; // Assume users to use the first context if auth_user2 is empty/does not exist
    		} else {
    			$user = trim($_POST['auth_user']);
    			$passwd = $_POST['auth_pass'];
    			$context = 'first';
    	$pipeno = captiveportal_get_next_dn_ruleno('auth');
    	/* if the pool is empty, return appropriate message and exit */
    	if (is_null($pipeno)) {
    		$replymsg = gettext("System reached maximum login capacity");
    		if ($cpcfg['auth_method'] === 'radmac') {
    			echo $replymsg;
    		} else {
    			portal_reply_page($redirurl, "error", $replymsg);
    		log_error("Zone: {$cpzone} - WARNING!  Captive portal has reached maximum login capacity");
    	$auth_result = captiveportal_authenticate_user($user, $passwd, $clientmac, $clientip, $pipeno, $context);
    	if ($auth_result['result']) {
    		captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status']);
    		portal_allow($clientip, $clientmac, $user, $passwd, $redirurl, $auth_result['attributes'], $pipeno, $auth_result['auth_method'], $context);
    	} else {
    		$type = "error";
    		if (!empty($auth_result['attributes']['url_redirection'])) {
    			$redirurl = $auth_result['attributes']['url_redirection'];
    			$type = "redir";
    		if ($auth_result['login_message']) {
    			$replymsg = $auth_result['login_message'];
    		} else {
    			$replymsg = gettext("Invalid credentials specified.");
    		captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status'], $replymsg);
    		/* Radius MAC authentication. */
    		if ($context === 'radmac' && $type !== 'redir' && !isset($cpcfg['radmac_fallback'])) {
    			echo $replymsg;
    		} else {
    			portal_reply_page($redirurl, $type, $replymsg);
    } else {
    	/* display captive portal page */
    	portal_reply_page($redirurl, "login", null, $clientmac, $clientip);

    Background Image

  • Rebel Alliance


    In addition, after connecting a user to the internet and the user disconnects from it (either because they went to a place far away from the internet or they switch off the wifi). If they try to connect to the internet again, the captive portal notification shows up on the notification bar for the user to authenticate. If the user navigates to the login page it prints out a message "You are Connected", but the user cannot get accesss to the internet. Is there anything wrong I am doing that I do not know? Can someone help me out here.

    It's a known issue with the current pfSense version.
    You have 2 choices :


  • I had a similar problem any time and the problem doesn`t are the captive portal

    My problem was the web captive portal is blank all time

    My problem was the DNS resolved, maybe you can check the DNSLookp in your client

    maybe this link helps you