<?php /* Detailed Pi-hole Block Page: Show "Website Blocked" if user browses to site, but not to image/file requests based on the work of WaLLy3K for DietPi & Pi-Hole */ function validIP($address){ if (preg_match('/[.:0]/', $address) && !preg_match('/[1-9a-f]/', $address)) { // Test if address contains either `:` or `0` but not 1-9 or a-f return false; } return !filter_var($address, FILTER_VALIDATE_IP) === false; } $uri = escapeshellcmd($_SERVER['REQUEST_URI']); $serverName = escapeshellcmd($_SERVER['SERVER_NAME']); // If the server name is 'pi.hole', it's likely a user trying to get to the admin panel. // Let's be nice and redirect them. if ($serverName === 'pi.hole') { header('HTTP/1.1 301 Moved Permanently'); header("Location: /admin/"); } // Retrieve server URI extension (EG: jpg, exe, php) ini_set('pcre.recursion_limit',100); $uriExt = pathinfo($uri, PATHINFO_EXTENSION); // Define which URL extensions get rendered as "Website Blocked" $webExt = array('asp', 'htm', 'html', 'php', 'rss', 'xml'); // Get IPv4 and IPv6 addresses from setupVars.conf (if available) $setupVars = parse_ini_file("/etc/pihole/setupVars.conf"); $ipv4 = isset($setupVars["IPV4_ADDRESS"]) ? explode("/", $setupVars["IPV4_ADDRESS"])[0] : $_SERVER['SERVER_ADDR']; $ipv6 = isset($setupVars["IPV6_ADDRESS"]) ? explode("/", $setupVars["IPV6_ADDRESS"])[0] : $_SERVER['SERVER_ADDR']; $AUTHORIZED_HOSTNAMES = array( $ipv4, $ipv6, str_replace(array("[","]"), array("",""), $_SERVER["SERVER_ADDR"]), "pi.hole", "localhost"); // Allow user set virtual hostnames $virtual_host = getenv('VIRTUAL_HOST'); if (!empty($virtual_host)) array_push($AUTHORIZED_HOSTNAMES, $virtual_host); // Immediately quit since we didn't block this page (the IP address or pi.hole is explicitly requested) if(validIP($serverName) || in_array($serverName,$AUTHORIZED_HOSTNAMES)) { http_response_code(404); die(); } if(in_array($uriExt, $webExt) || empty($uriExt)) { // Requested resource has an extension listed in $webExt // or no extension (index access to some folder incl. the root dir) $showPage = true; } else { // Something else $showPage = false; } // Handle incoming URI types if (!$showPage) { ?> <html> <head> <script>window.close();</script></head> <body> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"> </body> </html> <?php die(); } // Get Pi-hole version $piHoleVersion = exec('cd /etc/.pihole/ && git describe --tags --abbrev=0'); // Don't show the URI if it is the root directory if($uri == "/") { $uri = ""; } ?> <!DOCTYPE html> <html> <head> <meta charset='UTF-8'/> <title>Website Blocked</title> <link rel='stylesheet' href='http://pi.hole/pihole/blockingpage.css'/> <link rel='shortcut icon' href='http://pi.hole/admin/img/favicon.png' type='image/png'/> <meta name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0, user-scalable=no'/> <meta name='robots' content='noindex,nofollow'/> </head> <body id="body"> <header> <h1><a href='/'>Website Blocked</a></h1> </header> <main> <div>Access to the following site has been blocked:<br/> <span class='pre msg'><?php echo $serverName.$uri; ?></span></div> <div>If you have an ongoing use for this website, please ask the owner of the Pi-hole in your network to have it whitelisted.</div> <input id="domain" type="hidden" value="<?php echo $serverName; ?>"> <input id="quiet" type="hidden" value="yes"> <button id="btnSearch" class="buttons blocked" type="button" style="visibility: hidden;"></button> This page is blocked because it is explicitly contained within the following block list(s): <pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre><br/> <div class='buttons blocked'> <a class='safe33' href='javascript:history.back()'>Go back</a> <a class='safe33' id="whitelisting">Whitelist this page</a> <a class='safe33' href='javascript:window.close()'>Close window</a> </div> <div style="width: 98%; text-align: center; padding: 10px;" hidden="true" id="whitelistingform"> <p>Note that whitelisting domains which are blocked using the wildcard method won't work.</p> <p>Password required!</p><br/> <form> <input name="list" type="hidden" value="white"><br/> Domain:<br/> <input name="domain" value="<?php echo $serverName ?>" disabled><br/><br/> Password:<br/> <input type="password" id="pw" name="pw"><br/><br/> <button class="buttons33 safe" id="btnAdd" type="button">Whitelist</button> </form><br/> <pre id="whitelistingoutput" style="width: 100%; height: 100%; padding: 5px;" hidden="true"></pre><br/> </div> </main> <footer>Generated <?php echo date('D g:i A, M d'); ?> by Pi-hole <?php echo $piHoleVersion; ?></footer> <script src="http://pi.hole/admin/scripts/vendor/jquery.min.js"></script> <script> // Create event for when the output is appended to (function($) { var origAppend = $.fn.append; $.fn.append = function () { return origAppend.apply(this, arguments).trigger("append"); }; })(jQuery); </script> <script src="http://pi.hole/admin/scripts/pi-hole/js/queryads.js"></script> <script> function inIframe () { try { return window.self !== window.top; } catch (e) { return true; } } // Try to detect if page is loaded within iframe if(inIframe()) { // Within iframe // hide content of page $('#body').hide(); // remove background document.body.style.backgroundImage = "none"; } else { // Query adlists $( "#btnSearch" ).click(); } $( "#whitelisting" ).on( "click", function(){ $( "#whitelistingform" ).removeAttr( "hidden" ); }); // Remove whitelist functionality if the domain was blocked because of a wildcard $( "#output" ).bind("append", function(){ if($( "#output" ).contents()[0].data.indexOf("Wildcard blocking") !== -1) { $( "#whitelisting" ).hide(); $( "#whitelistingform" ).hide(); } }); function add() { var domain = $("#domain"); var pw = $("#pw"); if(domain.val().length === 0){ return; } $.ajax({ url: "/admin/scripts/pi-hole/php/add.php", method: "post", data: {"domain":domain.val(), "list":"white", "pw":pw.val()}, success: function(response) { $( "#whitelistingoutput" ).removeAttr( "hidden" ); if(response.indexOf("Pi-hole blocking") !== -1) { // Reload page after 5 seconds setTimeout(function(){window.location.reload(1);}, 5000); $( "#whitelistingoutput" ).html("---> Success <---<br/>You may have to flush your DNS cache"); } else { $( "#whitelistingoutput" ).html("---> "+response+" <---"); } }, error: function(jqXHR, exception) { $( "#whitelistingoutput" ).removeAttr( "hidden" ); $( "#whitelistingoutput" ).html("---> Unknown Error <---"); } }); } // Handle enter button for adding domains $(document).keypress(function(e) { if(e.which === 13 && $("#pw").is(":focus")) { add(); } }); // Handle buttons $("#btnAdd").on("click", function() { add(); }); </script> </body> </html>