Merge pull request #543 from billz/feature/notracking

Enable ad / tracker blocking with host blocklists
This commit is contained in:
Bill Zimmerman 2020-04-03 08:58:46 +02:00 committed by GitHub
commit 67746601a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 411 additions and 2 deletions

View file

@ -0,0 +1,24 @@
<?php
require '../../includes/csrf.php';
require_once '../../includes/config.php';
if (isset($_POST['blocklist_id'])) {
$blocklist_id = $_POST['blocklist_id'];
$notracking_url = "https://raw.githubusercontent.com/notracking/hosts-blocklists/master/";
switch ($blocklist_id) {
case "notracking-hostnames":
$file = "hostnames.txt";
break;
case "notracking-domains":
$file = "domains.txt";
break;
}
$blocklist = $notracking_url . $file;
exec("sudo /etc/raspap/adblock/update_blocklist.sh $blocklist $file " .RASPI_ADBLOCK_LISTPATH, $return);
$jsonData = ['return'=>$return];
echo json_encode($jsonData);
}

View file

@ -221,3 +221,17 @@ canvas#divDBChartBandwidthhourly {
.table {
margin-bottom: 0rem;
}
.check-hidden {
visibility: hidden;
}
.check-updated {
opacity: 0;
color: #1cc88a;
}
.check-progress {
color: #999;
}

View file

@ -245,3 +245,17 @@ canvas#divDBChartBandwidthhourly {
.table {
margin-bottom: 0rem;
}
.check-hidden {
visibility: hidden;
}
.check-updated {
opacity: 0;
color: #1cc88a;
}
.check-progress {
color: #999;
}

View file

@ -434,3 +434,17 @@ canvas#divDBChartBandwidthhourly {
.figure, .authors {
filter: brightness(70%) !important;
}
.check-hidden {
visibility: hidden;
}
.check-updated {
opacity: 0;
color: #1cc88a;
}
.check-progress {
color: #999;
}

View file

@ -291,6 +291,28 @@ function loadChannelSelect(selected) {
});
}
/* Updates the selected blocklist
* Request is passed to an ajax handler to download the associated list.
* Interface elements are updated to indicate current progress, status.
*/
function updateBlocklist() {
var blocklist_id = $('#cbxblocklist').val();
if (blocklist_id == '') { return; }
$('#cbxblocklist-status').find('i').removeClass('fas fa-check').addClass('fas fa-cog fa-spin');
$('#cbxblocklist-status').removeClass('check-hidden').addClass('check-progress');
$.post('ajax/adblock/update_blocklist.php',{ 'blocklist_id':blocklist_id },function(data){
var jsonData = JSON.parse(data);
if (jsonData['return'] == '0') {
$('#cbxblocklist-status').find('i').removeClass('fas fa-cog fa-spin').addClass('fas fa-check');
$('#cbxblocklist-status').removeClass('check-progress').addClass('check-updated').delay(500).animate({ opacity: 1 }, 700);
$('#'+blocklist_id).text("Just now");
}
})
}
function clearBlocklistStatus() {
$('#cbxblocklist-status').removeClass('check-updated').addClass('check-hidden');
}
// Static Array method
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);

6
config/blocklists.json Normal file
View file

@ -0,0 +1,6 @@
{
"notracking/hosts-blocklist": [
"notracking-hostnames",
"notracking-domains"
]
}

View file

@ -11,6 +11,8 @@ define('RASPI_CACHE_PATH', sys_get_temp_dir() . '/raspap');
// These are typical for default RPi installs. Modify if needed.
define('RASPI_DNSMASQ_CONFIG', '/etc/dnsmasq.d/090_raspap.conf');
define('RASPI_DNSMASQ_LEASES', '/var/lib/misc/dnsmasq.leases');
define('RASPI_ADBLOCK_LISTPATH', '/etc/raspap/adblock/');
define('RASPI_ADBLOCK_CONFIG', '/etc/dnsmasq.d/090_adblock.conf');
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
define('RASPI_DHCPCD_CONFIG', '/etc/dhcpcd.conf');
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');

60
includes/adblock.php Normal file
View file

