Merge branch 'development' into blockpage2

This commit is contained in:
WaLLy3K 2017-05-13 23:29:44 +10:00 committed by GitHub
commit f9d41caeb6
9 changed files with 180 additions and 142 deletions

View file

@ -25,6 +25,8 @@ addn-hosts=/etc/pihole/local.list
domain-needed domain-needed
localise-queries
bogus-priv bogus-priv
no-resolv no-resolv

View file

@ -54,6 +54,8 @@ fetch_checkout_pull_branch() {
# Set the reference for the requested branch, fetch, check it put and pull it # Set the reference for the requested branch, fetch, check it put and pull it
cd "${directory}" cd "${directory}"
git remote set-branches origin "${branch}" || return 1 git remote set-branches origin "${branch}" || return 1
git stash --all --quiet &> /dev/null || true
git clean --force -d || true
git fetch --quiet || return 1 git fetch --quiet || return 1
checkout_pull_branch "${directory}" "${branch}" || return 1 checkout_pull_branch "${directory}" "${branch}" || return 1
} }

View file

@ -27,6 +27,7 @@ PIHOLELOG="/var/log/pihole.log"
PIHOLEGITDIR="/etc/.pihole/" PIHOLEGITDIR="/etc/.pihole/"
ADMINGITDIR="/var/www/html/admin/" ADMINGITDIR="/var/www/html/admin/"
WHITELISTMATCHES="/tmp/whitelistmatches.list" WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
TIMEOUT=60 TIMEOUT=60
# Header info and introduction # Header info and introduction
@ -259,18 +260,18 @@ ip_ping_check() {
if [[ -n ${ip_def_gateway} ]]; then if [[ -n ${ip_def_gateway} ]]; then
echo -n "::: Pinging default IPv${protocol} gateway: " echo -n "::: Pinging default IPv${protocol} gateway: "
if ! ping_gateway="$(${cmd} -q -W 3 -c 3 -n ${ip_def_gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then if ! ping_gateway="$(${cmd} -q -W 3 -c 3 -n ${ip_def_gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
echo "Gateway did not respond." log_echo "Gateway did not respond."
return 1 return 1
else else
echo "Gateway responded." log_echo "Gateway responded."
log_write "${ping_gateway}" log_write "${ping_gateway}"
fi fi
echo -n "::: Pinging Internet via IPv${protocol}: " echo -n "::: Pinging Internet via IPv${protocol}: "
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${g_addr} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${g_addr} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
echo "Query did not respond." log_echo "Query did not respond."
return 1 return 1
else else
echo "Query responded." log_echo "Query responded."
log_write "${ping_inet}" log_write "${ping_inet}"
fi fi
else else
@ -523,6 +524,18 @@ header_write "Analyzing pihole.log"
&& log_write "${PIHOLELOG} is ${pihole_size}." \ && log_write "${PIHOLELOG} is ${pihole_size}." \
|| log_echo "Warning: No pihole.log file found!" || log_echo "Warning: No pihole.log file found!"
header_write "Analyzing pihole-FTL.log"
FTL_length=$(grep -c ^ "${FTLLOG}") \
&& log_write "${FTLLOG} is ${FTL_length} lines long." \
|| log_echo "Warning: No pihole-FTL.log file found!"
FTL_size=$(du -h "${FTLLOG}" | awk '{ print $1 }') \
&& log_write "${FTLLOG} is ${FTL_size}." \
|| log_echo "Warning: No pihole-FTL.log file found!"
tail -n50 "${FTLLOG}" >&3
trap finalWork EXIT trap finalWork EXIT
### Method calls for additional logging ### ### Method calls for additional logging ###

View file

@ -10,9 +10,9 @@
echo -n "::: Flushing /var/log/pihole.log ..." echo -n "::: Flushing /var/log/pihole.log ..."
# Test if logrotate is available on this system # Test if logrotate is available on this system
if command -v /usr/sbin/logrotate &> /dev/null; then if command -v /usr/sbin/logrotate >/dev/null; then
# Flush twice to move all data out of sight of FTL # Flush twice to move all data out of sight of FTL
/usr/sbin/logrotate --force /etc/pihole/logrotate /usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
/usr/sbin/logrotate --force /etc/pihole/logrotate /usr/sbin/logrotate --force /etc/pihole/logrotate
else else
# Flush both pihole.log and pihole.log.1 (if existing) # Flush both pihole.log and pihole.log.1 (if existing)

View file

@ -10,17 +10,22 @@
# Variables # Variables
DEFAULT="-1" DEFAULT="-1"
PHGITDIR="/etc/.pihole/" COREGITDIR="/etc/.pihole/"
WEBGITDIR="/var/www/html/admin/" WEBGITDIR="/var/www/html/admin/"
getLocalVersion() { getLocalVersion() {
# FTL requires a different method
if [[ "$1" == "FTL" ]]; then
pihole-FTL version
return 0
fi
# Get the tagged version of the local repository # Get the tagged version of the local repository
local directory="${1}" local directory="${1}"
local version local version
cd "${directory}" || { echo "${DEFAULT}"; return 1; } cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
version=$(git describe --tags --always || \ version=$(git describe --tags --always || echo "$DEFAULT")
echo "${DEFAULT}")
if [[ "${version}" =~ ^v ]]; then if [[ "${version}" =~ ^v ]]; then
echo "${version}" echo "${version}"
elif [[ "${version}" == "${DEFAULT}" ]]; then elif [[ "${version}" == "${DEFAULT}" ]]; then
@ -33,13 +38,18 @@ getLocalVersion() {
} }
getLocalHash() { getLocalHash() {
# Local FTL hash does not exist on filesystem
if [[ "$1" == "FTL" ]]; then
echo "N/A"
return 0
fi
# Get the short hash of the local repository # Get the short hash of the local repository
local directory="${1}" local directory="${1}"
local hash local hash
cd "${directory}" || { echo "${DEFAULT}"; return 1; } cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
hash=$(git rev-parse --short HEAD || \ hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
echo "${DEFAULT}")
if [[ "${hash}" == "${DEFAULT}" ]]; then if [[ "${hash}" == "${DEFAULT}" ]]; then
echo "ERROR" echo "ERROR"
return 1 return 1
@ -49,12 +59,33 @@ getLocalHash() {
return 0 return 0
} }
getRemoteHash(){
# Remote FTL hash is not applicable
if [[ "$1" == "FTL" ]]; then
echo "N/A"
return 0
fi
local daemon="${1}"
local branch="${2}"
hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \
awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}')
if [[ -n "$hash" ]]; then
echo "$hash"
else
echo "ERROR"
return 1
fi
return 0
}
getRemoteVersion(){ getRemoteVersion(){
# Get the version from the remote origin # Get the version from the remote origin
local daemon="${1}" local daemon="${1}"
local version local version
version=$(curl --silent --fail https://api.github.com/repos/pi-hole/${daemon}/releases/latest | \ version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
awk -F: '$1 ~/tag_name/ { print $2 }' | \ awk -F: '$1 ~/tag_name/ { print $2 }' | \
tr -cd '[[:alnum:]]._-') tr -cd '[[:alnum:]]._-')
if [[ "${version}" =~ ^v ]]; then if [[ "${version}" =~ ^v ]]; then
@ -66,72 +97,72 @@ getRemoteVersion(){
return 0 return 0
} }
#PHHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/commits/master | \ versionOutput() {
# grep sha | \ [[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
# head -n1 | \ [[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
# awk -F ' ' '{ print $2 }' | \ [[ "$1" == "FTL" ]] && GITDIR="FTL"
# tr -cd '[[:alnum:]]._-')
#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \ [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
# grep sha | \ [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
# head -n1 | \ if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
# awk -F ' ' '{ print $2 }' | \ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
# tr -cd '[[:alnum:]]._-') [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
normalOutput() {
echo "::: Pi-hole version is $(getLocalVersion "${PHGITDIR}") (Latest version is $(getRemoteVersion pi-hole))"
if [ -d "${WEBGITDIR}" ]; then
echo "::: Web-Admin version is $(getLocalVersion "${WEBGITDIR}") (Latest version is $(getRemoteVersion AdminLTE))"
fi fi
}
webOutput() { if [[ -n "$current" ]] && [[ -n "$latest" ]]; then
if [ -d "${WEBGITDIR}" ]; then output="${1^} version is $current (Latest: $latest)"
case "${1}" in elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
"-l" | "--latest" ) echo $(getRemoteVersion AdminLTE);; output="Current ${1^} version is $current"
"-c" | "--current" ) echo $(getLocalVersion "${WEBGITDIR}");; elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
"-h" | "--hash" ) echo $(getLocalHash "${WEBGITDIR}");; output="Latest ${1^} version is $latest"
* ) echo "::: Invalid Option!"; exit 1; elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
esac output="${1^} hash is not applicable"
elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then
output="${1^} hash is $curHash (Latest: $latHash)"
elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then
output="Current ${1^} hash is $curHash"
elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then
output="Latest ${1^} hash is $latHash"
else else
echo "::: Web interface not installed!"; exit 1; errorOutput
fi fi
[[ -n "$output" ]] && echo " $output"
} }
coreOutput() { errorOutput() {
case "${1}" in echo " Invalid Option! Try 'pihole -v --help' for more information."
"-l" | "--latest" ) echo $(getRemoteVersion pi-hole);; exit 1
"-c" | "--current" ) echo $(getLocalVersion "${PHGITDIR}");; }
"-h" | "--hash" ) echo $(getLocalHash "${PHGITDIR}");;
* ) echo "::: Invalid Option!"; exit 1; defaultOutput() {
esac versionOutput "pi-hole" "$@"
versionOutput "AdminLTE" "$@"
versionOutput "FTL" "$@"
} }
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole -v [REPO | OPTION] [OPTION]
::: Show Pi-hole, Web Admin & FTL versions
::: Show Pi-hole/Web Admin versions
::: Repositories:
::: Usage: pihole -v [ -a | -p ] [ -l | -c ] -p, --pihole Only retrieve info regarding Pi-hole repository
::: -a, --admin Only retrieve info regarding AdminLTE repository
::: Options: -f, --ftl Only retrieve info regarding FTL repository
::: -a, --admin Show both current and latest versions of web admin
::: -p, --pihole Show both current and latest versions of Pi-hole core files Options:
::: -l, --latest (Only after -a | -p) Return only latest version -c, --current Return the current version
::: -c, --current (Only after -a | -p) Return only current version -l, --latest Return the latest version
::: -h, --help Show this help dialog -h, --hash Return the Github hash from your local repositories
::: --help Show this help dialog
EOM "
exit 0 exit 0
} }
if [[ $# = 0 ]]; then
normalOutput
fi
case "${1}" in case "${1}" in
"-a" | "--admin" ) shift; webOutput "$@";; "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
"-p" | "--pihole" ) shift; coreOutput "$@" ;; "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
"-h" | "--help" ) helpFunc;; "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
"--help" ) helpFunc;;
* ) defaultOutput "$@";;
esac esac

