David Chao

David Chao

CentOS

做自己的 AdBlock Server – Centos 7 + DNSMasq

2016/11/17

你討厭網路 廣告嗎?在某些情況我實在是恨死現在的網路廣告了,尤其是手機上那些跳出的覆蓋型廣告,關閉鈕還非常難點,這樣的設計擺明是為了誤擊,自己在公司也是負責行銷團隊,看到這樣的廣告投遞方式,只是讓我更瞭解為什麼轉換率那麼差!

也是因為如此現在有越來越多的廣告封鎖軟體,像是 Adblock 或是 uBlock 使用起來也很方便,但是也有一些缺點,以手機來說 Adblock 只能搭配 Safari 使用,所以你如果使用或透過其他 App 瀏覽網頁就依然會有廣告,我最常碰到的情況就是用 Facebook 點連結,因為還是在 Facebook 的 App 中,所以 Adblock 是無法作用的,再來越來越多網站會偵測使用者是否有安裝廣告阻擋工具,如果偵測到就會跟你曉以大義,看多了心情會不好…..所以自己來吧。

實作原理很簡單,透過 DNSMasq 來做 DNS Server 然後將我們要阻擋的廣告 Domain 加入 Host 檔就可以了,DNSMasq 會優先查詢 Host 檔,如果查不到再往外部的 DNS Server 查詢。

環境:

Centos 7
dnsmasq 2.66

先透過 yum 安裝 dnsmasq

yum install -y dnsmasq

編輯 dnsmasq 設定檔 /etc/dnsmasq.conf 確定設定值如下

domain-needed
bogus-priv
strict-order
no-resolv
#外部DNS,可以指定你喜歡的,像中華的 168.95.1.1
server=8.8.8.8
user=dnsmasq
group=dnsmasq
no-dhcp-interface=eth0
bind-interfaces
no-hosts
#另外指定我們的黑名單 host 檔案
addn-hosts=/etc/blocklist.txt
log-facility=/var/log/dnsmasq.log
log-queries
conf-dir=/etc/dnsmasq.d

新增相關的使用者與群組

groupadd -r dnsmasq
useradd -r -g dnsmasq dnsmasq

啟動 dnsmasq

service dnsmasq start

接下來我們使用一支網路上分享的 Shell Script 幫我們將各種 Ad List 組合成 Host 檔案,由於原作者的 Github 已經關閉了,所以我直接分享相關程式碼,其中 outlist 的位置必須跟 dnsmasq 的 addn-hosts 一致喔:

#!/bin/bash
# Modified Pi-hole script to generate a generic hosts file
# for use with dnsmasq's addn-hosts configuration
# original : https://github.com/jacobsalmela/pi-hole/blob/master/gravity-adv.sh

# Address to send ads to. This could possibily be removed, but may be useful for debugging purposes?
destinationIP="0.0.0.0"

outlist='/etc/blocklist.txt'
tempoutlist="$outlist.tmp"

echo "Getting yoyo ad list..."
curl -s -d mimetype=plaintext -d hostformat=unixhosts http://pgl.yoyo.org/adservers/serverlist.php? | sort > $tempoutlist
echo "Getting winhelp2002 ad list..."
curl -s http://winhelp2002.mvps.org/hosts.txt | grep -v "#" | grep -v "127.0.0.1" | sed '/^$/d' | sed 's/\ /\\ /g' | awk '{print $2}' | sort >> $tempoutlist
echo "Getting adaway ad list..."
curl -s https://adaway.org/hosts.txt | grep -v "#" | grep -v "::1" | sed '/^$/d' | sed 's/\ /\\ /g' | awk '{print $2}' | grep -v '^\\' | grep -v '\\$' | sort >> $tempoutlist
echo "Getting hosts-file ad list..."
curl -s http://hosts-file.net/.%5Cad_servers.txt | grep -v "#" | grep -v "::1" | sed '/^$/d' | sed 's/\ /\\ /g' | awk '{print $2}' | grep -v '^\\' | grep -v '\\$' | sort >> $tempoutlist
echo "Getting malwaredomainlist ad list..."
curl -s http://www.malwaredomainlist.com/hostslist/hosts.txt | grep -v "#" | sed '/^$/d' | sed 's/\ /\\ /g' | awk '{print $3}' | grep -v '^\\' | grep -v '\\$' | sort >> $tempoutlist
echo "Getting adblock.gjtech ad list..."
curl -s http://adblock.gjtech.net/?format=unix-hosts | grep -v "#" | sed '/^$/d' | sed 's/\ /\\ /g' | awk '{print $2}' | grep -v '^\\' | grep -v '\\$' | sort >> $tempoutlist
echo "Getting someone who cares ad list..."
curl -s http://someonewhocares.org/hosts/hosts | grep -v "#" | sed '/^$/d' | sed 's/\ /\\ /g' | grep -v '^\\' | grep -v '\\$' | awk '{print $2}' | grep -v '^\\' | grep -v '\\$' | sort >> $tempoutlist
echo "Getting Mother of All Ad Blocks list..."
curl -A 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' -e http://forum.xda-developers.com/ http://adblock.mahakala.is/ | grep -v "#" | awk '{print $2}' | sort >> $tempoutlist

