├── piholecron.sh ├── README.md ├── blocklist.txt └── youtubeblock.py /piholecron.sh: -------------------------------------------------------------------------------- 1 | cd youtubeblock 2 | python youtubeblock.py 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # youtubeblock.py 2 | This python file will search the pihole logs for youtube advertisement urls and adds them to the blocklist. 3 | Run this script once a day or after seeing advertisement. 4 | 5 | For now it searches the logs for: 6 | - r1---sn- 7 | - r2---sn- 8 | - r3---sn- 9 | - r4---sn- 10 | - r5---sn- 11 | - r6---sn- 12 | - r7---sn- 13 | - r8---sn- 14 | - r9---sn- 15 | - r10---sn- 16 | - r11---sn- 17 | - r12---sn- 18 | - r13---sn- 19 | - r14---sn- 20 | - r15---sn- 21 | - r16---sn- 22 | - r17---sn- 23 | - r18---sn- 24 | - r19---sn- 25 | - r20---sn- 26 | - .sn- 27 | 28 | For me it seems that if I block all domain with "sn-5hne" in it, video's wont load. So this script skips these. Some adds will come through, but most will be blocked. Feedback is welcome! 29 | 30 | as described in https://discourse.pi-hole.net/t/how-do-i-block-ads-on-youtube/253/237 31 | 32 | run this command on pihole (over ssh): 33 | - git clone https://github.com/eLVee1991/youtubeblock.git 34 | - sudo apt-get install python-pip (If python2 is not pre-installed) 35 | - pip install pexpect 36 | - cd youtubeblock 37 | - python youtubeblock.py 38 | -------------------------------------------------------------------------------- /blocklist.txt: -------------------------------------------------------------------------------- 1 | r1---sn-vgqsener.googlevideo.com 2 | r3---sn-qxoedn7z.googlevideo.com 3 | r5---sn-5uaezn6r.googlevideo.com 4 | r5---sn-5goeen76.googlevideo.com 5 | r4---sn-hp57knll.googlevideo.com 6 | r6---sn-qxoedn7z.googlevideo.com 7 | r4---sn-4g5e6nze.googlevideo.com 8 | r1---sn-5ualdn7e.googlevideo.com 9 | r2---sn-tt1e7n7e.googlevideo.com 10 | r4---sn-hp57yn7r.googlevideo.com 11 | r5---sn-n4v7snee.googlevideo.com 12 | r2---sn-8xgp1vo-2iae.googlevideo.com 13 | r6---sn-oapm-guhz.googlevideo.com 14 | r2---sn-bvvbax-hn2d.googlevideo.com 15 | r3---sn-8xgp1vo-qxoe.googlevideo.com 16 | r6---sn-ab5szn7k.googlevideo.com 17 | r2---sn-8xgp1vo-cvnl.googlevideo.com 18 | r5---sn-q4f7sn76.googlevideo.com 19 | r1---sn-8xgp1vo-cvnl.googlevideo.com 20 | r4---sn-h5q7rn7l.googlevideo.com 21 | r2---sn-gx1v2vax-atne.googlevideo.com 22 | r3---sn-gx1v2vax-atne.googlevideo.com 23 | r4---sn-8xgp1vo-cvne.googlevideo.com 24 | r3---sn-2gb7sn7r.googlevideo.com 25 | r3---sn-8xgp1vo-ab5s.googlevideo.com 26 | r4---sn-hgn7yn7l.googlevideo.com 27 | r4---sn-3c27sn7k.googlevideo.com 28 | r6---sn-4g5ednek.googlevideo.com 29 | r2---sn-a5mekn7r.googlevideo.com 30 | r6---sn-f5f7lnee.googlevideo.com 31 | r6---sn-q4fl6nez.googlevideo.com 32 | r4---sn-4g5e6ns6.googlevideo.com 33 | r5---sn-hgn7rne7.googlevideo.com 34 | r4---sn-9gv7enek.googlevideo.com 35 | r4---sn-hpa7znsd.googlevideo.com 36 | r1---sn-qxo7rn7e.googlevideo.com 37 | r4---sn-t0a7sn7d.googlevideo.com 38 | r4---sn-5uaezn6y.googlevideo.com 39 | r1---sn-tt1e7n7k.googlevideo.com 40 | r4---sn-5go7yn7z.googlevideo.com 41 | r5---sn-h5q7rn7s.googlevideo.com 42 | r2---sn-h5q7kned.googlevideo.com 43 | r4---sn-2gb7sn7z.googlevideo.com 44 | r2---sn-aigzrn7e.googlevideo.com 45 | r5---sn-h5q7knel.googlevideo.com 46 | r5---sn-1gieen7e.googlevideo.com 47 | r1---sn-a5msen7s.googlevideo.com 48 | r4---sn-c0q7lnse.googlevideo.com 49 | r1---sn-h0jeen76.googlevideo.com 50 | r2---sn-8xgp1vo-qxoe.googlevideo.com 51 | r4---sn-h5q7knes.googlevideo.com 52 | r1---sn-5uaezn6l.googlevideo.com 53 | r5---sn-2gb7sn7k.googlevideo.com 54 | r5---sn-25glenes.googlevideo.com 55 | r1---sn-4g5e6nss.googlevideo.com 56 | r4---sn-4g5ednsr.googlevideo.com 57 | r3---sn-apn7en7e.googlevideo.com 58 | r5---sn-4g5e6nez.googlevideo.com 59 | r1---sn-4g5ednsr.googlevideo.com 60 | r5---sn-4g5ednss.googlevideo.com 61 | r1---sn-4g5edned.googlevideo.com 62 | r1---sn-4g5e6nld.googlevideo.com 63 | r2---sn-4g5edns6.googlevideo.com 64 | r1---sn-4g5ednsd.googlevideo.com 65 | r1---sn-4g5e6nsy.googlevideo.com 66 | r1---sn-hgn7yn7z.googlevideo.com 67 | r5---sn-ab5l6ndr.googlevideo.com 68 | r1---sn-hgn7yn7s.googlevideo.com 69 | r4---sn-8xgp1vo-cvnl.googlevideo.com 70 | r6---sn-5goeen76.googlevideo.com 71 | r12---sn-bvvbax-hn2d.googlevideo.com 72 | r3---sn-q0cedn7s.googlevideo.com 73 | r1---sn-5ualdn7r.googlevideo.com 74 | r4---sn-ab5szne7.googlevideo.com 75 | r2---sn-q4flrnee.googlevideo.com 76 | r3---sn-q4fl6nss.googlevideo.com 77 | r5---sn-hgn7rn7r.googlevideo.com 78 | r1---sn-aigl6ned.googlevideo.com 79 | r4---sn-aigl6ned.googlevideo.com 80 | r5---sn-aigl6n7z.googlevideo.com 81 | r3---sn-aigzrn7k.googlevideo.com 82 | r4---sn-aigl6ney.googlevideo.com 83 | r4---sn-aigzrn7s.googlevideo.com 84 | r5---sn-aigzrn7s.googlevideo.com 85 | r3---sn-aigl6nek.googlevideo.com 86 | r5---sn-aigzrn76.googlevideo.com 87 | r2---sn-aigl6nl7.googlevideo.com 88 | r4---sn-aigl6n7z.googlevideo.com 89 | r1---sn-aigzrn7d.googlevideo.com 90 | r3---sn-aigl6n76.googlevideo.com 91 | r6---sn-aigl6n76.googlevideo.com 92 | r4---sn-aigzrn7e.googlevideo.com 93 | r2---sn-aigzrn7z.googlevideo.com 94 | r5---sn-aigl6n7s.googlevideo.com 95 | r1---sn-aigl6nl7.googlevideo.com 96 | r4---sn-aigzrn7k.googlevideo.com 97 | r3---sn-aigl6nl7.googlevideo.com 98 | r2---sn-aigzrn7s.googlevideo.com 99 | r4---sn-aigl6n7s.googlevideo.com 100 | r1---sn-aigzrn76.googlevideo.com 101 | r2---sn-aigl6nek.googlevideo.com 102 | r2---sn-aigzrn7d.googlevideo.com 103 | r1---sn-aigzrn7l.googlevideo.com 104 | -------------------------------------------------------------------------------- /youtubeblock.py: -------------------------------------------------------------------------------- 1 | #!/bin/env/python 2 | 3 | import os 4 | import re 5 | try: 6 | import pexpect as p 7 | except ImportError: 8 | print("[+] Pexpect not installed. Please run: 'pip install pexpect' in command line.") 9 | exit() 10 | 11 | raw_addlist = "youtube_raw_addlist.log" 12 | pihole_log = "/var/log/pihole.log" 13 | all_queries = "all_queries.log" 14 | block_list = "blocklist.txt" 15 | black_list = "/etc/pihole/blacklist.txt" 16 | prefix = [] 17 | 18 | # Regex used to match relevant loglines (in this case, to create an part of an IP like r1---sn- etc.) 19 | for i in range(1, 21): 20 | line = ("r"+str(i)+"---sn-") 21 | prefix.append(line) 22 | 23 | 24 | class colors: 25 | """ 26 | Class specifically for message fuction below. 27 | Contains colors and fonts. 28 | """ 29 | UNDERLINE = '\033[4m' 30 | RED = '\033[91m' 31 | GREEN = '\033[92m' 32 | BOLD = '\033[1m' 33 | END = '\033[0m' 34 | 35 | def message(state, msg): 36 | """ 37 | Function that creates print statements with fonts and colors. 38 | """ 39 | if state == "underline": 40 | print(colors.UNDERLINE + msg + colors.END) 41 | elif state == "green": 42 | print(colors.GREEN + msg + colors.END) 43 | elif state == "red": 44 | print(colors.RED + msg + colors.END) 45 | elif state == "bold": 46 | print(colors.BOLD + msg + colors.END) 47 | else: 48 | print("Wrong state. Please try: 'underline', 'green', 'red' or 'bold'") 49 | 50 | 51 | def text(): 52 | message("red", """ 53 | Yb dP .d88b. 8 8 88888 8 8 888b. 8888 54 | YbdP 8P Y8 8 8 8 8 8 8wwwP 8www 55 | YP 8b d8 8b..d8 8 8b..d8 8 b 8 56 | 88 `Y88P' `Y88P' 8 `Y88P' 888P' 8888 57 | 58 | 8 8 8 8 w w 59 | 88b. 8 .d8b. .d8b 8.dP 8 w d88b w8ww 60 | 8 8 8 8' .8 8 88b 8 8 `Yb. 8 61 | 88P' 8 `Y8P' `Y8P 8 Yb 8 8 Y88P Y8P 62 | """) 63 | message("underline", "Pihole unique YouTube advertisement url checker") 64 | message("underline", "Created by eLVee") 65 | message("underline", "Version 1.1") 66 | print("") 67 | 68 | def check_raw(): 69 | """ 70 | Checks the pihole logs for the prefix var above. 71 | Saves the raw data that needs to be sorting to 'youtube_raw_addlist.log' 72 | """ 73 | output_filename = os.path.normpath(raw_addlist) 74 | message("green", "[+] Checking for youtube fingerprint..") 75 | for url in prefix: 76 | line_regex = re.compile(r".*"+url+".*$") 77 | with open(output_filename, "a+") as out_file: 78 | with open(pihole_log, "r") as in_file: 79 | for line in in_file: 80 | if (line_regex.search(line)) or ".sn-" in line: 81 | #print line 82 | out_file.write(line) 83 | else: 84 | #print(url+" not found trying again") 85 | continue 86 | in_file.close() 87 | out_file.close() 88 | 89 | def query_list(): 90 | """ 91 | Checks 'youtube_raw_addlist.log' for the word 'query', so we know for sure it's outgoing. 92 | Then saves that data to 'all_queries.log' for further sorting. 93 | """ 94 | output_filename = os.path.normpath(all_queries) 95 | line_regex = re.compile(r".*"+"query"+".*$") 96 | with open(output_filename, "a+") as out_file: 97 | with open(raw_addlist, "r") as in_file: 98 | for line in in_file: 99 | if (line_regex.search(line)) and "googlevideo.com" in line: 100 | if "5hne" in line: 101 | #print("'5hne' is found in url. Probably a video. Skipping") 102 | pass 103 | if "5hnl" in line: 104 | #print("'5hne' is found in url. Probably a video. Skipping") 105 | pass 106 | else: 107 | thisline = line.split("A] ") 108 | thisline = thisline[1].split(" from") 109 | #print(thisline[0]) 110 | out_file.write(thisline[0]+"\n") 111 | else: 112 | #print(url+" not found trying again") 113 | continue 114 | in_file.close() 115 | out_file.close() 116 | 117 | 118 | 119 | def blocklist(): 120 | """ 121 | Check the the file 'all_queries.log' for unique urls and sorts them. 122 | Then check the blocklist.txt if the urls is already present. If not, adds it. 123 | """ 124 | uniquelines = set(open(all_queries).readlines()) 125 | for line in uniquelines: 126 | with open(block_list, "r+") as in_file: 127 | if line in in_file: 128 | #print("> "+line+" Already in 'blocklist.txt'.") 129 | pass 130 | else: 131 | with open(block_list, "a") as out_file: 132 | #print(line+"\n") 133 | out_file.write(line) 134 | out_file.close() 135 | in_file.close() 136 | 137 | 138 | def add_to_pihole(): 139 | """ 140 | Uploads the contents of 'blocklist.txt' to the pihole with the command pihole -b 141 | """ 142 | urls = [] 143 | with open(block_list, 'r') as in_file: 144 | for line in in_file: 145 | with open(black_list, "r") as in_file2: 146 | if line in in_file2: 147 | pass 148 | else: 149 | #print(line) 150 | urls.append(line.rstrip()+" ") 151 | all_urls = "".join(urls) 152 | #print("[+] Adding "+line.rstrip()+" "+" to pihole.") 153 | if all_urls: 154 | command = p.spawnu("pihole -b "+all_urls) 155 | command.interact() 156 | #print("[+] Done.") 157 | command.close() 158 | command1 = p.spawnu("pihole restartdns") 159 | command1.interact() 160 | command1.close() 161 | else: 162 | message("bold", "[+] No urls to add.") 163 | in_file.close() 164 | 165 | def delete_logs(): 166 | """ 167 | Delete the files 168 | - youtube_raw_addlist.log 169 | - all_queries.log 170 | to keep it nice and clean. 171 | """ 172 | command = p.spawnu("rm -rf youtube_raw_addlist.log all_queries.log") 173 | command.interact() 174 | command.close() 175 | 176 | 177 | text() 178 | message("green", "[+] Checking all dns requests for YouTube queries.") 179 | check_raw() 180 | message("bold", "[+] Done checking requests.") 181 | message("green", "[+] Sorting urls..") 182 | query_list() 183 | message("bold", "[+] Done sorting urls for queries.") 184 | message("green", "[+] Sorting for unique urls and adding to list 'blocklist.txt'..") 185 | blocklist() 186 | message("bold", "[+] Done adding to blocklist.") 187 | message("green", "[+] Adding contents of blocklist to pihole.") 188 | add_to_pihole() 189 | message("bold", "[+] Done adding to pihole.") 190 | message("bold", "[+] Finished.") 191 | delete_logs() 192 | --------------------------------------------------------------------------------