@ -0,0 +1,60 @@
<?php
require_once 'includes/status_messages.php';
require_once 'config.php';
/**
* Manages ad blocking (dnsmasq) configuration
*
*/
function DisplayAdBlockConfig()
{
$status = new StatusMessages();
$enabled = false;
if (!RASPI_MONITOR_ENABLED) {
if (isset($_POST['saveadblocksettings'])) {
if ($_POST['adblock-enable'] == "1") {
$config = 'conf-file=' .RASPI_ADBLOCK_LISTPATH .'domains.txt'.PHP_EOL;
$config.= 'addn-hosts=' .RASPI_ADBLOCK_LISTPATH .'hostnames.txt'.PHP_EOL;
} elseif ($_POST['adblock-enable'] == "0") {
$config = null;
}
file_put_contents("/tmp/dnsmasqdata", $config);
system('sudo cp /tmp/dnsmasqdata '.RASPI_ADBLOCK_CONFIG, $return);
if ($return == 0) {
$status->addMessage('Adblock configuration updated successfully', 'success');
} else {
$status->addMessage('Adblock configuration failed to be updated.', 'danger');
}
} elseif (isset($_POST['restartadblock']) || isset($_POST['startadblock'])) {
exec('sudo /bin/systemctl restart dnsmasq.service', $dnsmasq, $return);
if ($return == 0) {
$status->addMessage('Adblock restart successful', 'success');
} else {
$status->addMessage('Adblock failed to restart.', 'danger');
}
}
}
exec('cat '. RASPI_ADBLOCK_CONFIG, $return);
$arrConf = ParseConfig($return);
if (sizeof($arrConf) > 0) {
$enabled = true;
}
exec('pidof dnsmasq | wc -l', $dnsmasq);
$dnsmasq_state = ($dnsmasq[0] > 0);
$serviceStatus = $dnsmasq_state && $enabled ? "up" : "down";
echo renderTemplate(
"adblock", compact(
"status",
"serviceStatus",
"dnsmasq_state",
"enabled"
)
);
}

View file

@ -15,6 +15,8 @@ $defaults = [
// These are typical for default RPi installs. Modify if needed.
'RASPI_DNSMASQ_CONFIG' => '/etc/dnsmasq.d/090_raspap.conf',
'RASPI_DNSMASQ_LEASES' => '/var/lib/misc/dnsmasq.leases',
'RASPI_ADBLOCK_LISTPATH' => '/etc/raspap/adblock/',
'RASPI_ADBLOCK_CONFIG' => '/etc/dnsmasq.d/090_adblock.conf',
'RASPI_HOSTAPD_CONFIG' => '/etc/hostapd/hostapd.conf',
'RASPI_DHCPCD_CONFIG' => '/etc/dhcpcd.conf',
'RASPI_WPA_SUPPLICANT_CONFIG' => '/etc/wpa_supplicant/wpa_supplicant.conf',

View file

@ -352,6 +352,12 @@ function dnsServers()
return (array) $data;
}
function blocklistProviders()
{
$data = json_decode(file_get_contents("./config/blocklists.json"));
return (array) $data;
}
function optionsForSelect($options)
{
$html = "";
@ -370,3 +376,44 @@ function optionsForSelect($options)
}
return $html;
}
function blocklistUpdated($file)
{
$blocklist = RASPI_CONFIG.'/adblock/'.$file;
if (file_exists($blocklist)) {
$lastModified = date ("F d Y H:i:s.", filemtime($blocklist));
$lastModified = formatDateAgo($lastModified);
return $lastModified;
} else {
return 'Never';
}
}
function formatDateAgo($datetime, $full = false)
{
$now = new DateTime;
$ago = new DateTime($datetime);
$diff = $now->diff($ago);
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}

View file