# Remove entries from the whitelist file if it exists at the root of the current user's home folder
echo "Removing duplicates and formatting the list of domains..."
# Removed the uniq command, using sort -u. Removes the dependency on uniq, which is not available on the router by default or via opkg.
# Added a rough way to exclude domains from the list. If you have a number of domains to whitelist, a better solution could be explored.
    cat $tempoutlist | sed $'s/\r$//' | sed '/thisisiafakedomain123\.com/d;/www\.anotherfakedomain123\.com/d' | sort -u | sed '/^$/d' | awk -v "IP=$destinationIP" '{sub(/\r$/,""); print IP" "$0}' > $outlist

# Removes the temporary list.
rm $tempoutlist

# Count how many domains/whitelists were added so it can be displayed to the user
numberOfAdsBlocked=$(cat $outlist | wc -l | sed 's/^[ \t]*//')
echo "$numberOfAdsBlocked ad domains blocked."

# Find a location to save the script. Make sure the file will survive reboot. One option is to mount a usb.
# This gist provides instructions on using a usb for optware on tomato firware (which is really useful on its own): https://gist.github.com/dferg/833aade513965d78b43d

# Now scp this file to a desired location on your router. Its also possible to wget the raw version of this gist.
# scp ./adblock.hosts user@192.168.1.1:/mnt/sda1/dnsmasq/

# Give the script permissions to execute:
# chmod +x make-mega-adblock-hostsfile.sh

# Add the hosts file and extra configuration to tomato's dnsmasq config via Advanced -> DHCP/DNS -> DnsMasq Custom configuration
# addn-hosts=/opt/dnsmasq/final_blocklist.txt
# Never forward plain names (without a dot or domain part)
# domain-needed
# Never forward addresses in the non-routed address spaces.
# bogus-priv

# For debugging purposes, log each DNS query as it passes through dnsmasq. Remove this once you have confirmed it is working.
# log-queries
# log-facility=/opt/dnsmasq/adblocking.log
# This allows it to continue functioning without being blocked by syslog, and allows syslog to use dnsmasq for DNS queries without risking deadlock
# log-async

# Go to Administration -> Scheduler -> Custom (Sets the script to update itself. Choose your own schedule.)
# sh /opt/dnsmasq/make-mega-adblock-hostsfile.sh

# Add another custom command:
# service dnsmasq restart
# ~OR~
# Have the router reboot sometime after the script has been downloaded.

或是從這邊下載:adblock.sh

執行 Script 後就會產生 blocklist.txt 這個檔案,內容大致如下:

記得重新啟動 dnsmasq

service dnsmasq restart

確定防火牆有打開 53 的 tcp / udp port,如果你是用 iptables 設定如下:

/sbin/iptables -A INPUT -i eth0 -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A INPUT -i eth0 -p tcp  --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

如果是 PC 就只要把 DNS 設定到你的主機上就可以了

如果你是 iOS 就有些問題,首先蘋果如果不是 wifi 的話是不支援指定 dns,所以你有三個選擇

1. 只在 wifi 環境用

2. 架設自己的 vpn 再讓 vpn 用自己的 dns server,這是我原本的選項,但實在是很麻煩,架設完成後發現用起來很不順手。

3. 裝一個 app 叫做 DNS Override 他有一個付費項目可以在 3G/4G 環境下變更 DNS 設定,原理還是 vpn,但因為是 on daemon 所以不需要打開 vpn 連線,上網的時候會自動使用,這很方便!費用應該是台幣 $60,為了以後的清淨,可以考慮一下!

趙大衛
貫徹死了都要創業為信念,卻差一點讓口號變成事實! 目前正在進行第一次修養,請多多支持。

發佈留言