freedombone-app-pihole 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # pi-hole ad blocker
  10. #
  11. # Adapted from instructions at:
  12. # http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0/#manualsetup
  13. #
  14. # License
  15. # =======
  16. #
  17. # Copyright (C) 2016-2018 Bob Mottram <bob@freedombone.net>
  18. #
  19. # This program is free software: you can redistribute it and/or modify
  20. # it under the terms of the GNU Affero General Public License as published by
  21. # the Free Software Foundation, either version 3 of the License, or
  22. # (at your option) any later version.
  23. #
  24. # This program is distributed in the hope that it will be useful,
  25. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. # GNU Affero General Public License for more details.
  28. #
  29. # You should have received a copy of the GNU Affero General Public License
  30. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. VARIANTS='full full-vim adblocker'
  32. IN_DEFAULT_INSTALL=0
  33. SHOW_ON_ABOUT=0
  34. PIHOLE_IFACE=eth0
  35. PIHOLE_DNS1='91.239.100.100'
  36. PIHOLE_DNS2='89.233.43.71'
  37. piholeBasename=pihole
  38. piholeDir=/etc/$piholeBasename
  39. PIHOLE_CUSTOM_ADLIST=$piholeDir/adlists.list
  40. PIHOLE_BLACKLIST=$piholeDir/blacklist.txt
  41. PIHOLE_WHITELIST=$piholeDir/whitelist.txt
  42. PIHOLE_REPO="https://github.com/pi-hole/pi-hole"
  43. PIHOLE_COMMIT='fbee18e24d56b418e3329a56ae4156dbe8fe5e1f'
  44. pihole_variables=(ONION_ONLY
  45. PIHOLE_IFACE
  46. PIHOLE_DNS1
  47. PIHOLE_DNS2)
  48. function logging_on_pihole {
  49. echo -n ''
  50. }
  51. function logging_off_pihole {
  52. echo -n ''
  53. }
  54. function pihole_copy_files {
  55. if [ ! -d /etc/.pihole ]; then
  56. mkdir /etc/.pihole
  57. fi
  58. cp "$INSTALL_DIR/pihole/adlists.default" /etc/.pihole/adlists.default
  59. cp "$INSTALL_DIR/pihole/adlists.default" $piholeDir/adlists.default
  60. if [ ! -f $PIHOLE_CUSTOM_ADLIST ]; then
  61. cp "$INSTALL_DIR/pihole/adlists.default" $PIHOLE_CUSTOM_ADLIST
  62. fi
  63. cp "$INSTALL_DIR/pihole/advanced/Scripts/"* /opt/$piholeBasename
  64. if [ -f /etc/dnsmasq.d/01-pihole.conf ]; then
  65. rm /etc/dnsmasq.d/01-pihole.conf
  66. fi
  67. cp "$INSTALL_DIR/pihole/advanced/pihole.cron" /etc/cron.d/pihole
  68. cp "$INSTALL_DIR/pihole/gravity.sh" /opt/$piholeBasename
  69. chmod +x /opt/pihole/*.sh
  70. }
  71. function pihole_change_ipv4 {
  72. new_ipv4="$1"
  73. if [ -f /usr/local/bin/pihole ]; then
  74. setupVars=$piholeDir/setupVars.conf
  75. if [ -f $setupVars ]; then
  76. sed -i "s|IPv4_address=.*|IPv4_address=${new_ipv4}|g" $setupVars
  77. fi
  78. fi
  79. }
  80. function pihole_update {
  81. if [ ! -f /usr/local/bin/gravity.sh ]; then
  82. return
  83. fi
  84. if [ ! -f "$HOME/${PROJECT_NAME}-wifi.cfg" ]; then
  85. PIHOLE_IFACE=eth0
  86. else
  87. read_config_param WIFI_INTERFACE
  88. PIHOLE_IFACE=$WIFI_INTERFACE
  89. fi
  90. IPv4_address="$(get_ipv4_address)"
  91. IPv6_address="$(get_ipv6_address)"
  92. setupVars=$piholeDir/setupVars.conf
  93. echo "piholeInterface=${PIHOLE_IFACE}" > ${setupVars}
  94. echo "IPV4_ADDRESS=${IPv4_address}" >> ${setupVars}
  95. if [ ${#IPv6_address} -gt 0 ]; then
  96. echo "IPV6_ADDRESS=${IPv6_address}" >> ${setupVars}
  97. fi
  98. echo "piholeDNS1=${PIHOLE_DNS1}" >> ${setupVars}
  99. echo "piholeDNS2=${PIHOLE_DNS1}" >> ${setupVars}
  100. { echo 'domain-needed';
  101. echo 'bogus-priv';
  102. echo 'no-resolv';
  103. echo "server=${PIHOLE_DNS1}";
  104. echo "server=${PIHOLE_DNS2}";
  105. echo "interface=${PIHOLE_IFACE}";
  106. echo 'listen-address=127.0.0.1'; } > /etc/dnsmasq.conf
  107. pihole -g
  108. systemctl restart dnsmasq
  109. # avoid having the tripwire report pihole updates
  110. if ! grep -q '!/etc/pihole' /etc/tripwire/twpol.txt; then
  111. sed -i '\|/etc\t\t->.*|a\ !/etc/pihole ;' /etc/tripwire/twpol.txt
  112. fi
  113. }
  114. function pihole_change_upstream_dns {
  115. data=$(mktemp 2>/dev/null)
  116. dialog --backtitle $"Ad Blocker Upstream DNS" \
  117. --radiolist $"Pick a domain name service (DNS):" 29 50 20 \
  118. 1 $"UncensoredDNS" on \
  119. 2 $"Digital Courage" off \
  120. 3 $"German Privacy Foundation 1" off \
  121. 4 $"German Privacy Foundation 2" off \
  122. 5 $"Chaos Computer Club" off \
  123. 6 $"ClaraNet" off \
  124. 7 $"OpenNIC 1" off \
  125. 8 $"OpenNIC 2" off \
  126. 9 $"OpenNIC 3" off \
  127. 10 $"OpenNIC 4" off \
  128. 11 $"OpenNIC 5" off \
  129. 12 $"OpenNIC 6" off \
  130. 13 $"OpenNIC 7" off \
  131. 14 $"PowerNS" off \
  132. 15 $"ValiDOM" off \
  133. 16 $"Freie Unzensierte" off \
  134. 17 $"DNS.Watch" off \
  135. 18 $"uncensoreddns.org" off \
  136. 19 $"Lorraine Data Network" off \
  137. 20 $"Google" off 2> "$data"
  138. sel=$?
  139. case $sel in
  140. 1) rm -f "$data"
  141. exit 1;;
  142. 255) rm -f "$data"
  143. exit 1;;
  144. esac
  145. case $(cat "$data") in
  146. 1) PIHOLE_DNS1='91.239.100.100'
  147. PIHOLE_DNS2='89.233.43.71'
  148. ;;
  149. 2) PIHOLE_DNS1='85.214.73.63'
  150. PIHOLE_DNS2='213.73.91.35'
  151. ;;
  152. 3) PIHOLE_DNS1='87.118.100.175'
  153. PIHOLE_DNS2='94.75.228.29'
  154. ;;
  155. 4) PIHOLE_DNS1='85.25.251.254'
  156. PIHOLE_DNS2='2.141.58.13'
  157. ;;
  158. 5) PIHOLE_DNS1='213.73.91.35'
  159. PIHOLE_DNS2='85.214.73.63'
  160. ;;
  161. 6) PIHOLE_DNS1='212.82.225.7'
  162. PIHOLE_DNS2='212.82.226.212'
  163. ;;
  164. 7) PIHOLE_DNS1='58.6.115.42'
  165. PIHOLE_DNS2='58.6.115.43'
  166. ;;
  167. 8) PIHOLE_DNS1='119.31.230.42'
  168. PIHOLE_DNS2='200.252.98.162'
  169. ;;
  170. 9) PIHOLE_DNS1='217.79.186.148'
  171. PIHOLE_DNS2='81.89.98.6'
  172. ;;
  173. 10) PIHOLE_DNS1='78.159.101.37'
  174. PIHOLE_DNS2='203.167.220.153'
  175. ;;
  176. 11) PIHOLE_DNS1='82.229.244.191'
  177. PIHOLE_DNS2='82.229.244.191'
  178. ;;
  179. 12) PIHOLE_DNS1='216.87.84.211'
  180. PIHOLE_DNS2='66.244.95.20'
  181. ;;
  182. 13) PIHOLE_DNS1='207.192.69.155'
  183. PIHOLE_DNS2='72.14.189.120'
  184. ;;
  185. 14) PIHOLE_DNS1='194.145.226.26'
  186. PIHOLE_DNS2='77.220.232.44'
  187. ;;
  188. 15) PIHOLE_DNS1='78.46.89.147'
  189. PIHOLE_DNS2='88.198.75.145'
  190. ;;
  191. 16) PIHOLE_DNS1='85.25.149.144'
  192. PIHOLE_DNS2='87.106.37.196'
  193. ;;
  194. 17) PIHOLE_DNS1='84.200.69.80'
  195. PIHOLE_DNS2='84.200.70.40'
  196. ;;
  197. 18) PIHOLE_DNS1='91.239.100.100'
  198. PIHOLE_DNS2='89.233.43.71'
  199. ;;
  200. 19) PIHOLE_DNS1='80.67.188.188'
  201. PIHOLE_DNS2='89.234.141.66'
  202. ;;
  203. 20) PIHOLE_DNS1='8.8.8.8'
  204. PIHOLE_DNS2='4.4.4.4'
  205. dialog --title $"WARNING" \
  206. --msgbox $"\\nGoogle's main purpose for providing DNS resolvers is to spy upon people and know which sites they are visiting.\\n\\nThis is something to consider, and you should only really be using Google DNS as a last resort if other resolvers are unavailable." 12 60
  207. ;;
  208. 255) rm -f "$data"
  209. exit 1;;
  210. esac
  211. rm -f "$data"
  212. write_config_param "PIHOLE_DNS1" "$PIHOLE_DNS1"
  213. write_config_param "PIHOLE_DNS2" "$PIHOLE_DNS2"
  214. }
  215. function update_pihole_interactive {
  216. clear
  217. echo $'Updating Ad Blocker Lists'
  218. echo ''
  219. pihole_update
  220. }
  221. function configure_firewall_for_pihole {
  222. firewall_add DNS 53
  223. }
  224. function pihole_pause {
  225. pihole disable
  226. dialog --title $"Pause Ad Blocker" \
  227. --msgbox $"Ad blocking is paused" 6 60
  228. }
  229. function pihole_resume {
  230. pihole enable
  231. dialog --title $"Resume Ad Blocker" \
  232. --msgbox $"Ad blocking has resumed" 6 60
  233. }
  234. function configure_interactive_pihole {
  235. W=(1 $"Edit ads list"
  236. 2 $"Edit blacklisted domain names"
  237. 3 $"Edit whitelisted domain names"
  238. 4 $"Change upstream DNS servers"
  239. 5 $"Pause blocker"
  240. 6 $"Resume blocker")
  241. while true
  242. do
  243. # shellcheck disable=SC2068
  244. selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Ad blocker" --menu $"Choose an operation, or ESC for main menu:" 13 60 9 "${W[@]}" 3>&2 2>&1 1>&3)
  245. if [ ! "$selection" ]; then
  246. break
  247. fi
  248. case $selection in
  249. 1) editor $PIHOLE_CUSTOM_ADLIST
  250. update_pihole_interactive
  251. ;;
  252. 2) editor $PIHOLE_BLACKLIST
  253. update_pihole_interactive
  254. ;;
  255. 3) editor $PIHOLE_WHITELIST
  256. update_pihole_interactive
  257. ;;
  258. 4) pihole_change_upstream_dns
  259. update_pihole_interactive
  260. ;;
  261. 5) pihole_pause
  262. ;;
  263. 6) pihole_resume
  264. ;;
  265. esac
  266. done
  267. }
  268. function install_interactive_pihole {
  269. APP_INSTALLED=1
  270. }
  271. function reconfigure_pihole {
  272. echo -n ''
  273. }
  274. function upgrade_pihole {
  275. CURR_PIHOLE_COMMIT=$(get_completion_param "pihole commit")
  276. if [[ "$CURR_PIHOLE_COMMIT" == "$PIHOLE_COMMIT" ]]; then
  277. return
  278. fi
  279. function_check set_repo_commit
  280. set_repo_commit "$INSTALL_DIR/pihole" "pihole commit" "$PIHOLE_COMMIT" $PIHOLE_REPO
  281. pihole_copy_files
  282. pihole_update
  283. }
  284. function backup_local_pihole {
  285. function_check backup_directory_to_usb
  286. backup_directory_to_usb $piholeDir pihole
  287. }
  288. function restore_local_pihole {
  289. function_check restore_directory_from_usb
  290. restore_directory_from_usb / pihole
  291. }
  292. function backup_remote_pihole {
  293. function_check backup_directory_to_friend
  294. backup_directory_to_friend $piholeDir pihole
  295. }
  296. function restore_remote_pihole {
  297. function_check restore_directory_from_friend
  298. restore_directory_from_friend / pihole
  299. }
  300. function remove_pihole {
  301. apt-get -yq remove --purge dnsmasq
  302. if [ ! -d /var/www/pihole ]; then
  303. rm -rf /var/www/pihole
  304. fi
  305. if [ -f /usr/local/bin/gravity.sh ]; then
  306. rm /usr/local/bin/gravity.sh
  307. fi
  308. if [ -f /usr/local/bin/pihole ]; then
  309. rm /usr/local/bin/pihole
  310. fi
  311. if [ -d /opt/pihole ]; then
  312. rm -rf /opt/pihole
  313. fi
  314. if [ -d $piholeDir ]; then
  315. rm -rf $piholeDir
  316. fi
  317. if [ -d /etc/.pihole ]; then
  318. rm -rf /etc/.pihole
  319. fi
  320. if [ -f /var/log/pihole.log ]; then
  321. rm /var/log/pihole.log
  322. fi
  323. if [ -f /etc/cron.d/pihole ]; then
  324. rm /etc/cron.d/pihole
  325. fi
  326. if [ -d "$INSTALL_DIR/pihole" ]; then
  327. rm -rf "$INSTALL_DIR/pihole"
  328. fi
  329. firewall_remove 53
  330. userdel -r pihole
  331. }
  332. function install_pihole {
  333. apt-get -yq install dnsmasq curl
  334. adduser --disabled-login --gecos 'pi-hole' pihole
  335. if [ ! -d /home/pihole ]; then
  336. echo $"/home/pihole directory not created"
  337. exit 538929
  338. fi
  339. chmod 600 /etc/shadow
  340. chmod 600 /etc/gshadow
  341. usermod -a -G www-data pihole
  342. chmod 0000 /etc/shadow
  343. chmod 0000 /etc/gshadow
  344. systemctl enable dnsmasq
  345. if [ ! -d "$INSTALL_DIR" ]; then
  346. mkdir -p "$INSTALL_DIR"
  347. fi
  348. if [ ! -d "$INSTALL_DIR/pihole" ]; then
  349. cd "$INSTALL_DIR" || exit 78245624527
  350. if [ -d /repos/pihole ]; then
  351. mkdir pihole
  352. cp -r -p /repos/pihole/. pihole
  353. cd pihole || exit 24572424684
  354. git pull
  355. else
  356. git_clone $PIHOLE_REPO pihole
  357. fi
  358. if [ ! -d "$INSTALL_DIR/pihole" ]; then
  359. exit 523925
  360. fi
  361. cd "$INSTALL_DIR/pihole" || exit 2682468242
  362. git checkout "$PIHOLE_COMMIT" -b "$PIHOLE_COMMIT"
  363. set_completion_param "pihole commit" "$PIHOLE_COMMIT"
  364. fi
  365. if [ ! -d /var/www/pihole/htdocs ]; then
  366. mkdir -p /var/www/pihole/htdocs
  367. fi
  368. # blank file which takes the place of ads
  369. { echo '<html>';
  370. echo '<body>';
  371. echo '</body>';
  372. echo '</html>'; } > /var/www/pihole/htdocs/index.html
  373. if [ ! -f "$INSTALL_DIR/pihole/gravity.sh" ]; then
  374. exit 26738
  375. fi
  376. cp "$INSTALL_DIR/pihole/gravity.sh" /usr/local/bin/gravity.sh
  377. chmod 755 /usr/local/bin/gravity.sh
  378. if [ ! -f "$INSTALL_DIR/pihole/pihole" ]; then
  379. exit 52935
  380. fi
  381. cp "$INSTALL_DIR/pihole/pihole" /usr/local/bin/pihole
  382. chmod 755 /usr/local/bin/pihole
  383. if [ ! -d $piholeDir ]; then
  384. mkdir $piholeDir
  385. fi
  386. if [ ! -d /opt/pihole ]; then
  387. mkdir -p /opt/pihole
  388. fi
  389. pihole_copy_files
  390. chown -R www-data:www-data /var/www/pihole/htdocs
  391. configure_firewall_for_pihole
  392. pihole_update
  393. APP_INSTALLED=1
  394. }
  395. # NOTE: deliberately no exit 0