@ -31,6 +31,7 @@ require_once 'includes/authenticate.php';
require_once 'includes/admin.php';
require_once 'includes/dhcp.php';
require_once 'includes/hostapd.php';
require_once 'includes/adblock.php';
require_once 'includes/system.php';
require_once 'includes/sysstats.php';
require_once 'includes/configure_client.php';
@ -137,6 +138,11 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
<?php if (RASPI_DHCP_ENABLED && !$bridgedEnabled) : ?>
<li class="nav-item">
<a class="nav-link" href="index.php?page=dhcpd_conf"><i class="fas fa-exchange-alt fa-fw mr-2"></i><span class="nav-label"><?php echo _("DHCP Server"); ?></a>
</li>
<?php endif; ?>
<?php if (RASPI_ADBLOCK_ENABLED) : ?>
<li class="nav-item">
<a class="nav-link" href="index.php?page=adblock_conf"><i class="far fa-hand-paper fa-fw mr-2"></i><span class="nav-label"><?php echo _("Ad Blocking"); ?></a>
</li>
<?php endif; ?>
<?php if (RASPI_NETWORK_ENABLED) : ?>
@ -239,6 +245,9 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
case "hostapd_conf":
DisplayHostAPDConfig();
break;
case "adblock_conf":
DisplayAdBlockConfig();
break;
case "openvpn_conf":
DisplayOpenVPNConfig();
break;

21
installers/update_blocklist.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/bash
#
#
# @author billz
# license: GNU General Public License v3.0
# Exit on error
set -o errexit
# Exit on error inside functions
set -o errtrace
# Turn on traces, disabled by default
#set -o xtrace
update_url=$1
file=$2
destination=$3
wget -q ${update_url} -O ${destination}${file} &> /dev/null
echo "$?"

Binary file not shown.

View file

@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: 1.2.1\n"
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
"PO-Revision-Date: 2018-05-17 17:15+0000\n"
"PO-Revision-Date: 2020-03-29 00:05+0000\n"
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
"Language-Team: \n"
"Language: en_US\n"
@ -318,7 +318,7 @@ msgid "Dnsmasq is running"
msgstr "Dnsmasq is running"
msgid "Dnsmasq is not running"
msgstr "Dnsmasq is not running
msgstr "Dnsmasq is not running"
msgid "Upstream DNS servers"
msgstr "Upstream DNS servers"
@ -688,3 +688,42 @@ msgstr "up"
msgid "down"
msgstr "down"
#: includes/adblock.php
msgid "adblock"
msgstr "adblock"
msgid "Ad Blocking"
msgstr "Ad Blocking"
msgid "Start Ad Blocking"
msgstr "Start Ad Blocking"
msgid "Restart Ad Blocking"
msgstr "Restart Ad Blocking"
msgid "Blocklist settings"
msgstr "Blocklist settings"
msgid "Enable blocklists"
msgstr "Enable blocklists"
msgid "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
msgstr "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
msgid "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
msgstr "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
msgid "Choose a blocklist provider"
msgstr "Choose a blocklist provider"
msgid "Update now"
msgstr "Update now"
msgid "Statistics"
msgstr "Statistics"
msgid "Information provided by adblock"
msgstr "Information provided by adblock"

52
templates/adblock.php Executable file
View file

@ -0,0 +1,52 @@
<?php ob_start() ?>
<?php if (!RASPI_MONITOR_ENABLED) : ?>
<input type="submit" class="btn btn-outline btn-primary" name="saveadblocksettings" value="<?php echo _("Save settings"); ?>">
<?php if ($dnsmasq_state) : ?>
<input type="submit" class="btn btn-warning" name="restartadblock" value="<?php echo _("Restart Ad Blocking"); ?>">
<?php else : ?>
<input type="submit" class="btn btn-success" name="startadblock" value="<?php echo _("Start Ad Blocking"); ?>">
<?php endif ?>
<?php endif ?>
<?php $buttons = ob_get_clean(); ob_end_clean() ?>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<i class="far fa-hand-paper mr-2"></i><?php echo _("Ad Blocking"); ?>
</div>
<div class="col">
<button class="btn btn-light btn-icon-split btn-sm service-status float-right">
<span class="icon text-gray-600"><i class="fas fa-circle service-status-<?php echo $serviceStatus ?>"></i></span>
<span class="text service-status">adblock <?php echo _($serviceStatus) ?></span>
</button>
</div>
</div><!-- /.row -->
</div><!-- /.card-header -->
<div class="card-body">
<?php $status->showMessages(); ?>
<form role="form" action="?page=adblock_conf" enctype="multipart/form-data" method="POST">
<?php echo CSRFTokenFieldTag() ?>
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="nav-item"><a class="nav-link active" id="clienttab" href="#adblocklistsettings" data-toggle="tab"><?php echo _("Blocklist settings"); ?></a></li>
<li class="nav-item"><a class="nav-link" id="logoutputtab" href="#adblocklogfileoutput" data-toggle="tab"><?php echo _("Logging"); ?></a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<?php echo renderTemplate("adblock/general", $__template_data) ?>
<?php echo renderTemplate("adblock/stats", $__template_data) ?>
<?php echo renderTemplate("adblock/logging", $__template_data) ?>
</div><!-- /.tab-content -->
<?php echo $buttons ?>
</form>
</div><!-- /.card-body -->
<div class="card-footer"><?php echo _("Information provided by adblock"); ?></div>
</div><!-- /.card -->
</div><!-- /.col-lg-12 -->
</div><!-- /.row -->