View file

@ -67,6 +67,13 @@ SetTemperatureUnit(){
} }
HashPassword(){
# Compute password hash twice to avoid rainbow table vulnerability
return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
echo ${return}
}
SetWebPassword(){ SetWebPassword(){
if [ "${SUDO_USER}" == "www-data" ]; then if [ "${SUDO_USER}" == "www-data" ]; then
@ -81,6 +88,10 @@ SetWebPassword(){
exit 1 exit 1
fi fi
if (( ${#args[2]} > 0 )) ; then
readonly PASSWORD="${args[2]}"
readonly CONFIRM="${PASSWORD}"
else
read -s -p "Enter New Password (Blank for no password): " PASSWORD read -s -p "Enter New Password (Blank for no password): " PASSWORD
echo "" echo ""
@ -92,10 +103,10 @@ SetWebPassword(){
read -s -p "Confirm Password: " CONFIRM read -s -p "Confirm Password: " CONFIRM
echo "" echo ""
fi
if [ "${PASSWORD}" == "${CONFIRM}" ] ; then if [ "${PASSWORD}" == "${CONFIRM}" ] ; then
# Compute password hash twice to avoid rainbow table vulnerability hash=$(HashPassword ${PASSWORD})
hash=$(echo -n ${PASSWORD} | sha256sum | sed 's/\s.*$//')
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
# Save hash to file # Save hash to file
change_setting "WEBPASSWORD" "${hash}" change_setting "WEBPASSWORD" "${hash}"
echo "New password set" echo "New password set"

View file

@ -300,7 +300,6 @@ if ($phBranch !== "master") {
if(domain.length === 0) { if(domain.length === 0) {
return; return;
} }
$.ajax({ $.ajax({
url: "/admin/scripts/pi-hole/php/add.php", url: "/admin/scripts/pi-hole/php/add.php",
method: "post", method: "post",
@ -315,7 +314,6 @@ if ($phBranch !== "master") {
$("#bpOutput").addClass("error"); $("#bpOutput").addClass("error");
$("#bpOutput").html(""+response+""); $("#bpOutput").html(""+response+"");
} }
}, },
error: function(jqXHR, exception) { error: function(jqXHR, exception) {
$("#bpOutput").removeClass("add"); $("#bpOutput").removeClass("add");
@ -323,18 +321,15 @@ if ($phBranch !== "master") {
} }
}); });
} }
<?php if ($featuredTotal > 0) { ?> <?php if ($featuredTotal > 0) { ?>
$(document).keypress(function(e) { $(document).keypress(function(e) {
if(e.which === 13 && $("#bpWLPassword").is(":focus")) { if(e.which === 13 && $("#bpWLPassword").is(":focus")) {
add(); add();
} }
}); });
$("#bpWhitelist").on("click", function() { $("#bpWhitelist").on("click", function() {
add(); add();
}); });
<?php } ?> <?php } ?>
</script> </script>
</body></html> </body></html>

View file

@ -86,7 +86,7 @@ if command -v apt-get &> /dev/null; then
#Debian Family #Debian Family
############################################# #############################################
PKG_MANAGER="apt-get" PKG_MANAGER="apt-get"
UPDATE_PKG_CACHE="test_dpkg_lock; ${PKG_MANAGER} update" UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_INSTALL=(${PKG_MANAGER} --yes --no-install-recommends install) PKG_INSTALL=(${PKG_MANAGER} --yes --no-install-recommends install)
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
@ -408,7 +408,7 @@ setDHCPCD() {
echo "interface ${PIHOLE_INTERFACE} echo "interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS} static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw} static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null static domain_name_servers=127.0.0.1" | tee -a /etc/dhcpcd.conf >/dev/null
} }
setStaticIPv4() { setStaticIPv4() {
@ -1413,7 +1413,8 @@ main() {
pw="" pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8) pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
/usr/local/bin/pihole -a -p "${pw}" . /opt/pihole/webpage.sh
echo "WEBPASSWORD=$(HashPassword ${pw})" >> ${setupVars}
fi fi
fi fi

75
pihole
View file

@ -84,62 +84,45 @@ scanList(){
domain="${1}" domain="${1}"
list="${2}" list="${2}"
method="${3}" method="${3}"
if [[ ${method} == "-exact" ]] ; then
grep -i -E "(^|\s)${domain}($|\s)" "${list}"
else
grep -i "${domain}" "${list}"
fi
}
processWildcards() { if [[ ${method} == "-exact" ]]; then
IFS="." read -r -a array <<< "${1}" grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
for (( i=${#array[@]}-1; i>=0; i-- )); do
ar=""
for (( j=${#array[@]}-1; j>${#array[@]}-i-2; j-- )); do
if [[ $j == $((${#array[@]}-1)) ]]; then
ar="${array[$j]}"
else else
ar="${array[$j]}.${ar}" grep -i "${domain}" ${list}
fi fi
done
echo "${ar}"
done
} }
queryFunc() { queryFunc() {
domain="${2}"
method="${3}" method="${3}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
if [ -e "${list}" ]; then
result=$(scanList ${domain} ${list} ${method})
# Remove empty lines before couting number of results
count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
echo "${result}"
fi
echo ""
else
echo "::: ${list} does not exist"
echo ""
fi
done
# Scan for possible wildcard matches # If domain contains non ASCII characters, convert domain to punycode if python exists
if [ -e "${wildcardlist}" ]; then # Cr: https://serverfault.com/a/335079
local wildcards=($(processWildcards "${domain}")) if [ -z "${2}" ]; then
for domain in ${wildcards[@]}; do echo "::: No domain specified"
result=$(scanList "\/${domain}\/" ${wildcardlist}) exit 1
# Remove empty lines before couting number of results elif [[ ${2} = *[![:ascii:]]* ]]; then
count=$(sed '/^\s*$/d' <<< "$result" | wc -l) [ `which python` ] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
if [[ ${count} > 0 ]]; then else
echo "::: Wildcard blocking ${domain} (${count} results)" domain="${2}"
echo "${result}"
echo ""
fi fi
done
# Scan Whitelist, Blacklist and Wildcards
lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
result=$(scanList ${domain} "${lists}" ${method})
if [ -n "$result" ]; then
echo "$result"
[[ ! -t 1 ]] && exit 0
fi fi
# Scan Domains lists
result=$(scanList ${domain} "/etc/pihole/*.domains" ${method})
if [ -n "$result" ]; then
sort -t . -k 2 -g <<< "$result"
else
[ -n "$method" ] && exact="exact "
echo "::: No ${exact}results found for ${domain}"
fi
exit 0 exit 0
} }