View file

@ -0,0 +1,43 @@
<!-- blocklist settings tab -->
<div class="tab-pane active" id="adblocklistsettings">
<div class="row">
<div class="col-md-6">
<h4 class="mt-3"><?php echo _("Blocklist settings"); ?></h4>
<div class="input-group">
<input type="hidden" name="adblock-enable" value="0">
<div class="custom-control custom-switch">
<input class="custom-control-input" id="adblock-enable" type="checkbox" name="adblock-enable" value="1" <?php echo $enabled ? ' checked="checked"' : "" ?> aria-describedby="adblock-description">
<label class="custom-control-label" for="adblock-enable"><?php echo _("Enable blocklists") ?></label>
</div>
<p id="adblock-description">
<small><?php echo _("Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis.") ?></small>
<div>
<small class="text-muted"><?php echo _("This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration.") ?></small>
</div>
</p>
</div>
<div class="row">
<div class="col-md-12">
<p id="blocklist-updated">
<div><small><?php echo _("Hostnames blocklist last updated") ?>: <span class="font-weight-bold" id="notracking-hostnames">
<?php echo blocklistUpdated('hostnames.txt') ?></span></small></div>
<div><small><?php echo _("Domains blocklist last updated") ?>: <span class="font-weight-bold" id="notracking-domains">
<?php echo blocklistUpdated('domains.txt') ?></b></small></div>
</p>
<div class="input-group col-md-12 mb-4">
<select class="custom-select custom-select-sm" id="cbxblocklist" onchange="clearBlocklistStatus()">
<option value=""><?php echo _("Choose a blocklist provider") ?></option>
<option disabled="disabled"></option>
<?php echo optionsForSelect(blocklistProviders()) ?>
</select>
<div class="input-group-append">
<button class="btn btn-sm btn-outline-secondary rounded-right" type="button" onclick="updateBlocklist()"><?php echo _("Update now"); ?></button>
<span id="cbxblocklist-status" class="input-group-addon check-hidden ml-2 mt-1"><i class="fas fa-check"></i></span>
</div>
</div>
</div>
</div>
</div>
</div><!-- /.row -->
</div><!-- /.tab-pane | advanded tab -->

View file

@ -0,0 +1,25 @@
<!-- logging tab -->
<div class="tab-pane fade" id="adblocklogfileoutput">
<h4 class="mt-3"><?php echo _("Logging"); ?></h4>
<div class="row">
<div class="form-group col-md-8">
<?php
$log = '';
exec('sudo chmod o+r /tmp/dnsmasq.log');
$handle = fopen("/tmp/dnsmasq.log", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/(0.0.0.0)/', $line)){
$log.=$line;
}
}
} else {
$log = "Unable to open log file";
}
fclose($handle);
echo '<textarea class="logoutput">'.htmlspecialchars($log, ENT_QUOTES).'</textarea>';
?>
</div>
</div>
</div><!-- /.tab-pane -->

View file

@ -0,0 +1,15 @@
<!-- statistics tab -->
<div class="tab-pane fade" id="adblockstats">
<h4 class="mt-3"><?php echo _("Statistics"); ?></h4>
<div class="row">
<div class="form-group col-md-8">
<?php
/*
* BZ todo: implement basic stats
*
*/
?>
</div>
</div>
</div><!-- /.tab-pane -->