Compare commits
1408 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8545eb1df | ||
|
|
76531da340 | ||
|
|
12bec1df68 | ||
|
|
ad61852804 | ||
|
|
dbd8aee4ee | ||
|
|
677694b01a | ||
|
|
85f0241c0d | ||
|
|
ade2185a9f | ||
|
|
0d27005dda | ||
|
|
8ee2bdec4d | ||
|
|
de6ce276d0 | ||
|
|
fbea81dcd7 | ||
|
|
502c349b8b | ||
|
|
5fb0aa70de | ||
|
|
7750e1344c | ||
|
|
8be37130e9 | ||
|
|
fa055481a7 | ||
|
|
d080e5d7a8 | ||
|
|
ad07655630 | ||
|
|
7cceb8615a | ||
|
|
ab9c8f4859 | ||
|
|
ffb8a74111 | ||
|
|
45587194e5 | ||
|
|
ccbf391913 | ||
|
|
7765efa6c4 | ||
|
|
02d4b6794c | ||
|
|
836b717346 | ||
|
|
fc596e41d4 | ||
|
|
1f9b0f7cef | ||
|
|
7bcc15e416 | ||
|
|
1a3bdbaabf | ||
|
|
5e35fdbc52 | ||
|
|
ab2c486f25 | ||
|
|
7fd7430d38 | ||
|
|
089b98430f | ||
|
|
5c7fc05a32 | ||
|
|
ced0d3c2c0 | ||
|
|
1afc5d351d | ||
|
|
09bbc81470 | ||
|
|
f7274addcd | ||
|
|
09bfa2ef77 | ||
|
|
a48518d234 | ||
|
|
a4a9879643 | ||
|
|
d1ccd7a460 | ||
|
|
9181a4a1d8 | ||
|
|
3268e1611a | ||
|
|
ea9ec384c6 | ||
|
|
bbb958b7ed | ||
|
|
cf724176dc | ||
|
|
18d1c98f08 | ||
|
|
d0cd39a25f | ||
|
|
03d4fcd17d | ||
|
|
02d658be65 | ||
|
|
1e627c7e8f | ||
|
|
9170488b0a | ||
|
|
b02730a5ad | ||
|
|
9af26cbaac | ||
|
|
73741f1518 | ||
|
|
9a9cb61345 | ||
|
|
6abd6d8879 | ||
|
|
c3b51b4ceb | ||
|
|
321ea8a3a9 | ||
|
|
4d6263872d | ||
|
|
fcdd58ac94 | ||
|
|
ef8292d371 | ||
|
|
bc6a985f7c | ||
|
|
7320fc11d2 | ||
|
|
51f6d75db4 | ||
|
|
a328326e39 | ||
|
|
4eedf8a746 | ||
|
|
c5f5252145 | ||
|
|
7fadd469c9 | ||
|
|
823e874d20 | ||
|
|
739aaafa9a | ||
|
|
62d001225a | ||
|
|
e50947eb58 | ||
|
|
ca056d32d2 | ||
|
|
63a455f4f7 | ||
|
|
a0e0465036 | ||
|
|
d174a9d015 | ||
|
|
7eb6124721 | ||
|
|
f458780ba7 | ||
|
|
8ad52806de | ||
|
|
dc22a50dcc | ||
|
|
852341c601 | ||
|
|
d5ed6c1901 | ||
|
|
e15548cbf5 | ||
|
|
5e28e6b9ac | ||
|
|
c78d43f640 | ||
|
|
da41383476 | ||
|
|
6ff79835da | ||
|
|
1d608b204a | ||
|
|
c2b8bed3a8 | ||
|
|
3365ef7aaa | ||
|
|
68c17b26dc | ||
|
|
e647efd471 | ||
|
|
15db1ffdd5 | ||
|
|
4632b0f797 | ||
|
|
65c35a5530 | ||
|
|
c449a1c0e0 | ||
|
|
b020010f0d | ||
|
|
0276c72fe2 | ||
|
|
e4aec05d0f | ||
|
|
2919f852ad | ||
|
|
a6e3b9de37 | ||
|
|
04a9791be2 | ||
|
|
cb8df06685 | ||
|
|
bfe5506cc1 | ||
|
|
b64066fec7 | ||
|
|
ffd31d8330 | ||
|
|
d89254fedf | ||
|
|
a771ddf667 | ||
|
|
ce2e410468 | ||
|
|
c1982c04ff | ||
|
|
9a62026830 | ||
|
|
d12efccd0b | ||
|
|
54afffed19 | ||
|
|
fc8fcdbece | ||
|
|
abd1fedc9d | ||
|
|
9725985037 | ||
|
|
754f3359ec | ||
|
|
4c131b8c28 | ||
|
|
15c674ba29 | ||
|
|
00aff6a906 | ||
|
|
c45c3a72b5 | ||
|
|
662d450651 | ||
|
|
a8897becd2 | ||
|
|
d0126f4454 | ||
|
|
fdb64a5702 | ||
|
|
73a80ff7dc | ||
|
|
a795fd698d | ||
|
|
2fb0dc0a4a | ||
|
|
5b4653cf39 | ||
|
|
aa8e1497a3 | ||
|
|
eb13d846ef | ||
|
|
c674a175ee | ||
|
|
afabf30ec6 | ||
|
|
420158494d | ||
|
|
6b7b0e0eb3 | ||
|
|
ad70db7e0e | ||
|
|
ef1ce66793 | ||
|
|
c364fd80b6 | ||
|
|
3bc5d1bae0 | ||
|
|
e4e34acba1 | ||
|
|
ff3c36a7a2 | ||
|
|
1e7e3259b5 | ||
|
|
5e53f484be | ||
|
|
513bc32d87 | ||
|
|
e7c944ff0b | ||
|
|
9355a8ad0e | ||
|
|
a74e48a138 | ||
|
|
ea5ee7b0f9 | ||
|
|
bc8cf1b2d8 | ||
|
|
bb28d94884 | ||
|
|
a4f58b0a22 | ||
|
|
bcf8139708 | ||
|
|
9b0390c9da | ||
|
|
e88f58c34e | ||
|
|
8f402f5c77 | ||
|
|
60054da582 | ||
|
|
4626b8ced5 | ||
|
|
ab7d193f98 | ||
|
|
cbf84c1840 | ||
|
|
420fb69166 | ||
|
|
c9c28cb59a | ||
|
|
9073f34b30 | ||
|
|
fb5578c0d4 | ||
|
|
4244f716e0 | ||
|
|
07a4f970d4 | ||
|
|
2335097c99 | ||
|
|
bef0a2fef0 | ||
|
|
c48e6c91f5 | ||
|
|
f082b5ba54 | ||
|
|
8841bdd252 | ||
|
|
58261098fb | ||
|
|
9432d3035a | ||
|
|
9907fc2770 | ||
|
|
d42caa8672 | ||
|
|
8117ec8e20 | ||
|
|
ff2783f9fc | ||
|
|
156a51c945 | ||
|
|
c72ffae4a2 | ||
|
|
7f3b0030ea | ||
|
|
9a626948f8 | ||
|
|
5c43df66a8 | ||
|
|
d0e3c546f8 | ||
|
|
a9cb93d801 | ||
|
|
ee8f29d178 | ||
|
|
da363070c7 | ||
|
|
50cf891e01 | ||
|
|
715838cf89 | ||
|
|
cd0c3f9418 | ||
|
|
efaee2b68b | ||
|
|
372c699cc6 | ||
|
|
8cb01cdd29 | ||
|
|
7a243f890e | ||
|
|
10982a0f45 | ||
|
|
d4c378ed5d | ||
|
|
7872f68a45 | ||
|
|
ec8c848106 | ||
|
|
3b50ce8c54 | ||
|
|
afabb5957b | ||
|
|
1eeaa01234 | ||
|
|
e2898217d2 | ||
|
|
f81dadc5d0 | ||
|
|
a0019d86c5 | ||
|
|
3c4a9bba78 | ||
|
|
4348653431 | ||
|
|
09cfa9bb20 | ||
|
|
e7713a9028 | ||
|
|
906a1753be | ||
|
|
a3d519b671 | ||
|
|
8591f9d576 | ||
|
|
c10ec5548f | ||
|
|
684ac98c8e | ||
|
|
db89fa9881 | ||
|
|
9a80421d73 | ||
|
|
2ddacf40c0 | ||
|
|
92f4824884 | ||
|
|
9a2ffabc33 | ||
|
|
2977168da1 | ||
|
|
85e3f37503 | ||
|
|
ba015c1918 | ||
|
|
1556adb678 | ||
|
|
6bfe729112 | ||
|
|
c340668870 | ||
|
|
207422f83a | ||
|
|
004ba28378 | ||
|
|
6f38801ed8 | ||
|
|
1509eb7d82 | ||
|
|
b8d2bfc890 | ||
|
|
8a2ee95e4a | ||
|
|
bc91716082 | ||
|
|
a00034a6a7 | ||
|
|
8dc0dc4d69 | ||
|
|
2f4b7ce3dd | ||
|
|
d4f83cb1d4 | ||
|
|
aaab3306a8 | ||
|
|
2bafa2f2ac | ||
|
|
9ac378ae09 | ||
|
|
bf867bd9fd | ||
|
|
7fd9ff43af | ||
|
|
bebb569c43 | ||
|
|
74e33bb1a0 | ||
|
|
b591df55b0 | ||
|
|
bddf31443c | ||
|
|
b9e0e88fe9 | ||
|
|
5120d9ec33 | ||
|
|
0a423ffd40 | ||
|
|
505c9e8979 | ||
|
|
75deb02961 | ||
|
|
480211033d | ||
|
|
c0886cb5c6 | ||
|
|
294df8690c | ||
|
|
5374f652dd | ||
|
|
fb72ac9904 | ||
|
|
b6639d9e7e | ||
|
|
74cb79252c | ||
|
|
6cd3c93472 | ||
|
|
eb63e75379 | ||
|
|
ca9321624c | ||
|
|
40f18df90f | ||
|
|
0d63cfd6c3 | ||
|
|
3d6b22de6c | ||
|
|
fc233fcdd3 | ||
|
|
20370d4348 | ||
|
|
0f90671241 | ||
|
|
a866c4e388 | ||
|
|
e7241a989c | ||
|
|
6e788668f9 | ||
|
|
b246dba7e7 | ||
|
|
f98de3d5db | ||
|
|
fab7d60373 | ||
|
|
b4e5358145 | ||
|
|
486db1e797 | ||
|
|
78cb43d0dc | ||
|
|
870454330d | ||
|
|
509cfd15f2 | ||
|
|
2061daa902 | ||
|
|
629ca970a1 | ||
|
|
c8ad6f23a8 | ||
|
|
d8912fd0a7 | ||
|
|
925c80edd4 | ||
|
|
2f6afd375b | ||
|
|
d92646324c | ||
|
|
c9fe62a691 | ||
|
|
cb52ad3ba3 | ||
|
|
2ec4acfe52 | ||
|
|
1c64f1d0cf | ||
|
|
48f4f44289 | ||
|
|
80c19cbf7d | ||
|
|
c97cfde9f9 | ||
|
|
7b26b308ad | ||
|
|
4c10634d85 | ||
|
|
3ba7d7640f | ||
|
|
907995a221 | ||
|
|
7bf0985a57 | ||
|
|
3ca21d8c8a | ||
|
|
a3a87c8883 | ||
|
|
de4401823e | ||
|
|
3ee10f5983 | ||
|
|
0fc8ac8d4d | ||
|
|
41bb53a29f | ||
|
|
cdee6d55d3 | ||
|
|
e5a1afaa26 | ||
|
|
f50cbe74cb | ||
|
|
5dbbf91917 | ||
|
|
7424a29960 | ||
|
|
eb22ca2467 | ||
|
|
ddbcbe5458 | ||
|
|
6e54cfd2ac | ||
|
|
fc3d4b3def | ||
|
|
df55b2c516 | ||
|
|
4d9fb57e22 | ||
|
|
3ed08b5c39 | ||
|
|
d715471426 | ||
|
|
486a4929da | ||
|
|
aacddb745b | ||
|
|
924f499303 | ||
|
|
e863a200e8 | ||
|
|
bb7f8ae69d | ||
|
|
33b6fe72da | ||
|
|
733919be4a | ||
|
|
4333e5487b | ||
|
|
22ead933b6 | ||
|
|
d53a3af191 | ||
|
|
08e7b7e0ad | ||
|
|
68cb0782c0 | ||
|
|
0e5a8e0033 | ||
|
|
4945f33254 | ||
|
|
3fa05293fc | ||
|
|
27e5f2798d | ||
|
|
291ca0874a | ||
|
|
96f2aa1803 | ||
|
|
c6857501aa | ||
|
|
3aba1607b2 | ||
|
|
f667298b64 | ||
|
|
0f4c8d4923 | ||
|
|
6d2c5b2312 | ||
|
|
a95ce11ca6 | ||
|
|
808503d526 | ||
|
|
d4b6fb9214 | ||
|
|
9bce5a09f3 | ||
|
|
bd61f38169 | ||
|
|
cac9c63325 | ||
|
|
e6d555ac31 | ||
|
|
fd0dd9f54c | ||
|
|
88c161769d | ||
|
|
01bf1ae92d | ||
|
|
9193c71cff | ||
|
|
db278d81e4 | ||
|
|
bdad454a0d | ||
|
|
ac8064c754 | ||
|
|
736e963cef | ||
|
|
b191cd73a7 | ||
|
|
86d3ca48ae | ||
|
|
fd7e4f2268 | ||
|
|
e9475a9739 | ||
|
|
d4270e02e9 | ||
|
|
b9a263ecb2 | ||
|
|
4929d415a6 | ||
|
|
b9e1f518aa | ||
|
|
0caa44e979 | ||
|
|
ca56ca5bd8 | ||
|
|
a0f0dff88e | ||
|
|
e5cc38a210 | ||
|
|
6cb5bb7200 | ||
|
|
563696e291 | ||
|
|
c755b3c49e | ||
|
|
b9f3493dbc | ||
|
|
8c08e9e473 | ||
|
|
c2930b0ca5 | ||
|
|
4300759287 | ||
|
|
fc1854cadd | ||
|
|
933973b12c | ||
|
|
5b54b9cb11 | ||
|
|
d2f815bba7 | ||
|
|
a5a067d50f | ||
|
|
699e299345 | ||
|
|
05e114173d | ||
|
|
d958b3ff65 | ||
|
|
0d7e06a141 | ||
|
|
633095aee1 | ||
|
|
a4aeb9a1dd | ||
|
|
71005e1db3 | ||
|
|
d7d6d6f991 | ||
|
|
5986121cfc | ||
|
|
c452a4569e | ||
|
|
a182a208dc | ||
|
|
d273b4b48b | ||
|
|
afed7d4af0 | ||
|
|
b429e890ad | ||
|
|
2f976504e8 | ||
|
|
b5fc88227b | ||
|
|
4b7b859db9 | ||
|
|
f7d0de53bb | ||
|
|
603ec997ba | ||
|
|
f7266ef4c8 | ||
|
|
3d43e1568c | ||
|
|
3cf6a65da9 | ||
|
|
c1a3f003e8 | ||
|
|
3f61aea7fc | ||
|
|
bd68db51e0 | ||
|
|
b8a5ed710e | ||
|
|
34be601dd7 | ||
|
|
1d64ad1ccd | ||
|
|
dfb4ac0365 | ||
|
|
f2d7a3d26d | ||
|
|
6d415a7384 | ||
|
|
0ef8832b04 | ||
|
|
e42a037b7d | ||
|
|
fe18d69b65 | ||
|
|
a1a9a7fa9e | ||
|
|
07029f93e3 | ||
|
|
e99ef9c093 | ||
|
|
fef9ab674e | ||
|
|
ee37c37cab | ||
|
|
b636c1e1f8 | ||
|
|
8b9f0487c0 | ||
|
|
a6cbd5a2fd | ||
|
|
ece1667fb0 | ||
|
|
50bd8b4a09 | ||
|
|
93d91353a1 | ||
|
|
8dc9143b34 | ||
|
|
a0d9a1133c | ||
|
|
7740e4268c | ||
|
|
f36e4ba336 | ||
|
|
3df2ef8587 | ||
|
|
354309fcad | ||
|
|
e832bfc61e | ||
|
|
99057ed859 | ||
|
|
c47c5e466f | ||
|
|
edd00e8e70 | ||
|
|
82e7de2aaa | ||
|
|
b723714c0c | ||
|
|
a2903b6e63 | ||
|
|
9a1876571b | ||
|
|
c07d7165ab | ||
|
|
d695c5972f | ||
|
|
bbc09ed313 | ||
|
|
1d21b0da9a | ||
|
|
617a147706 | ||
|
|
d4dccfdb2d | ||
|
|
035e4bf727 | ||
|
|
9ec5bbd560 | ||
|
|
34482c5ed6 | ||
|
|
7d414b5628 | ||
|
|
d9528dfd09 | ||
|
|
12f5f8ba00 | ||
|
|
db0f3307e0 | ||
|
|
9c83825cb8 | ||
|
|
7a22471787 | ||
|
|
7548d9a8fe | ||
|
|
26789f9b36 | ||
|
|
b4524839bb | ||
|
|
6605c269cf | ||
|
|
c30478bf4a | ||
|
|
d986746ef9 | ||
|
|
a8fa061f2e | ||
|
|
72015b0226 | ||
|
|
f8e9726922 | ||
|
|
884363bd05 | ||
|
|
bdd240ecb6 | ||
|
|
04da292df9 | ||
|
|
85b8676b8e | ||
|
|
114bc13c23 | ||
|
|
5fef5f1ed4 | ||
|
|
807b60b0e6 | ||
|
|
fbc800e556 | ||
|
|
1991ee7a7d | ||
|
|
ffbfadbccf | ||
|
|
c3e2bce956 | ||
|
|
0c9520d7e3 | ||
|
|
1e7e5230cc | ||
|
|
f1efc97357 | ||
|
|
fb5ac6d6d7 | ||
|
|
4e7ca51beb | ||
|
|
d561600a31 | ||
|
|
024e843998 | ||
|
|
126f275e18 | ||
|
|
c65e5ff8e0 | ||
|
|
ef13e67572 | ||
|
|
7920fcbb5e | ||
|
|
fa36fdeb03 | ||
|
|
c143b5ccb4 | ||
|
|
05c8406fca | ||
|
|
69e3a45083 | ||
|
|
45259b6ec6 | ||
|
|
d6fe48112c | ||
|
|
dcf6e6b14d | ||
|
|
908697a963 | ||
|
|
bdaf961196 | ||
|
|
6bd5d9b1a4 | ||
|
|
beb0dae5a7 | ||
|
|
fad2d6b1d1 | ||
|
|
9cd830b6aa | ||
|
|
d9a16b0ff4 | ||
|
|
cb5c94ef5e | ||
|
|
85fbd66871 | ||
|
|
3da75d6125 | ||
|
|
d4a3a5c180 | ||
|
|
65e0fcbf10 | ||
|
|
e22aca49c8 | ||
|
|
71e3a473d6 | ||
|
|
c2cfc09f63 | ||
|
|
cbfad28f7e | ||
|
|
6a4a468022 | ||
|
|
01f10b56e8 | ||
|
|
90ec0a610e | ||
|
|
42bff1ce1b | ||
|
|
e3c7a1f31f | ||
|
|
0debbffa70 | ||
|
|
473b58d26d | ||
|
|
7e9498f04c | ||
|
|
300001e766 | ||
|
|
21fc6344bf | ||
|
|
a38edd891f | ||
|
|
794fa21137 | ||
|
|
977d1d1998 | ||
|
|
cde003bc98 | ||
|
|
9e4e1d1cb2 | ||
|
|
60142cd960 | ||
|
|
f9570a82cc | ||
|
|
36285ead57 | ||
|
|
13e488dace | ||
|
|
f169da8fd0 | ||
|
|
60741298b7 | ||
|
|
f73734acb0 | ||
|
|
fc360abe43 | ||
|
|
3996e11425 | ||
|
|
3a4fe3e391 | ||
|
|
98db002770 | ||
|
|
7c89b6934a | ||
|
|
380a19274d | ||
|
|
f1c1caf7bd | ||
|
|
e2997b8135 | ||
|
|
4ed6e4d016 | ||
|
|
ac8d24a1ce | ||
|
|
fc776921d5 | ||
|
|
55a653aca4 | ||
|
|
0d6a6b97f9 | ||
|
|
469ff45f01 | ||
|
|
bc077acfb8 | ||
|
|
4269626f5d | ||
|
|
8fa897aadb | ||
|
|
f549618d12 | ||
|
|
2fa47aaf31 | ||
|
|
b0874fb23a | ||
|
|
fb70fd77e8 | ||
|
|
01f17f9cbb | ||
|
|
4c853defb2 | ||
|
|
bd0db56ba0 | ||
|
|
95f0b3710d | ||
|
|
e0ac109dd1 | ||
|
|
86349527e7 | ||
|
|
18005ceee8 | ||
|
|
7653b3d088 | ||
|
|
911053f63f | ||
|
|
eb52f81a5c | ||
|
|
4839953328 | ||
|
|
aba0d93fda | ||
|
|
0de74c0448 | ||
|
|
ee927346b7 | ||
|
|
2f8015cbca | ||
|
|
f3bf7c4b38 | ||
|
|
e37c4d57da | ||
|
|
acff90c000 | ||
|
|
5f9e72dd71 | ||
|
|
be0bcb8f7d | ||
|
|
44c3d56439 | ||
|
|
519d731ddd | ||
|
|
119c00c22a | ||
|
|
12596dd697 | ||
|
|
cb38f5f0d7 | ||
|
|
b49384ffe4 | ||
|
|
7fb622638b | ||
|
|
bd0cc134bf | ||
|
|
476fd1f695 | ||
|
|
96053d13be | ||
|
|
c958bed418 | ||
|
|
2b2c240d39 | ||
|
|
1f0ae16216 | ||
|
|
b79392ba2c | ||
|
|
8ee98f0a4a | ||
|
|
82e78fb651 | ||
|
|
d0826b2c33 | ||
|
|
ff588200c0 | ||
|
|
5d6072524c | ||
|
|
07a66a70fc | ||
|
|
69ba8a3c2f | ||
|
|
a30c75ef71 | ||
|
|
d0b3727c5d | ||
|
|
6e94bf5b6d | ||
|
|
0f04e270a7 | ||
|
|
ec4f5007e7 | ||
|
|
21b906e0e0 | ||
|
|
7ebaf8e843 | ||
|
|
640398ced4 | ||
|
|
ebbe1fc236 | ||
|
|
aac8e45397 | ||
|
|
5ebfa5ecf7 | ||
|
|
12e041c9ef | ||
|
|
54913f06a3 | ||
|
|
44a36368a2 | ||
|
|
8f9ff930b3 | ||
|
|
e199f6db87 | ||
|
|
c83dd3ccd7 | ||
|
|
78fbafa1cd | ||
|
|
c0012540ed | ||
|
|
9ab6df0e54 | ||
|
|
685b775b68 | ||
|
|
9056a5a7b6 | ||
|
|
e1c56bcbfe | ||
|
|
15d68467a1 | ||
|
|
3b6ecc573e | ||
|
|
9427b1e594 | ||
|
|
3ca3eaa62c | ||
|
|
dda448e050 | ||
|
|
60873144ea | ||
|
|
a9d17c96be | ||
|
|
aaee895b2b | ||
|
|
7d7e17b351 | ||
|
|
c71a976e76 | ||
|
|
3623183072 | ||
|
|
e6bd979aeb | ||
|
|
266c160108 | ||
|
|
b5b6350cc7 | ||
|
|
bbcf4800de | ||
|
|
41056ace02 | ||
|
|
60a80dd678 | ||
|
|
0efda04920 | ||
|
|
8819e58882 | ||
|
|
28eeaf201b | ||
|
|
74bfcea6a8 | ||
|
|
16f1d7fad9 | ||
|
|
9aa38cf0ae | ||
|
|
a7fa7466fb | ||
|
|
3f73c61cee | ||
|
|
a64f4cd871 | ||
|
|
a41eff1276 | ||
|
|
b88fe572fe | ||
|
|
59ba6f8aec | ||
|
|
25343da6b7 | ||
|
|
60d17b97f5 | ||
|
|
8cb72d87e4 | ||
|
|
8872594ab9 | ||
|
|
b50584119b | ||
|
|
975f4f2a17 | ||
|
|
16e4f79f09 | ||
|
|
76cae20c33 | ||
|
|
b66f23cfd0 | ||
|
|
27d6e5d8cf | ||
|
|
ff5d5b97c3 | ||
|
|
ce46c4dec4 | ||
|
|
77e8be09a1 | ||
|
|
013d77488a | ||
|
|
29ad2496b6 | ||
|
|
97a013b2b7 | ||
|
|
77808223dc | ||
|
|
fc89851ce9 | ||
|
|
c4c6555814 | ||
|
|
df0087fb23 | ||
|
|
ef3c13fe2b | ||
|
|
0ad704e532 | ||
|
|
2220d2dab8 | ||
|
|
49f48e2aaa | ||
|
|
dce24df379 | ||
|
|
b59136c262 | ||
|
|
fb9664b636 | ||
|
|
5b736ae05e | ||
|
|
ee114b3075 | ||
|
|
123b16991b | ||
|
|
5792fc0bef | ||
|
|
42c93917ef | ||
|
|
8c0f860601 | ||
|
|
df30a4c0d1 | ||
|
|
9ce13f0035 | ||
|
|
3884b01503 | ||
|
|
a84c3adeab | ||
|
|
a65b784907 | ||
|
|
05dadad2e1 | ||
|
|
3a9b39b842 | ||
|
|
e612003293 | ||
|
|
a43577fa26 | ||
|
|
7e10dcdcf0 | ||
|
|
7ee1110351 | ||
|
|
51c4c51d9e | ||
|
|
fc4fe54099 | ||
|
|
b5b240d0be | ||
|
|
4c42f00a86 | ||
|
|
090fbd04af | ||
|
|
461de48625 | ||
|
|
9352ba6e4a | ||
|
|
5e883239f9 | ||
|
|
5ea08a2120 | ||
|
|
a6fa60868b | ||
|
|
99878ae7d6 | ||
|
|
26202014a2 | ||
|
|
f4f8b96788 | ||
|
|
e5ede16749 | ||
|
|
fbe3547129 | ||
|
|
23f7363c70 | ||
|
|
97c44042e1 | ||
|
|
a03caea549 | ||
|
|
aa23fb1d56 | ||
|
|
4f35aac6dd | ||
|
|
4418ca9e9f | ||
|
|
570611fc09 | ||
|
|
94dd5b1ebe | ||
|
|
74524e024d | ||
|
|
324e00194f | ||
|
|
e42b6dcc8e | ||
|
|
d71b799e75 | ||
|
|
87e7121332 | ||
|
|
94f6354c94 | ||
|
|
b79059ebdb | ||
|
|
07b7e8a1a6 | ||
|
|
7ae2fc37c0 | ||
|
|
4f98c1bebb | ||
|
|
2feec01e10 | ||
|
|
72b95e192e | ||
|
|
47aad254d8 | ||
|
|
bc14074d2a | ||
|
|
5ab5b1a190 | ||
|
|
b055f190f5 | ||
|
|
84b8953352 | ||
|
|
93a591d487 | ||
|
|
e6c0f38a7c | ||
|
|
d169305e5d | ||
|
|
f107ae4f9b | ||
|
|
bad7a08804 | ||
|
|
25cbf4cb35 | ||
|
|
7f179f9a58 | ||
|
|
5287ea8537 | ||
|
|
43e2aaebf0 | ||
|
|
e60eb66283 | ||
|
|
ca59b808d8 | ||
|
|
8a15fd44d5 | ||
|
|
dac2b8942e | ||
|
|
54a1c5b63a | ||
|
|
61b02bf6d3 | ||
|
|
9d048b2fdf | ||
|
|
d9e28a7422 | ||
|
|
1fecdf42ca | ||
|
|
d4bf85b67c | ||
|
|
7131ff27c3 | ||
|
|
a30f78c1c8 | ||
|
|
7e0afffca8 | ||
|
|
293c60fb9c | ||
|
|
f5be8b2a5e | ||
|
|
6772603c15 | ||
|
|
a22904f99b | ||
|
|
6710d2852f | ||
|
|
b157bc5cd7 | ||
|
|
10e1a03c76 | ||
|
|
d20df92e9f | ||
|
|
44170207ac | ||
|
|
9354799a26 | ||
|
|
33745be745 | ||
|
|
6a28070017 | ||
|
|
91b948332e | ||
|
|
d1a7fe2d44 | ||
|
|
8224ef20a4 | ||
|
|
a4c3464bc8 | ||
|
|
5966d76e9a | ||
|
|
c39324d11f | ||
|
|
8c151c62ce | ||
|
|
50d16d8215 | ||
|
|
3bbac9a5f2 | ||
|
|
3600fd277e | ||
|
|
e8bb4a7e36 | ||
|
|
36987cb1cc | ||
|
|
5382b4fa37 | ||
|
|
28ef8068c8 | ||
|
|
ca0cbd68d6 | ||
|
|
c281b47905 | ||
|
|
aca5064743 | ||
|
|
6f780316c4 | ||
|
|
4e262d81f0 | ||
|
|
6c2ff950ee | ||
|
|
7684069d0b | ||
|
|
73c85ae68a | ||
|
|
911e39ba09 | ||
|
|
9a421d510a | ||
|
|
3bc7172e5e | ||
|
|
1a83988e26 | ||
|
|
0d0fc2504a | ||
|
|
0d4402ee0c | ||
|
|
722def9362 | ||
|
|
6a8bef83b3 | ||
|
|
a9c3e2c7ba | ||
|
|
7fcb40739d | ||
|
|
5a3d319677 | ||
|
|
8466d0b681 | ||
|
|
5de179f1eb | ||
|
|
36e10595cc | ||
|
|
78c8723629 | ||
|
|
edd7f28104 | ||
|
|
dba1ab3fc0 | ||
|
|
3df9c48012 | ||
|
|
6f6450bcff | ||
|
|
1f34203167 | ||
|
|
fed20648c6 | ||
|
|
3fc3c5cae4 | ||
|
|
daa5366b57 | ||
|
|
ac1c299369 | ||
|
|
5bbb3ac49a | ||
|
|
014bdf911a | ||
|
|
874853fe18 | ||
|
|
274b71f8bc | ||
|
|
c41d543d81 | ||
|
|
7729ddab30 | ||
|
|
60c0e59a83 | ||
|
|
ac49e639bd | ||
|
|
f01b20c2af | ||
|
|
a0d47be088 | ||
|
|
521374e238 | ||
|
|
34806ee2c2 | ||
|
|
4a0d5138a1 | ||
|
|
e6a3758899 | ||
|
|
fcb7d9111e | ||
|
|
d907731027 | ||
|
|
ac8d295bb9 | ||
|
|
a963beb96e | ||
|
|
737b510116 | ||
|
|
47cba83450 | ||
|
|
21d4199a38 | ||
|
|
655c422c3c | ||
|
|
b6f8bd408f | ||
|
|
a3edd0b976 | ||
|
|
8e8efa5caf | ||
|
|
a41b8f62a2 | ||
|
|
452ee8c2df | ||
|
|
5ca6599ca9 | ||
|
|
dcedf6bfd0 | ||
|
|
1f4b43645b | ||
|
|
3d5140458b | ||
|
|
f16574085f | ||
|
|
3ed62d45f5 | ||
|
|
b1a7b0a186 | ||
|
|
ec0c68621c | ||
|
|
a0977af081 | ||
|
|
a3ef9efd2f | ||
|
|
d58f7c6ec9 | ||
|
|
d124c2c12e | ||
|
|
0229f70761 | ||
|
|
dde9281139 | ||
|
|
6eedfb572e | ||
|
|
edf81a232d | ||
|
|
c2cb92a0b0 | ||
|
|
640af300cb | ||
|
|
6c0c6182e9 | ||
|
|
05ad4445b5 | ||
|
|
1dd9f0747e | ||
|
|
150e01be8b | ||
|
|
95ee3216c4 | ||
|
|
3b5e409b38 | ||
|
|
eb201b614a | ||
|
|
162a6b8b5c | ||
|
|
4ec01769cb | ||
|
|
19b656132d | ||
|
|
6305c7e2ab | ||
|
|
04c60e8a1c | ||
|
|
b6ceb06a32 | ||
|
|
8cb2f85a08 | ||
|
|
7ccfb6ea88 | ||
|
|
531398b532 | ||
|
|
ec6ecf0d60 | ||
|
|
fdb0e31a78 | ||
|
|
01a9534729 | ||
|
|
921278c5ea | ||
|
|
d938f73207 | ||
|
|
344e63c2dc | ||
|
|
681144b2a3 | ||
|
|
e4295f5d3c | ||
|
|
77135ca3c7 | ||
|
|
29b548f07c | ||
|
|
cb33ef77f7 | ||
|
|
49ded54306 | ||
|
|
6c0a8a4337 | ||
|
|
e9a0ddf798 | ||
|
|
d217626318 | ||
|
|
4f5fcc2a37 | ||
|
|
ed94f4b1df | ||
|
|
a57b097afc | ||
|
|
eb42b894c4 | ||
|
|
af666e2209 | ||
|
|
2f2e746e56 | ||
|
|
b3e7619048 | ||
|
|
0121136498 | ||
|
|
7eb43a0b47 | ||
|
|
c0430a2248 | ||
|
|
6796b8bdad | ||
|
|
475d016029 | ||
|
|
201304e678 | ||
|
|
fdb104348c | ||
|
|
f54828352d | ||
|
|
cc157def63 | ||
|
|
8fc83655ab | ||
|
|
9fb549293a | ||
|
|
e4cc5b5b70 | ||
|
|
6f0b659b38 | ||
|
|
652bdf1518 | ||
|
|
f6ac0d73b4 | ||
|
|
ae47be0ce9 | ||
|
|
491c37eafe | ||
|
|
3ade7a8b0e | ||
|
|
3c7738b6d0 | ||
|
|
037318e2ff | ||
|
|
a9a499939e | ||
|
|
7e5bcd2ec3 | ||
|
|
f49ca48a22 | ||
|
|
9cb4e8bde8 | ||
|
|
95edb49bb8 | ||
|
|
fb69bf551e | ||
|
|
fe8d0f8ea8 | ||
|
|
acc5fa2a95 | ||
|
|
f2e33f8581 | ||
|
|
4748cdc2c9 | ||
|
|
2bc364023a | ||
|
|
3070f61e20 | ||
|
|
57df56dc62 | ||
|
|
e11ef5a7f0 | ||
|
|
6a17a3eeec | ||
|
|
66ff9a24c6 | ||
|
|
a3b3a7a34d | ||
|
|
c04b3559d0 | ||
|
|
e642b41b5b | ||
|
|
ba6881d685 | ||
|
|
20d8c9053b | ||
|
|
0749e4ed70 | ||
|
|
b0cc69ff80 | ||
|
|
02c4669e95 | ||
|
|
8550b76e23 | ||
|
|
fdf27e3d24 | ||
|
|
069023fca2 | ||
|
|
1fd6648db1 | ||
|
|
7a08c8b694 | ||
|
|
60aad3f19b | ||
|
|
51dcc2bc0f | ||
|
|
941525d1e0 | ||
|
|
5fb6c5b012 | ||
|
|
3affa73257 | ||
|
|
c647e27e15 | ||
|
|
f696ed48b3 | ||
|
|
73645f299a | ||
|
|
6aeb5f1172 | ||
|
|
ce8f07750f | ||
|
|
a32ad0dbf2 | ||
|
|
61ff12e8d4 | ||
|
|
02b0e96db8 | ||
|
|
e942440bb7 | ||
|
|
a27f1f17de | ||
|
|
e106ff0fef | ||
|
|
6f068e0b9c | ||
|
|
ada531c88a | ||
|
|
f0a2248c81 | ||
|
|
11f2524b9b | ||
|
|
b011e5f838 | ||
|
|
f45eb84d6b | ||
|
|
412c0a172d | ||
|
|
c1d8496b93 | ||
|
|
4657959790 | ||
|
|
2b0ba281a4 | ||
|
|
325a41c598 | ||
|
|
9b8efe1b27 | ||
|
|
024b741552 | ||
|
|
4e95f4678f | ||
|
|
a86b982591 | ||
|
|
ec8da00485 | ||
|
|
bcfe130d51 | ||
|
|
0e143f7275 | ||
|
|
7670b4e380 | ||
|
|
636a9123b8 | ||
|
|
caaee40889 | ||
|
|
1f130b6550 | ||
|
|
2ce47f49b1 | ||
|
|
0250e03b86 | ||
|
|
ce110aab90 | ||
|
|
fd92752f52 | ||
|
|
3c4a305976 | ||
|
|
791e5bbd55 | ||
|
|
46df6e7dd3 | ||
|
|
9ccf9d57a8 | ||
|
|
fa89bd830a | ||
|
|
3ba05d0274 | ||
|
|
0d9a8d70bf | ||
|
|
5c79184d3b | ||
|
|
3d619d9ccc | ||
|
|
afdf3ae7a1 | ||
|
|
943f7c06b5 | ||
|
|
27a9642090 | ||
|
|
d0b6ff2d08 | ||
|
|
97737ee9e3 | ||
|
|
5e27ccc37c | ||
|
|
682113892a | ||
|
|
376eb81181 | ||
|
|
4fc40d96d9 | ||
|
|
e6634531c7 | ||
|
|
66724826f5 | ||
|
|
04e375a523 | ||
|
|
65638973ea | ||
|
|
9c26bdd676 | ||
|
|
b31931c907 | ||
|
|
c74af2c21f | ||
|
|
c160b2e54b | ||
|
|
c4234f4542 | ||
|
|
62fa9c0f6e | ||
|
|
8198f06073 | ||
|
|
6f2117d786 | ||
|
|
b3ec3b487c | ||
|
|
d67957d015 | ||
|
|
94f131a0b7 | ||
|
|
7af0029175 | ||
|
|
f4228b04f8 | ||
|
|
ffaf243160 | ||
|
|
29d48bbd9a | ||
|
|
37dda79db2 | ||
|
|
063e3e85e1 | ||
|
|
42afaa9f66 | ||
|
|
366fcf76f6 | ||
|
|
72e8ec7d93 | ||
|
|
13a479a9f6 | ||
|
|
1194e48bd8 | ||
|
|
1e0666d1ef | ||
|
|
1c53ad6876 | ||
|
|
dc2a537f6b | ||
|
|
a5d3022e9f | ||
|
|
4541da1f17 | ||
|
|
a16cd9aef7 | ||
|
|
6cf446032f | ||
|
|
3fda2d9ac3 | ||
|
|
c03268707a | ||
|
|
7829e907c9 | ||
|
|
b5529e5138 | ||
|
|
d601afcebc | ||
|
|
892a90bf51 | ||
|
|
d52a8f08ed | ||
|
|
b7e27bf6b4 | ||
|
|
9ee96d6176 | ||
|
|
c0e1772e21 | ||
|
|
62dc160c65 | ||
|
|
f03303e5aa | ||
|
|
7bc2844b9d | ||
|
|
ba283755be | ||
|
|
2209beff8a | ||
|
|
00cc480bc1 | ||
|
|
d7de5b2afa | ||
|
|
221b72439b | ||
|
|
08e6f60941 | ||
|
|
10066209e7 | ||
|
|
08e95ed606 | ||
|
|
a5ad48aa18 | ||
|
|
81fdfcba22 | ||
|
|
24de6d6fc9 | ||
|
|
aec6fcd00b | ||
|
|
619082dbed | ||
|
|
09cdf5081c | ||
|
|
d7abbbfac4 | ||
|
|
c714196647 | ||
|
|
b702c1d9a8 | ||
|
|
56ac04c48e | ||
|
|
b58519b974 | ||
|
|
ad574f5e90 | ||
|
|
4941a657bf | ||
|
|
3d4bff9414 | ||
|
|
2d03616c10 | ||
|
|
fcb9ba08a8 | ||
|
|
77f4126f9b | ||
|
|
4c890ab202 | ||
|
|
d10e9b1b6e | ||
|
|
a6bee76581 | ||
|
|
2f4f5a6ad2 | ||
|
|
3853997295 | ||
|
|
76899c9ac5 | ||
|
|
99a5b3a98a | ||
|
|
219aff9a93 | ||
|
|
b6e1b3bff0 | ||
|
|
1ce888e828 | ||
|
|
1c10a801dc | ||
|
|
48fa83c9ac | ||
|
|
31ea3a2757 | ||
|
|
05e0003555 | ||
|
|
be79281418 | ||
|
|
01f53f6d6c | ||
|
|
107e0404de | ||
|
|
ab99e80333 | ||
|
|
3154a378a6 | ||
|
|
8e04f1c03e | ||
|
|
c0aadeab3d | ||
|
|
6c87698f1a | ||
|
|
db2e9f8bf3 | ||
|
|
9a4c5cef86 | ||
|
|
bdfc86f850 | ||
|
|
70dadfba28 | ||
|
|
01e1e34874 | ||
|
|
28a3cbfa87 | ||
|
|
0b480c2d3f | ||
|
|
391dea445a | ||
|
|
e074c72130 | ||
|
|
96f3f863e5 | ||
|
|
3877f6fd94 | ||
|
|
cbbc6df05a | ||
|
|
32ff7fb321 | ||
|
|
5537e57eec | ||
|
|
9c94af04cc | ||
|
|
3f0b15902d | ||
|
|
4d3835dde2 | ||
|
|
8514f42d0d | ||
|
|
6d9fbe8d41 | ||
|
|
849185d3c9 | ||
|
|
47cc757ed0 | ||
|
|
f6edd435af | ||
|
|
0c0dd914f7 | ||
|
|
c6405bc93b | ||
|
|
cdffdfbded | ||
|
|
0bbfb323b1 | ||
|
|
4f08359786 | ||
|
|
7efb17537a | ||
|
|
7e06769d44 | ||
|
|
5347ee4896 | ||
|
|
834bf30a10 | ||
|
|
22ea384ac8 | ||
|
|
3e6dd9ea9e | ||
|
|
10f363e9e7 | ||
|
|
69e8c014c3 | ||
|
|
dbb40e1dda | ||
|
|
d710b97276 | ||
|
|
0e6e8040ba | ||
|
|
c6fb0bad4b | ||
|
|
2d08217173 | ||
|
|
36645d9335 | ||
|
|
97d3aedba1 | ||
|
|
5976b20aec | ||
|
|
ad8573c739 | ||
|
|
7f9410fd34 | ||
|
|
71133f6b59 | ||
|
|
5d5d6c2c70 | ||
|
|
37fa462db5 | ||
|
|
1a2046a7eb | ||
|
|
3dff7e80fc | ||
|
|
6eea9239a7 | ||
|
|
75f1969bd2 | ||
|
|
e97755eb91 | ||
|
|
b938949cdb | ||
|
|
447af208b3 | ||
|
|
d47fbbbe96 | ||
|
|
767b72fbfa | ||
|
|
b94a8da9d6 | ||
|
|
12b5be239b | ||
|
|
0fbf72bb09 | ||
|
|
ae2117ff5a | ||
|
|
b80821c4b7 | ||
|
|
cf01b5a002 | ||
|
|
bb66d559e7 | ||
|
|
7b8fa3b922 | ||
|
|
777676b525 | ||
|
|
28f2a1309e | ||
|
|
4b0a7c2252 | ||
|
|
2625d9f7fe | ||
|
|
45f24c8a85 | ||
|
|
5f7c11f495 | ||
|
|
ec4d2d65a6 | ||
|
|
3e20f5dd3c | ||
|
|
7014b5a150 | ||
|
|
f8427ab789 | ||
|
|
31fc2bfeb7 | ||
|
|
fb5bc16c83 | ||
|
|
724075e448 | ||
|
|
45cb9a2e80 | ||
|
|
456eee05f2 | ||
|
|
23872f77a8 | ||
|
|
37c1999965 | ||
|
|
86dd4dd784 | ||
|
|
00b65abd09 | ||
|
|
fee55fa642 | ||
|
|
76ea1962be | ||
|
|
df3cf72d29 | ||
|
|
32dd594f06 | ||
|
|
ba0ba1de94 | ||
|
|
660e71f032 | ||
|
|
169e6fdba4 | ||
|
|
138aeaf8c7 | ||
|
|
33669793b7 | ||
|
|
80f4bf9475 | ||
|
|
bed869b08e | ||
|
|
f2150ee7e1 | ||
|
|
eaf89995ee | ||
|
|
2311b42bca | ||
|
|
a4fbccac9b | ||
|
|
a0cf93a7ca | ||
|
|
f444c7d4a5 | ||
|
|
8ef4c12f97 | ||
|
|
c520c55ff4 | ||
|
|
6145748bfb | ||
|
|
1a1026b367 | ||
|
|
8c45bd32b7 | ||
|
|
2b5cee05e6 | ||
|
|
5442954db6 | ||
|
|
5ee382c8eb | ||
|
|
901cb44f5e | ||
|
|
7388461ede | ||
|
|
5223627b71 | ||
|
|
646c4a3ccc | ||
|
|
0b9e78df2c | ||
|
|
a9c24b456d | ||
|
|
b4463bf42c | ||
|
|
8f8dc66c70 | ||
|
|
b746250e71 | ||
|
|
26b7e7ec8e | ||
|
|
bc09760c84 | ||
|
|
ceb229c6ac | ||
|
|
1e6ac33ef1 | ||
|
|
86eafe7a33 | ||
|
|
00f46dc149 | ||
|
|
396c7ab9ee | ||
|
|
fa2cef6395 | ||
|
|
04638c9065 | ||
|
|
02bb5b6742 | ||
|
|
fad5fafa32 | ||
|
|
b0dd231018 | ||
|
|
0b5f005a5d | ||
|
|
babca8d47b | ||
|
|
eb462955fe | ||
|
|
b79db36336 | ||
|
|
404ea0ce6d | ||
|
|
d3971b26e4 | ||
|
|
a44a201f00 | ||
|
|
1d80fdddd4 | ||
|
|
f09745b4ad | ||
|
|
d13ae0610e | ||
|
|
3eaa447323 | ||
|
|
604506da10 | ||
|
|
122ce11381 | ||
|
|
8cbd9f7f08 | ||
|
|
7c41e5bafc | ||
|
|
4452f784a8 | ||
|
|
ced0ae0d65 | ||
|
|
876c51302a | ||
|
|
a6877e7c13 | ||
|
|
f633d1fa5b | ||
|
|
4f90b41343 | ||
|
|
e4ddf8bc33 | ||
|
|
613ab9febc | ||
|
|
e92cceecc1 | ||
|
|
3283f3ed7d | ||
|
|
0ed30b802d | ||
|
|
beefff8cce | ||
|
|
b1554d6a89 | ||
|
|
4230b03884 | ||
|
|
2182b8339e | ||
|
|
b07b77c58f | ||
|
|
6542407fa3 | ||
|
|
ebf995536b | ||
|
|
adcd7f10ee | ||
|
|
af83936047 | ||
|
|
c3b5b97a41 | ||
|
|
6c58ea18dc | ||
|
|
830b287e5d | ||
|
|
52549d51ab | ||
|
|
fe05ed13e5 | ||
|
|
3a46e7fc0a | ||
|
|
88674e21cf | ||
|
|
a0673c7028 | ||
|
|
592af80659 | ||
|
|
3ec9b3b021 | ||
|
|
ca2d3a192c | ||
|
|
209bf7d746 | ||
|
|
13777cc1aa | ||
|
|
bffc77e478 | ||
|
|
0ebb7eecdb | ||
|
|
99863bb799 | ||
|
|
800d2f0859 | ||
|
|
f397844603 | ||
|
|
2d895f328c | ||
|
|
b14b182084 | ||
|
|
8687d25d88 | ||
|
|
7001edcd1d | ||
|
|
4a1e88f4bf | ||
|
|
b41608d40b | ||
|
|
c5d45edf2d | ||
|
|
0116b6341c | ||
|
|
3e7ecda80f | ||
|
|
f0e5b2b6f9 | ||
|
|
5976ec9323 | ||
|
|
eb3463fad1 | ||
|
|
5f9e5869e9 | ||
|
|
950480bb77 | ||
|
|
6530ec58c7 | ||
|
|
b1515c5e3f | ||
|
|
6581f119fd | ||
|
|
9ad7c12710 | ||
|
|
8e289215b4 | ||
|
|
3718c3be56 | ||
|
|
c3c051385c | ||
|
|
21c688a8a8 | ||
|
|
668b883651 | ||
|
|
c396aeed52 | ||
|
|
40f541bc31 | ||
|
|
44974f98a0 | ||
|
|
b7cb3df9bc | ||
|
|
432e6d5395 | ||
|
|
fdf805bc7b | ||
|
|
73e13f3875 | ||
|
|
da959e1296 | ||
|
|
94600c54cb | ||
|
|
c4fc2e089d | ||
|
|
06444c1c27 | ||
|
|
f8897942f3 | ||
|
|
4d0b4cfb36 | ||
|
|
7116634739 | ||
|
|
36492f4857 | ||
|
|
3a887af513 | ||
|
|
3142992c57 | ||
|
|
68a9b88b58 | ||
|
|
3c801e5b91 | ||
|
|
ecd46f8560 | ||
|
|
dee8ce587d | ||
|
|
4c24186911 | ||
|
|
af360a1a20 | ||
|
|
b5406240c6 | ||
|
|
73bfbba5f7 | ||
|
|
46d7bfecdb | ||
|
|
a734927591 | ||
|
|
255706e173 | ||
|
|
b2fbf46e60 | ||
|
|
e37495d80b | ||
|
|
beb6b950f7 | ||
|
|
2d1c0be24e | ||
|
|
9941651b3c | ||
|
|
31fda124f3 | ||
|
|
b7f6498a5c | ||
|
|
282da1c2b6 | ||
|
|
8e6ec6ef0c | ||
|
|
704b3ee673 | ||
|
|
c18a1c3eca | ||
|
|
4e1870197e | ||
|
|
3bf61cce95 | ||
|
|
68889b0544 | ||
|
|
8a90a47fc2 | ||
|
|
c93c4cc5e6 | ||
|
|
06cba7defd | ||
|
|
8b76bbe51d | ||
|
|
aa1d3a4c2e | ||
|
|
66817411f9 | ||
|
|
23c3196935 | ||
|
|
38e73a188a | ||
|
|
3fdf588cc9 | ||
|
|
9412fe8a0a | ||
|
|
c6450e60e1 | ||
|
|
8126e9f4b1 | ||
|
|
70e4104c17 | ||
|
|
29e0e1760b | ||
|
|
442b7b4c4d | ||
|
|
548153fd5e | ||
|
|
5060ed8970 | ||
|
|
d18e064d21 | ||
|
|
0cfb3c7ab4 | ||
|
|
2e0c2f2e77 | ||
|
|
48f9a61ff0 | ||
|
|
0042e3ae02 | ||
|
|
a1204cf246 | ||
|
|
fc499d9e7c | ||
|
|
b83704dac2 | ||
|
|
b93e46de14 | ||
|
|
3c49aa9d9d | ||
|
|
a448b48eaf | ||
|
|
3c6551f202 | ||
|
|
9e0c7ed29a | ||
|
|
677293f3a9 | ||
|
|
34bd7ce3a7 | ||
|
|
21a07e7419 | ||
|
|
6b50ea6504 | ||
|
|
895647b908 | ||
|
|
0ece58b9cb | ||
|
|
49a56cf131 | ||
|
|
5fa0d798e2 | ||
|
|
cadc506aa5 | ||
|
|
eee0ccef8c | ||
|
|
088bd632ab | ||
|
|
52b5d7143b | ||
|
|
60bf14d4dd | ||
|
|
c00fb44cee | ||
|
|
5111880edf | ||
|
|
3d78b44a8e | ||
|
|
f2d71d41a8 | ||
|
|
b75b290351 | ||
|
|
701ae06e4a | ||
|
|
edd0b809b7 | ||
|
|
98a0d17431 | ||
|
|
b1bd56cd51 | ||
|
|
ae336da7a1 | ||
|
|
4a61b80dd6 | ||
|
|
ef99fe2d18 | ||
|
|
352ebc3193 | ||
|
|
556799428c | ||
|
|
d74c8261aa | ||
|
|
ac373545d0 | ||
|
|
a21948d2c6 | ||
|
|
940480effe | ||
|
|
29c593b8b0 | ||
|
|
0c444e6f2b | ||
|
|
6cf6e16d22 | ||
|
|
abef758ff6 | ||
|
|
e5f9663a0e | ||
|
|
ff5ed561cc | ||
|
|
71fd32b1f4 | ||
|
|
fcf3b4e4e2 |
38
.gitattributes
vendored
Normal file
38
.gitattributes
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# FROM https://github.com/libgit2/libgit2sharp
|
||||||
|
# Text files that should be normalized to LF in odb.
|
||||||
|
*.cs text diff=csharp
|
||||||
|
*.config text
|
||||||
|
|
||||||
|
*.sln text
|
||||||
|
*.csproj text
|
||||||
|
|
||||||
|
*.md text
|
||||||
|
*.sh text
|
||||||
|
*.ps1 text
|
||||||
|
*.cmd text
|
||||||
|
*.bat text
|
||||||
|
*.markdown text
|
||||||
|
*.msbuild text
|
||||||
|
|
||||||
|
Lib/* binary
|
||||||
|
GitHub.Tests.Integration/Resources/* binary
|
||||||
|
|
||||||
|
|
||||||
|
# Binary files that should not be normalized or diffed
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.gif binary
|
||||||
|
|
||||||
|
*.pfx binary
|
||||||
|
*.snk binary
|
||||||
|
*.dll binary
|
||||||
|
*.exe binary
|
||||||
|
*.lib binary
|
||||||
|
*.exp binary
|
||||||
|
*.pdb binary
|
||||||
|
*.sdf binary
|
||||||
|
*.7z binary
|
||||||
|
|
||||||
|
|
||||||
|
# Catch all for anything we forgot. Add rules if you get CRLF -> LF warnings.
|
||||||
|
* text=auto
|
||||||
33
.github/ISSUE_TEMPLATE.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
**In raising this issue, I confirm the following (please check boxes, eg [X]) Failure to fill the template will close your issue:**
|
||||||
|
|
||||||
|
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
|
||||||
|
- [] The issue I am reporting can be *replicated*
|
||||||
|
- [] The issue I'm reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)).
|
||||||
|
|
||||||
|
**How familiar are you with the codebase?:**
|
||||||
|
|
||||||
|
_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
|
||||||
|
|
||||||
|
---
|
||||||
|
**[FEATURE REQUEST | QUESTION | OTHER]:**
|
||||||
|
|
||||||
|
Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track.
|
||||||
|
|
||||||
|
**[BUG | ISSUE] Expected Behaviour:**
|
||||||
|
|
||||||
|
|
||||||
|
**[BUG | ISSUE] Actual Behaviour:**
|
||||||
|
|
||||||
|
|
||||||
|
**[BUG | ISSUE] Steps to reproduce:**
|
||||||
|
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
|
||||||
|
**(Optional) Debug token generated by `pihole -d`:**
|
||||||
|
|
||||||
|
`<token>`
|
||||||
|
|
||||||
|
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
|
||||||
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
**By submitting this pull request, I confirm the following (please check boxes, eg [X]) _Failure to fill the template will close your PR_:**
|
||||||
|
|
||||||
|
***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request***
|
||||||
|
|
||||||
|
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
|
||||||
|
- [] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist.
|
||||||
|
- [] I have considered, and confirmed that this submission will be valuable to others.
|
||||||
|
- [] I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
|
||||||
|
- [] I give this submission freely, and claim no ownership to its content.
|
||||||
|
|
||||||
|
**How familiar are you with the codebase?:**
|
||||||
|
|
||||||
|
_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
|
||||||
|
|
||||||
|
---
|
||||||
|
_{replace this line with your pull request content}_
|
||||||
|
|
||||||
|
|
||||||
|
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
|
||||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.DS_Store
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
__pycache__
|
||||||
|
.cache
|
||||||
|
.pullapprove.yml
|
||||||
|
|
||||||
25
.idea/codeStyleSettings.xml
generated
Normal file
25
.idea/codeStyleSettings.xml
generated
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectCodeStyleSettingsManager">
|
||||||
|
<option name="PER_PROJECT_SETTINGS">
|
||||||
|
<value>
|
||||||
|
<option name="OTHER_INDENT_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
<option name="USE_TAB_CHARACTER" value="false" />
|
||||||
|
<option name="SMART_TABS" value="false" />
|
||||||
|
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||||
|
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||||
|
<option name="USE_RELATIVE_INDENTS" value="false" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<MarkdownNavigatorCodeStyleSettings>
|
||||||
|
<option name="RIGHT_MARGIN" value="72" />
|
||||||
|
</MarkdownNavigatorCodeStyleSettings>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
38
.pullapprove.yml
Normal file
38
.pullapprove.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
always_pending:
|
||||||
|
title_regex: '(WIP|wip)'
|
||||||
|
labels:
|
||||||
|
- wip
|
||||||
|
explanation: 'This PR is a work in progress...'
|
||||||
|
|
||||||
|
group_defaults:
|
||||||
|
reset_on_push:
|
||||||
|
enabled: true
|
||||||
|
reject_value: -2
|
||||||
|
approve_regex: '^(Approved|:shipit:|:\+1:|Engage)'
|
||||||
|
reject_regex: '^(Rejected|:-1:|Borg)'
|
||||||
|
author_approval:
|
||||||
|
auto: true
|
||||||
|
|
||||||
|
|
||||||
|
groups:
|
||||||
|
development:
|
||||||
|
approve_by_comment:
|
||||||
|
enabled: true
|
||||||
|
conditions:
|
||||||
|
branches:
|
||||||
|
- development
|
||||||
|
required: 2
|
||||||
|
teams:
|
||||||
|
- approvers
|
||||||
|
|
||||||
|
master:
|
||||||
|
approve_by_comment:
|
||||||
|
enabled: true
|
||||||
|
conditions:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
required: -1
|
||||||
|
teams:
|
||||||
|
- admin
|
||||||
10
.travis.yml
Normal file
10
.travis.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
sudo: required
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
language: python
|
||||||
|
python:
|
||||||
|
- "2.7"
|
||||||
|
install:
|
||||||
|
- pip install -r requirements.txt
|
||||||
|
|
||||||
|
script: py.test -vv
|
||||||
38
CONTRIBUTING.md
Normal file
38
CONTRIBUTING.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
|
||||||
|
|
||||||
|
# Contributors Guide
|
||||||
|
|
||||||
|
Please read and understand the contribution guide before creating an issue or pull request.
|
||||||
|
|
||||||
|
## Etiquette
|
||||||
|
|
||||||
|
- Our goal for Pi-hole is **stability before features**. This means we focus on squashing critical bugs before adding new features. Often, we can do both in tandem, but bugs will take priority over a new feature.
|
||||||
|
- Pi-hole is open source and [powered by donations](https://pi-hole.net/donate/), and as such, we give our **free time** to build, maintain, and **provide user support** for this project. It would be extremely unfair for us to suffer abuse or anger for our hard work, so please take a moment to consider that.
|
||||||
|
- Please be considerate towards the developers and other users when raising issues or presenting pull requests.
|
||||||
|
- Respect our decision(s), and do not be upset or abusive if your submission is not used.
|
||||||
|
|
||||||
|
## Viability
|
||||||
|
|
||||||
|
When requesting or submitting new features, first consider whether it might be useful to others. Open source projects are used by many people, who may have entirely different needs to your own. Think about whether or not your feature is likely to be used by other users of the project.
|
||||||
|
|
||||||
|
## Procedure
|
||||||
|
|
||||||
|
**Before filing an issue:**
|
||||||
|
|
||||||
|
- Attempt to replicate and **document** the problem, to ensure that it wasn't a coincidental incident.
|
||||||
|
- Check to make sure your feature suggestion isn't already present within the project.
|
||||||
|
- Check the pull requests tab to ensure that the bug doesn't have a fix in progress.
|
||||||
|
- Check the pull requests tab to ensure that the feature isn't already in progress.
|
||||||
|
|
||||||
|
**Before submitting a pull request:**
|
||||||
|
|
||||||
|
- Check the codebase to ensure that your feature doesn't already exist.
|
||||||
|
- Check the pull requests to ensure that another person hasn't already submitted the feature or fix.
|
||||||
|
|
||||||
|
## Technical Requirements
|
||||||
|
|
||||||
|
- Submit Pull Requests to the **development branch only**.
|
||||||
|
- Before Submitting your Pull Request, merge `development` with your new branch and fix any conflicts. (Make sure you don't break anything in development!)
|
||||||
|
- Please use the [Google Style Guide for Shell](https://google.github.io/styleguide/shell.xml) for your code submission styles.
|
||||||
|
- Commit Unix line endings.
|
||||||
|
- (Optional fun) keep to the theme of Star Trek/black holes/gravity.
|
||||||
190
README.md
190
README.md
@@ -1,85 +1,161 @@
|
|||||||
# Automated Install
|
<p align="center">
|
||||||
##### Designed For Raspberry Pi B, B+, 2, and Zero (with an Ethernet adapter)
|
<a href=https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE><img src="https://www.bountysource.com/badge/tracker?tracker_id=3011939"></a>
|
||||||
|
<a href="https://www.codacy.com/app/Pi-hole/pi-hole?utm_source=github.com&utm_medium=referral&utm_content=pi-hole/pi-hole&utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/c558a0f8d7124c99b02b84f0f5564238"/></a>
|
||||||
|
<a href=https://travis-ci.org/pi-hole/pi-hole><img src="https://travis-ci.org/pi-hole/pi-hole.svg?branch=development"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
1. Install Raspbian
|
<p align="center">
|
||||||
2. Run the command below
|
<a href=https://discourse.pi-hole.net><img src="https://assets.pi-hole.net/static/Vortex_text.png" width=210></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
### ```curl -L install.pi-hole.net | bash```
|
## The multi-platform, network-wide ad blocker
|
||||||
|
|
||||||
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to [use the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
|
Block ads for **all** your devices _without_ the need to install client-side software. The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
|
||||||
|
|
||||||
## Pi-hole Is Free, But Powered By Your Donations
|
- Web Browsers
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY "Donate")
|
- Cell Phones
|
||||||
|
- Smart TV's
|
||||||
|
- Internet-connected home automation
|
||||||
|
- Anything that communicates with the Internet
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href=http://www.digitalocean.com/?refcode=344d234950e1><img src="https://assets.pi-hole.net/static/DOHostingSlug.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Your Support Still Matters
|
||||||
|
|
||||||
|
Digital Ocean helps with our infrastructure, but our developers are all volunteers so *your donations help keep us innovating*. Sending a donation using our links below helps us offset a portion of our monthly costs.
|
||||||
|
|
||||||
|
-  [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
|
||||||
|
-  Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
|
||||||
|
|
||||||
|
### One-Step Automated Install
|
||||||
|
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
|
||||||
|
2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
|
||||||
|
|
||||||
|
### `curl -sSL https://install.pi-hole.net | bash`
|
||||||
|
|
||||||
|
#### Alternative Semi-Automated Install Methods
|
||||||
|
_If you wish to read over the script before running it, run `nano basic-install.sh` to open the file in a text viewer._
|
||||||
|
|
||||||
|
##### Clone our repository and run the automated installer from your device.
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
|
||||||
|
cd Pi-hole/automated_installer/
|
||||||
|
bash basic-install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Or
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -O basic-install.sh https://install.pi-hole.net
|
||||||
|
bash basic-install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to [use the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
|
||||||
|
|
||||||
|
## Installing the Pi-hole (Click to Watch!)
|
||||||
|
<p align="center">
|
||||||
|
<a href=https://www.youtube.com/watch?v=TzFLJqUeirA><img src="https://assets.pi-hole.net/static/global.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Would you like to know more?
|
||||||
|
|
||||||
## How Does It Work?
|
|
||||||
**Watch the 60-second video below to get a quick overview**
|
**Watch the 60-second video below to get a quick overview**
|
||||||
|
<p align="center">
|
||||||
|
<a href=https://youtu.be/9Eti3xibiho><img src="https://assets.pi-hole.net/static/blackhole_web.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
[](https://vimeo.com/135965232)
|
## Get Help Or Connect With Us On The Web
|
||||||
|
|
||||||
## Pi-hole Projects
|
- [Users Forum](https://discourse.pi-hole.net/)
|
||||||
- [Pi-hole Chrome extension](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([open source](https://github.com/packtloss/pihole-extension))
|
- [FAQs](https://discourse.pi-hole.net/c/faqs)
|
||||||
- [Go Bananas for CHiP-hole ad blocking](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037)
|
- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
|
||||||
- [Sky-Hole](http://dlaa.me/blog/post/skyhole)
|
-  [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
|
||||||
- [Pi-hole in the Cloud!](http://blog.codybunch.com/2015/07/28/Pi-Hole-in-the-cloud/)
|
-  [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
|
||||||
- [unRaid-hole](https://github.com/spants/unraidtemplates/blob/master/Spants/unRaid-hole.xml#L13)--[Repo and more info](http://lime-technology.com/forum/index.php?PHPSESSID=c0eae3e5ef7e521f7866034a3336489d&topic=38486.0)
|
-  [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
|
||||||
- [Pi-hole on/off button](http://thetimmy.silvernight.org/pages/endisbutton/)
|
- [](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
- [Minibian Pi-hole](http://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole)
|
|
||||||
|
|
||||||
## Coverage
|
|
||||||
- [MacObserver Podcast 585](http://www.macobserver.com/tmo/podcast/macgeekgab-585)
|
|
||||||
- [Medium: Block All Ads For $53](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d)
|
|
||||||
- [MakeUseOf: Adblock Everywhere, The Pi-hole Way](http://www.makeuseof.com/tag/adblock-everywhere-raspberry-pi-hole-way/)
|
|
||||||
- [Lifehacker: Turn Your Pi Into An Ad Blocker With A Single Command](http://lifehacker.com/turn-a-raspberry-pi-into-an-ad-blocker-with-a-single-co-1686093533)!
|
|
||||||
- [Pi-hole on TekThing](https://youtu.be/8Co59HU2gY0?t=2m)
|
|
||||||
- [Pi-hole on Security Now! Podcast](http://www.youtube.com/watch?v=p7-osq_y8i8&t=100m26s)
|
|
||||||
- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
|
|
||||||
- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
|
|
||||||
- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
|
|
||||||
|
|
||||||
## Partnering With Optimal.com
|
|
||||||
|
|
||||||
Pi-hole will be teaming up with [Rob Leathern's subscription service to avoid ads](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d). This service is unique and will help content-creators and publishers [still make money from visitors who are using an ad ablocker](http://techcrunch.com/2015/12/17/the-new-optimal/).
|
|
||||||
|
|
||||||
## Technical Details
|
## Technical Details
|
||||||
|
|
||||||
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
|
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
|
||||||
|
|
||||||
A more detailed explanation of the installation can be found [here](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0).
|
### Gravity
|
||||||
|
|
||||||
## Gravity
|
The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
|
||||||
The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)).
|
|
||||||
|
|
||||||
## Whitelist and blacklist
|
|
||||||
Domains can be whitelisted and blacklisted using two pre-installed scripts. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details
|
|
||||||
|
|
||||||
## Web Interface
|
|
||||||
The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
|
|
||||||
|
|
||||||
`http://192.168.1.x/admin/index.php`
|
#### Other Operating Systems
|
||||||
|
|
||||||
### API
|
The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. However, this script will work for most UNIX-like systems, some with some slight **modifications** that we can help you work through. If you can install `dnsmasq` and a Webserver, it should work OK. If there are other platforms you'd like supported, let us know.
|
||||||
|
|
||||||
|
### Web Interface
|
||||||
|
|
||||||
|
The [Web interface](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
|
||||||
|
|
||||||
|
`http://192.168.1.x/admin/index.php` or `http://pi.hole/admin`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Whitelist and blacklist
|
||||||
|
|
||||||
|
Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details
|
||||||
|
<p align="center">
|
||||||
|
<a href=https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting><img src="https://assets.pi-hole.net/static/controlpanel.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
A basic read-only API can be accessed at `/admin/api.php`. It returns the following JSON:
|
A basic read-only API can be accessed at `/admin/api.php`. It returns the following JSON:
|
||||||
```JSON
|
|
||||||
|
``` json
|
||||||
{
|
{
|
||||||
"domains_being_blocked": "136708",
|
"domains_being_blocked": "136708",
|
||||||
"dns_queries_today": "18108",
|
"dns_queries_today": "18108",
|
||||||
"ads_blocked_today": "14648",
|
"ads_blocked_today": "14648",
|
||||||
"ads_percentage_today": "80.89"
|
"ads_percentage_today": "80.89"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
The same output can be acheived on the CLI by running `chronometer.sh -j`
|
|
||||||
|
|
||||||

|
The same output can be achieved on the CLI by running `chronometer.sh -j`
|
||||||
|
|
||||||
## Real-time Statistics
|
## Real-time Statistics
|
||||||
|
|
||||||
You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-monitor-chronometer/) via `ssh` or on an [2.8" LCD screen](http://amzn.to/1P0q1Fj). This is accomplished via [`chronometer.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh).
|
You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-monitor-chronometer/) via `ssh` or on an [2.8" LCD screen](http://amzn.to/1P0q1Fj). This is accomplished via [`chronometer.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh). 
|
||||||

|
|
||||||
|
|
||||||
## Help
|
## Pi-hole Projects
|
||||||
- See the [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization) entry for more details
|
|
||||||
- There is also an [FAQ section on pi-hole.net](http://pi-hole.net)
|
|
||||||
|
|
||||||
## Other Operating Systems
|
- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
|
||||||
This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install only works for a clean install of Raspiban right now since that is how the project originated.
|
- [Get LED alerts for each blocked ad](http://www.stinebaugh.info/get-led-alerts-for-each-blocked-ad-using-pi-hole/)
|
||||||
|
- [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html)
|
||||||
|
- [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/)
|
||||||
|
- [Splunk: Pi-hole Visualizser](https://splunkbase.splunk.com/app/3023/)
|
||||||
|
- [Pi-hole Chrome extension](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([open source](https://github.com/packtloss/pihole-extension))
|
||||||
|
- [Go Bananas for CHiP-hole ad blocking](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037)
|
||||||
|
- [Sky-Hole](http://dlaa.me/blog/post/skyhole)
|
||||||
|
- [Pi-hole in the Cloud!](http://blog.codybunch.com/2015/07/28/Pi-Hole-in-the-cloud/)
|
||||||
|
- [unRaid-hole](https://github.com/spants/unraidtemplates/blob/master/Spants/unRaid-hole.xml#L13)--[Repo and more info](http://lime-technology.com/forum/index.php?PHPSESSID=c0eae3e5ef7e521f7866034a3336489d&topic=38486.0)
|
||||||
|
- [Pi-hole on/off button](http://thetimmy.silvernight.org/pages/endisbutton/)
|
||||||
|
- [Minibian Pi-hole](http://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole)
|
||||||
|
- [Windows Tray Stat Application](https://github.com/goldbattle/copernicus)
|
||||||
|
- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
|
||||||
|
- [Pi-Hole Prometheus exporter](https://github.com/nlamirault/pihole_exporter) : a [Prometheus](https://prometheus.io/) exporter for Pi-Hole
|
||||||
|
|
||||||
|
## Coverage
|
||||||
|
|
||||||
|
- [Adafruit livestream install](https://www.youtube.com/watch?v=eg4u2j1HYlI)
|
||||||
|
- [TekThing: 5 fun, easy projects for a Raspberry Pi](https://youtu.be/QwrKlyC2kdM?t=1m42s)
|
||||||
|
- [Pi-hole on Adafruit's blog](https://blog.adafruit.com/2016/03/04/pi-hole-is-a-black-hole-for-internet-ads-piday-raspberrypi-raspberry_pi/)
|
||||||
|
- [The Defrag Show - MSDN/Channel 9](https://channel9.msdn.com/Shows/The-Defrag-Show/Defrag-Endoscope-USB-Camera-The-Final-HoloLens-Vote-Adblock-Pi-and-more?WT.mc_id=dlvr_twitter_ch9#time=20m39s)
|
||||||
|
- [MacObserver Podcast 585](http://www.macobserver.com/tmo/podcast/macgeekgab-585)
|
||||||
|
- [Medium: Block All Ads For $53](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d)
|
||||||
|
- [MakeUseOf: Adblock Everywhere, The Pi-hole Way](http://www.makeuseof.com/tag/adblock-everywhere-raspberry-pi-hole-way/)
|
||||||
|
- [Lifehacker: Turn Your Pi Into An Ad Blocker With A Single Command](http://lifehacker.com/turn-a-raspberry-pi-into-an-ad-blocker-with-a-single-co-1686093533)!
|
||||||
|
- [Pi-hole on TekThing](https://youtu.be/8Co59HU2gY0?t=2m)
|
||||||
|
- [Pi-hole on Security Now! Podcast](http://www.youtube.com/watch?v=p7-osq_y8i8&t=100m26s)
|
||||||
|
- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
|
||||||
|
- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
|
||||||
|
- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
|
||||||
|
- [Build an Ad-Blocker for less than 10$ with Orange-Pi](http://www.devacron.com/orangepi-zero-as-an-ad-block-server-with-pi-hole/)
|
||||||
|
|||||||
53
adlists.default
Normal file
53
adlists.default
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
## Pi-hole ad-list default sources. Updated 29/10/2016 #########################
|
||||||
|
# #
|
||||||
|
# To make changes to this file: #
|
||||||
|
# 1. run `cp /etc/pihole/adlists.default /etc/pihole/adlists.list` #
|
||||||
|
# 2. run `nano /etc/pihole/adlists.list` #
|
||||||
|
# 3. Uncomment or comment any of the below lists #
|
||||||
|
# #
|
||||||
|
# Know of any other lists? Feel free to let us know about them, or add them #
|
||||||
|
# to this file! #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# The below list amalgamates several lists we used previously.
|
||||||
|
# See `https://github.com/StevenBlack/hosts` for details
|
||||||
|
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
|
|
||||||
|
# Other lists we consider safe:
|
||||||
|
http://mirror1.malwaredomains.com/files/justdomains
|
||||||
|
http://sysctl.org/cameleon/hosts
|
||||||
|
https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
|
||||||
|
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
|
||||||
|
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
||||||
|
|
||||||
|
# hosts-file.net list. Updated frequently, but has been known to block legitimate sites.
|
||||||
|
https://hosts-file.net/ad_servers.txt
|
||||||
|
|
||||||
|
# Mahakala list. Has been known to block legitimage domains including the entire .com range.
|
||||||
|
# Warning: Due to the sheer size of this list, the web admin console will be unresponsive.
|
||||||
|
#http://adblock.mahakala.is/
|
||||||
|
|
||||||
|
# ADZHOSTS list. Has been known to block legitimate domains
|
||||||
|
#http://pilotfiber.dl.sourceforge.net/project/adzhosts/HOSTS.txt
|
||||||
|
|
||||||
|
# Windows 10 telemetry list
|
||||||
|
#https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/win10/spy.txt
|
||||||
|
|
||||||
|
# Securemecca.com list - Also blocks "adult" sites (pornography/gambling etc)
|
||||||
|
#http://securemecca.com/Downloads/hosts.txt
|
||||||
|
|
||||||
|
# Quidsup's tracker list
|
||||||
|
#https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt
|
||||||
|
|
||||||
|
# Block the BBC News website Breaking News banner
|
||||||
|
#https://raw.githubusercontent.com/BreakingTheNews/BreakingTheNews.github.io/master/hosts
|
||||||
|
|
||||||
|
# Untested Lists:
|
||||||
|
#https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt
|
||||||
|
#https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt
|
||||||
|
#http://malwaredomains.lehigh.edu/files/domains.txt
|
||||||
|
# Following two lists should be used simultaneously: (readme https://github.com/notracking/hosts-blocklists/)
|
||||||
|
#https://raw.github.com/notracking/hosts-blocklists/master/hostnames.txt
|
||||||
|
#https://raw.github.com/notracking/hosts-blocklists/master/domains.txt
|
||||||
|
# Combination of serveral host files on the internet (warning some facebook domains are also blocked but you can go to facebook.com). See https://github.com/mat1th/Dns-add-block for more information.
|
||||||
|
#https://raw.githubusercontent.com/mat1th/Dns-add-block/master/hosts
|
||||||
44
advanced/01-pihole.conf
Normal file
44
advanced/01-pihole.conf
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# dnsmasq config for Pi-hole
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||||
|
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||||
|
# #
|
||||||
|
# IF YOU WISH TO CHANGE THE UPSTREAM SERVERS, CHANGE THEM IN: #
|
||||||
|
# /etc/pihole/setupVars.conf #
|
||||||
|
# #
|
||||||
|
# ANY OTHER CHANGES SHOULD BE MADE IN A SEPERATE CONFIG FILE #
|
||||||
|
# OR IN /etc/dnsmasq.conf #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
addn-hosts=/etc/pihole/gravity.list
|
||||||
|
addn-hosts=/etc/pihole/local.list
|
||||||
|
|
||||||
|
domain-needed
|
||||||
|
|
||||||
|
bogus-priv
|
||||||
|
|
||||||
|
no-resolv
|
||||||
|
|
||||||
|
server=@DNS1@
|
||||||
|
server=@DNS2@
|
||||||
|
|
||||||
|
interface=@INT@
|
||||||
|
|
||||||
|
cache-size=10000
|
||||||
|
|
||||||
|
log-queries
|
||||||
|
log-facility=/var/log/pihole.log
|
||||||
|
|
||||||
|
local-ttl=300
|
||||||
|
|
||||||
|
log-async
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# (c) 2015 by Jacob Salmela
|
|
||||||
# This file is part of Pi-hole.
|
|
||||||
#
|
|
||||||
# Pi-hole is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
if [[ $# = 0 ]]; then
|
|
||||||
echo "Immediately blacklists one or more domains in the hosts file"
|
|
||||||
echo " "
|
|
||||||
echo "Usage: blacklist.sh domain1 [domain2 ...]"
|
|
||||||
echo " "
|
|
||||||
echo "Options:"
|
|
||||||
echo " -d, --delmode Remove domains from the blacklist"
|
|
||||||
echo " -nr, --noreload Update blacklist without refreshing dnsmasq"
|
|
||||||
echo " -f, --force Force updating of the hosts files, even if there are no changes"
|
|
||||||
echo " -q, --quiet output is less verbose"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#globals
|
|
||||||
blacklist=/etc/pihole/blacklist.txt
|
|
||||||
adList=/etc/pihole/gravity.list
|
|
||||||
reload=true
|
|
||||||
addmode=true
|
|
||||||
force=false
|
|
||||||
versbose=true
|
|
||||||
domList=()
|
|
||||||
domToRemoveList=()
|
|
||||||
|
|
||||||
|
|
||||||
piholeIPfile=/tmp/piholeIP
|
|
||||||
piholeIPv6file=/etc/pihole/.useIPv6
|
|
||||||
|
|
||||||
# Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script
|
|
||||||
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
|
|
||||||
piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}')
|
|
||||||
piholeIP=${piholeIPCIDR%/*}
|
|
||||||
|
|
||||||
modifyHost=false
|
|
||||||
|
|
||||||
|
|
||||||
if [[ -f $piholeIPv6file ]];then
|
|
||||||
# If the file exists, then the user previously chose to use IPv6 in the automated installer
|
|
||||||
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
function HandleOther(){
|
|
||||||
#check validity of domain
|
|
||||||
validDomain=$(echo $1 | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
|
|
||||||
|
|
||||||
if [ -z "$validDomain" ]; then
|
|
||||||
echo $1 is not a valid argument or domain name
|
|
||||||
else
|
|
||||||
domList=("${domList[@]}" $validDomain)
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function PopBlacklistFile(){
|
|
||||||
#check blacklist file exists, and if not, create it
|
|
||||||
if [[ ! -f $blacklist ]];then
|
|
||||||
touch $blacklist
|
|
||||||
fi
|
|
||||||
for dom in "${domList[@]}"
|
|
||||||
do
|
|
||||||
if $addmode; then
|
|
||||||
AddDomain $dom
|
|
||||||
else
|
|
||||||
RemoveDomain $dom
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddDomain(){
|
|
||||||
#| sed 's/\./\\./g'
|
|
||||||
bool=false
|
|
||||||
grep -Ex -q "$1" $blacklist || bool=true
|
|
||||||
if $bool; then
|
|
||||||
#domain not found in the blacklist file, add it!
|
|
||||||
if $versbose; then
|
|
||||||
echo -n "::: Adding $1 to blacklist file..."
|
|
||||||
fi
|
|
||||||
echo $1 >> $blacklist
|
|
||||||
modifyHost=true
|
|
||||||
echo " done!"
|
|
||||||
else
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: $1 already exists in blacklist.txt! No need to add"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function RemoveDomain(){
|
|
||||||
|
|
||||||
bool=false
|
|
||||||
grep -Ex -q "$1" $blacklist || bool=true
|
|
||||||
if $bool; then
|
|
||||||
#Domain is not in the blacklist file, no need to Remove
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: $1 is NOT blacklisted! No need to remove"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
#Domain is in the blacklist file, add to a temporary array
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: Un-blacklisting $dom..."
|
|
||||||
fi
|
|
||||||
domToRemoveList=("${domToRemoveList[@]}" $1)
|
|
||||||
modifyHost=true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function ModifyHostFile(){
|
|
||||||
if $addmode; then
|
|
||||||
#add domains to the hosts file
|
|
||||||
if [[ -r $blacklist ]];then
|
|
||||||
numberOf=$(cat $blacklist | sed '/^\s*$/d' | wc -l)
|
|
||||||
plural=; [[ "$numberOf" != "1" ]] && plural=s
|
|
||||||
echo ":::"
|
|
||||||
echo -n "::: Modifying HOSTS file to blacklist $numberOf domain${plural}..."
|
|
||||||
if [[ -n $piholeIPv6 ]];then
|
|
||||||
cat $blacklist | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList
|
|
||||||
else
|
|
||||||
cat $blacklist | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
|
|
||||||
echo ":::"
|
|
||||||
for dom in "${domToRemoveList[@]}"
|
|
||||||
do
|
|
||||||
#we need to remove the domains from the blacklist file and the host file
|
|
||||||
echo "::: $dom"
|
|
||||||
echo -n "::: removing from HOSTS file..."
|
|
||||||
echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' $adList
|
|
||||||
echo " done!"
|
|
||||||
echo -n "::: removing from blackist.txt..."
|
|
||||||
echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $blacklist
|
|
||||||
echo " done!"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function Reload() {
|
|
||||||
# Reload hosts file
|
|
||||||
echo ":::"
|
|
||||||
echo -n "::: Refresh lists in dnsmasq..."
|
|
||||||
|
|
||||||
dnsmasqPid=$(pidof dnsmasq)
|
|
||||||
|
|
||||||
if [[ $dnsmasqPid ]]; then
|
|
||||||
# service already running - reload config
|
|
||||||
sudo kill -HUP $dnsmasqPid
|
|
||||||
else
|
|
||||||
# service not running, start it up
|
|
||||||
sudo service dnsmasq start
|
|
||||||
fi
|
|
||||||
echo " done!"
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
for var in "$@"
|
|
||||||
do
|
|
||||||
case "$var" in
|
|
||||||
"-nr"| "--noreload" ) reload=false;;
|
|
||||||
"-d" | "--delmode" ) addmode=false;;
|
|
||||||
"-f" | "--force" ) force=true;;
|
|
||||||
"-q" | "--quiet" ) versbose=false;;
|
|
||||||
* ) HandleOther $var;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
PopBlacklistFile
|
|
||||||
|
|
||||||
if $modifyHost || $force; then
|
|
||||||
ModifyHostFile
|
|
||||||
else
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: No changes need to be made"
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $reload; then
|
|
||||||
Reload
|
|
||||||
fi
|
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# (c) 2015 by Jacob Salmela
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
# This file is part of Pi-hole.
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Calculates stats and displays to an LCD
|
||||||
#
|
#
|
||||||
# Pi-hole is free software: you can redistribute it and/or modify
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -12,17 +15,15 @@
|
|||||||
piLog="/var/log/pihole.log"
|
piLog="/var/log/pihole.log"
|
||||||
gravity="/etc/pihole/gravity.list"
|
gravity="/etc/pihole/gravity.list"
|
||||||
|
|
||||||
today=$(date "+%b %e")
|
. /etc/pihole/setupVars.conf
|
||||||
|
|
||||||
function CalcBlockedDomains(){
|
CalcBlockedDomains() {
|
||||||
CheckIPv6
|
if [ -e "${gravity}" ]; then
|
||||||
if [ -e "$gravity" ]; then
|
# if BOTH IPV4 and IPV6 are in use, then we need to divide total domains by 2.
|
||||||
#Are we IPV6 or IPV4?
|
if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]]; then
|
||||||
if [[ -n $piholeIPv6 ]];then
|
|
||||||
#We are IPV6
|
|
||||||
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
|
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
|
||||||
else
|
else
|
||||||
#We are IPV4
|
# only one is set.
|
||||||
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1}')
|
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1}')
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -30,106 +31,105 @@ function CalcBlockedDomains(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function CalcQueriesToday(){
|
CalcQueriesToday() {
|
||||||
if [ -e "$piLog" ];then
|
if [ -e "${piLog}" ]; then
|
||||||
queriesToday=$(cat "$piLog" | grep "$today" | awk '/query/ {print $6}' | wc -l)
|
queriesToday=$(awk '/query\[/ {print $6}' < "${piLog}" | wc -l)
|
||||||
else
|
else
|
||||||
queriesToday="Err."
|
queriesToday="Err."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function CalcblockedToday(){
|
CalcblockedToday() {
|
||||||
if [ -e "$piLog" ] && [ -e "$gravity" ];then
|
if [ -e "${piLog}" ] && [ -e "${gravity}" ];then
|
||||||
blockedToday=$(cat $piLog | awk '/\/etc\/pihole\/gravity.list/ && !/address/ {print $6}' | wc -l)
|
blockedToday=$(awk '/\/etc\/pihole\/gravity.list/ && !/address/ {print $6}' < "${piLog}" | wc -l)
|
||||||
else
|
else
|
||||||
blockedToday="Err."
|
blockedToday="Err."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function CalcPercentBlockedToday(){
|
CalcPercentBlockedToday() {
|
||||||
if [ "$queriesToday" != "Err." ] && [ "$blockedToday" != "Err." ]; then
|
if [ "${queriesToday}" != "Err." ] && [ "${blockedToday}" != "Err." ]; then
|
||||||
#scale 2 rounds the number down, so we'll do scale 4 and then trim the last 2 zeros
|
if [ "${queriesToday}" != 0 ]; then #Fixes divide by zero error :)
|
||||||
percentBlockedToday=$(echo "scale=4; $blockedToday/$queriesToday*100" | bc)
|
#scale 2 rounds the number down, so we'll do scale 4 and then trim the last 2 zeros
|
||||||
percentBlockedToday=$(sed 's/.\{2\}$//' <<< "$percentBlockedToday")
|
percentBlockedToday=$(echo "scale=4; ${blockedToday}/${queriesToday}*100" | bc)
|
||||||
|
percentBlockedToday=$(sed 's/.\{2\}$//' <<< "${percentBlockedToday}")
|
||||||
|
else
|
||||||
|
percentBlockedToday=0
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function CheckIPv6(){
|
outputJSON() {
|
||||||
piholeIPv6file="/etc/pihole/.useIPv6"
|
|
||||||
if [[ -f $piholeIPv6file ]];then
|
|
||||||
# If the file exists, then the user previously chose to use IPv6 in the automated installer
|
|
||||||
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function outputJSON(){
|
|
||||||
CalcQueriesToday
|
CalcQueriesToday
|
||||||
CalcblockedToday
|
CalcblockedToday
|
||||||
CalcPercentBlockedToday
|
CalcPercentBlockedToday
|
||||||
|
|
||||||
CalcBlockedDomains
|
CalcBlockedDomains
|
||||||
|
|
||||||
printf '{"domains_being_blocked":"%s","dns_queries_today":"%s","ads_blocked_today":"%s","ads_percentage_today":"%s"}\n' "$blockedDomainsTotal" "$queriesToday" "$blockedToday" "$percentBlockedToday"
|
printf '{"domains_being_blocked":"%s","dns_queries_today":"%s","ads_blocked_today":"%s","ads_percentage_today":"%s"}\n' "$blockedDomainsTotal" "$queriesToday" "$blockedToday" "$percentBlockedToday"
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalChrono(){
|
normalChrono() {
|
||||||
for (( ; ; ))
|
for (( ; ; )); do
|
||||||
do
|
|
||||||
clear
|
clear
|
||||||
# Displays a colorful Pi-hole logo
|
# Displays a colorful Pi-hole logo
|
||||||
toilet -f small -F gay Pi-hole
|
echo " [0;1;35;95m_[0;1;31;91m__[0m [0;1;33;93m_[0m [0;1;34;94m_[0m [0;1;36;96m_[0m"
|
||||||
echo " $(ifconfig eth0 | awk '/inet addr/ {print $2}' | cut -d':' -f2)"
|
echo "[0;1;31;91m|[0m [0;1;33;93m_[0m [0;1;32;92m(_[0;1;36;96m)_[0;1;34;94m__[0;1;35;95m|[0m [0;1;31;91m|_[0m [0;1;32;92m__[0;1;36;96m_|[0m [0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m"
|
||||||
|
echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
|
||||||
|
echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
|
||||||
|
echo ""
|
||||||
|
echo " ${IPV4_ADDRESS}"
|
||||||
echo ""
|
echo ""
|
||||||
uptime | cut -d' ' -f11-
|
uptime | cut -d' ' -f11-
|
||||||
|
#uptime -p #Doesn't work on all versions of uptime
|
||||||
|
uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
|
||||||
echo "-------------------------------"
|
echo "-------------------------------"
|
||||||
# Uncomment to continually read the log file and display the current domain being blocked
|
# Uncomment to continually read the log file and display the current domain being blocked
|
||||||
#tail -f /var/log/pihole.log | awk '/\/etc\/pihole\/gravity.list/ {if ($7 != "address" && $7 != "name" && $7 != "/etc/pihole/gravity.list") print $7; else;}'
|
#tail -f /var/log/pihole.log | awk '/\/etc\/pihole\/gravity.list/ {if ($7 != "address" && $7 != "name" && $7 != "/etc/pihole/gravity.list") print $7; else;}'
|
||||||
|
|
||||||
#uncomment next 4 lines to use original query count calculation
|
#uncomment next 4 lines to use original query count calculation
|
||||||
#today=$(date "+%b %e")
|
#today=$(date "+%b %e")
|
||||||
#todaysQueryCount=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ {print $7}' | wc -l)
|
#todaysQueryCount=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ {print $7}' | wc -l)
|
||||||
#todaysQueryCountV4=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[A\]/ {print $7}' | wc -l)
|
#todaysQueryCountV4=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[A\]/ {print $7}' | wc -l)
|
||||||
#todaysQueryCountV6=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[AAAA\]/ {print $7}' | wc -l)
|
#todaysQueryCountV6=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[AAAA\]/ {print $7}' | wc -l)
|
||||||
|
|
||||||
|
|
||||||
CalcQueriesToday
|
CalcQueriesToday
|
||||||
CalcblockedToday
|
CalcblockedToday
|
||||||
CalcPercentBlockedToday
|
CalcPercentBlockedToday
|
||||||
|
|
||||||
CalcBlockedDomains
|
CalcBlockedDomains
|
||||||
|
|
||||||
echo "Blocking: $blockedDomainsTotal"
|
echo "Blocking: ${blockedDomainsTotal}"
|
||||||
#below commented line does not add up to todaysQueryCount
|
echo "Queries: ${queriesToday}" #same total calculation as dashboard
|
||||||
#echo "Queries: $todaysQueryCountV4 / $todaysQueryCountV6"
|
echo "Pi-holed: ${blockedToday} (${percentBlockedToday}%)"
|
||||||
echo "Queries: $queriesToday" #same total calculation as dashboard
|
|
||||||
echo "Pi-holed: $blockedToday ($percentBlockedToday%)"
|
|
||||||
|
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayHelp(){
|
displayHelp() {
|
||||||
echo "Displays stats about your piHole!"
|
cat << EOM
|
||||||
echo " "
|
::: Displays stats about your piHole!
|
||||||
echo "Usage: chronometer.sh [optional:-j]"
|
:::
|
||||||
echo "Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds"
|
::: Usage: sudo pihole -c [optional:-j]
|
||||||
echo " "
|
::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds
|
||||||
echo "Options:"
|
:::
|
||||||
echo " -j, --json output stats as JSON formatted string"
|
::: Options:
|
||||||
echo " -h, --help display this help text"
|
::: -j, --json output stats as JSON formatted string
|
||||||
|
::: -h, --help display this help text
|
||||||
exit 1
|
EOM
|
||||||
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $# = 0 ]]; then
|
if [[ $# = 0 ]]; then
|
||||||
normalChrono
|
normalChrono
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for var in "$@"
|
for var in "$@"; do
|
||||||
do
|
case "$var" in
|
||||||
case "$var" in
|
"-j" | "--json" ) outputJSON;;
|
||||||
"-j" | "--json" ) outputJSON;;
|
"-h" | "--help" ) displayHelp;;
|
||||||
"-h" | "--help" ) displayHelp;;
|
* ) exit 1;;
|
||||||
* ) exit 1;;
|
esac
|
||||||
esac
|
|
||||||
done
|
done
|
||||||
|
|||||||
177
advanced/Scripts/list.sh
Executable file
177
advanced/Scripts/list.sh
Executable file
@@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Whitelists and blacklists domains
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
#globals
|
||||||
|
basename=pihole
|
||||||
|
piholeDir=/etc/${basename}
|
||||||
|
whitelist=${piholeDir}/whitelist.txt
|
||||||
|
blacklist=${piholeDir}/blacklist.txt
|
||||||
|
reload=false
|
||||||
|
addmode=true
|
||||||
|
verbose=true
|
||||||
|
|
||||||
|
domList=()
|
||||||
|
domToRemoveList=()
|
||||||
|
|
||||||
|
listMain=""
|
||||||
|
listAlt=""
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
|
||||||
|
if [[ ${listMain} == ${whitelist} ]]; then
|
||||||
|
letter="w"
|
||||||
|
word="white"
|
||||||
|
else
|
||||||
|
letter="b"
|
||||||
|
word="black"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat << EOM
|
||||||
|
::: Immediately ${word}lists one or more domains in the hosts file
|
||||||
|
:::
|
||||||
|
::: Usage: pihole -${letter} domain1 [domain2 ...]
|
||||||
|
:::
|
||||||
|
::: Options:
|
||||||
|
::: -d, --delmode Remove domains from the ${word}list
|
||||||
|
::: -nr, --noreload Update ${word}list without refreshing dnsmasq
|
||||||
|
::: -q, --quiet output is less verbose
|
||||||
|
::: -h, --help Show this help dialog
|
||||||
|
::: -l, --list Display your ${word}listed domains
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
EscapeRegexp() {
|
||||||
|
# This way we may safely insert an arbitrary
|
||||||
|
# string in our regular expressions
|
||||||
|
echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleOther(){
|
||||||
|
# First, convert everything to lowercase
|
||||||
|
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
|
||||||
|
|
||||||
|
#check validity of domain
|
||||||
|
validDomain=$(perl -ne "print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/" <<< "$domain")
|
||||||
|
if [ -z "${validDomain}" ]; then
|
||||||
|
echo "::: $1 is not a valid argument or domain name"
|
||||||
|
else
|
||||||
|
domList=("${domList[@]}" ${validDomain})
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
PoplistFile() {
|
||||||
|
#check whitelist file exists, and if not, create it
|
||||||
|
if [[ ! -f ${whitelist} ]]; then
|
||||||
|
touch ${whitelist}
|
||||||
|
fi
|
||||||
|
for dom in "${domList[@]}"; do
|
||||||
|
# Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
|
||||||
|
if ${addmode}; then
|
||||||
|
AddDomain "${dom}" "${listMain}"
|
||||||
|
RemoveDomain "${dom}" "${listAlt}"
|
||||||
|
else
|
||||||
|
RemoveDomain "${dom}" "${listMain}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
AddDomain() {
|
||||||
|
list="$2"
|
||||||
|
domain=$(EscapeRegexp "$1")
|
||||||
|
|
||||||
|
bool=true
|
||||||
|
#Is the domain in the list we want to add it to?
|
||||||
|
grep -Ex -q "${domain}" ${list} > /dev/null 2>&1 || bool=false
|
||||||
|
|
||||||
|
if [[ "${bool}" == false ]]; then
|
||||||
|
#domain not found in the whitelist file, add it!
|
||||||
|
if [[ "${verbose}" == true ]]; then
|
||||||
|
echo "::: Adding $1 to $list..."
|
||||||
|
fi
|
||||||
|
reload=true
|
||||||
|
# Add it to the list we want to add it to
|
||||||
|
echo "$1" >> ${list}
|
||||||
|
else
|
||||||
|
if [[ "${verbose}" == true ]]; then
|
||||||
|
echo "::: ${1} already exists in ${list}, no need to add!"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveDomain() {
|
||||||
|
list="$2"
|
||||||
|
domain=$(EscapeRegexp "$1")
|
||||||
|
|
||||||
|
bool=true
|
||||||
|
#Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
|
||||||
|
grep -Ex -q "${domain}" ${list} > /dev/null 2>&1 || bool=false
|
||||||
|
if [[ "${bool}" == true ]]; then
|
||||||
|
# Remove it from the other one
|
||||||
|
echo "::: Removing $1 from $list..."
|
||||||
|
# /I flag: search case-insensitive
|
||||||
|
sed -i "/${domain}/Id" ${list}
|
||||||
|
reload=true
|
||||||
|
else
|
||||||
|
if [[ "${verbose}" == true ]]; then
|
||||||
|
echo "::: ${1} does not exist in ${list}, no need to remove!"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
Reload() {
|
||||||
|
# Reload hosts file
|
||||||
|
pihole -g -sd
|
||||||
|
}
|
||||||
|
|
||||||
|
Displaylist() {
|
||||||
|
if [[ ${listMain} == ${whitelist} ]]; then
|
||||||
|
string="gravity resistant domains"
|
||||||
|
else
|
||||||
|
string="domains caught in the sinkhole"
|
||||||
|
fi
|
||||||
|
verbose=false
|
||||||
|
echo -e " Displaying $string \n"
|
||||||
|
count=1
|
||||||
|
while IFS= read -r RD; do
|
||||||
|
echo "${count}: ${RD}"
|
||||||
|
count=$((count+1))
|
||||||
|
done < "${listMain}"
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for var in "$@"; do
|
||||||
|
case "${var}" in
|
||||||
|
"-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
|
||||||
|
"-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
|
||||||
|
"-nr"| "--noreload" ) reload=false;;
|
||||||
|
"-d" | "--delmode" ) addmode=false;;
|
||||||
|
"-f" | "--force" ) force=true;;
|
||||||
|
"-q" | "--quiet" ) verbose=false;;
|
||||||
|
"-h" | "--help" ) helpFunc;;
|
||||||
|
"-l" | "--list" ) Displaylist;;
|
||||||
|
* ) HandleOther "${var}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ $# = 0 ]]; then
|
||||||
|
helpFunc
|
||||||
|
fi
|
||||||
|
|
||||||
|
PoplistFile
|
||||||
|
|
||||||
|
if ${reload}; then
|
||||||
|
Reload
|
||||||
|
fi
|
||||||
|
|
||||||
408
advanced/Scripts/piholeDebug.sh
Executable file
408
advanced/Scripts/piholeDebug.sh
Executable file
@@ -0,0 +1,408 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Generates pihole_debug.log to be used for troubleshooting.
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
######## GLOBAL VARS ########
|
||||||
|
VARSFILE="/etc/pihole/setupVars.conf"
|
||||||
|
DEBUG_LOG="/var/log/pihole_debug.log"
|
||||||
|
DNSMASQFILE="/etc/dnsmasq.conf"
|
||||||
|
DNSMASQCONFFILE="/etc/dnsmasq.d/01-pihole.conf"
|
||||||
|
LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf"
|
||||||
|
LIGHTTPDERRFILE="/var/log/lighttpd/error.log"
|
||||||
|
GRAVITYFILE="/etc/pihole/gravity.list"
|
||||||
|
WHITELISTFILE="/etc/pihole/whitelist.txt"
|
||||||
|
BLACKLISTFILE="/etc/pihole/blacklist.txt"
|
||||||
|
ADLISTFILE="/etc/pihole/adlists.list"
|
||||||
|
PIHOLELOG="/var/log/pihole.log"
|
||||||
|
WHITELISTMATCHES="/tmp/whitelistmatches.list"
|
||||||
|
|
||||||
|
IPV6_READY=false
|
||||||
|
TIMEOUT=60
|
||||||
|
# Header info and introduction
|
||||||
|
cat << EOM
|
||||||
|
::: Beginning Pi-hole debug at $(date)!
|
||||||
|
:::
|
||||||
|
::: This process collects information from your Pi-hole, and optionally uploads
|
||||||
|
::: it to a unique and random directory on tricorder.pi-hole.net.
|
||||||
|
:::
|
||||||
|
::: NOTE: All log files auto-delete after 24 hours and ONLY the Pi-hole developers
|
||||||
|
::: can access your data via the given token. We have taken these extra steps to
|
||||||
|
::: secure your data and will work to further reduce any personal information gathered.
|
||||||
|
:::
|
||||||
|
::: Please read and note any issues, and follow any directions advised during this process.
|
||||||
|
EOM
|
||||||
|
|
||||||
|
# Ensure the file exists, create if not, clear if exists.
|
||||||
|
truncate --size=0 "${DEBUG_LOG}"
|
||||||
|
chmod 644 ${DEBUG_LOG}
|
||||||
|
chown "$USER":pihole ${DEBUG_LOG}
|
||||||
|
|
||||||
|
source ${VARSFILE}
|
||||||
|
|
||||||
|
### Private functions exist here ###
|
||||||
|
log_write() {
|
||||||
|
echo "${1}" >> "${DEBUG_LOG}"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_echo() {
|
||||||
|
case ${1} in
|
||||||
|
-n)
|
||||||
|
echo -n "::: ${2}"
|
||||||
|
log_write "${2}"
|
||||||
|
;;
|
||||||
|
-r)
|
||||||
|
echo "::: ${2}"
|
||||||
|
log_write "${2}"
|
||||||
|
;;
|
||||||
|
-l)
|
||||||
|
echo "${2}"
|
||||||
|
log_write "${2}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "::: ${1}"
|
||||||
|
log_write "${1}"
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
header_write() {
|
||||||
|
log_echo ""
|
||||||
|
log_echo "${1}"
|
||||||
|
log_write ""
|
||||||
|
}
|
||||||
|
|
||||||
|
file_parse() {
|
||||||
|
while read -r line; do
|
||||||
|
if [ ! -z "${line}" ]; then
|
||||||
|
[[ "${line}" =~ ^#.*$ || ! "${line}" ]] && continue
|
||||||
|
log_write "${line}"
|
||||||
|
fi
|
||||||
|
done < "${1}"
|
||||||
|
log_write ""
|
||||||
|
}
|
||||||
|
|
||||||
|
block_parse() {
|
||||||
|
log_write "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
lsof_parse() {
|
||||||
|
local user
|
||||||
|
local process
|
||||||
|
|
||||||
|
user=$(echo ${1} | cut -f 3 -d ' ' | cut -c 2-)
|
||||||
|
process=$(echo ${1} | cut -f 2 -d ' ' | cut -c 2-)
|
||||||
|
[[ ${2} -eq ${process} ]] \
|
||||||
|
&& echo "::: Correctly configured." \
|
||||||
|
|| log_echo "::: Failure: Incorrectly configured daemon."
|
||||||
|
|
||||||
|
log_write "Found user ${user} with process ${process}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
version_check() {
|
||||||
|
header_write "Detecting Installed Package Versions:"
|
||||||
|
|
||||||
|
local error_found
|
||||||
|
error_found=0
|
||||||
|
|
||||||
|
local pi_hole_ver="$(cd /etc/.pihole/ && git describe --tags --abbrev=0)" \
|
||||||
|
&& log_echo -r "Pi-hole: $pi_hole_ver" || (log_echo "Pi-hole git repository not detected." && error_found=1)
|
||||||
|
local admin_ver="$(cd /var/www/html/admin && git describe --tags --abbrev=0)" \
|
||||||
|
&& log_echo -r "WebUI: $admin_ver" || (log_echo "Pi-hole Admin Pages git repository not detected." && error_found=1)
|
||||||
|
local light_ver="$(lighttpd -v |& head -n1 | cut -d " " -f1)" \
|
||||||
|
&& log_echo -r "${light_ver}" || (log_echo "lighttpd not installed." && error_found=1)
|
||||||
|
local php_ver="$(php -v |& head -n1)" \
|
||||||
|
&& log_echo -r "${php_ver}" || (log_echo "PHP not installed." && error_found=1)
|
||||||
|
return "${error_found}"
|
||||||
|
}
|
||||||
|
|
||||||
|
files_check() {
|
||||||
|
#Check non-zero length existence of ${1}
|
||||||
|
header_write "Detecting existence of ${1}:"
|
||||||
|
local search_file="${1}"
|
||||||
|
if [[ -s ${search_file} ]]; then
|
||||||
|
echo "::: File exists"
|
||||||
|
file_parse "${search_file}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_echo "${1} not found!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo ":::"
|
||||||
|
}
|
||||||
|
|
||||||
|
source_file() {
|
||||||
|
local file_found=$(files_check "${1}") \
|
||||||
|
&& (source "${1}" &> /dev/null && echo "${file_found} and was successfully sourced") \
|
||||||
|
|| log_echo -l "${file_found} and could not be sourced"
|
||||||
|
}
|
||||||
|
|
||||||
|
distro_check() {
|
||||||
|
local soft_fail
|
||||||
|
header_write "Detecting installed OS Distribution"
|
||||||
|
soft_fail=0
|
||||||
|
local distro="$(cat /etc/*release)" && block_parse "${distro}" || (log_echo "Distribution details not found." && soft_fail=1)
|
||||||
|
return "${soft_fail}"
|
||||||
|
}
|
||||||
|
|
||||||
|
processor_check() {
|
||||||
|
header_write "Checking processor variety"
|
||||||
|
log_write $(uname -m) && return 0 || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6_check() {
|
||||||
|
# Check if system is IPv6 enabled, for use in other functions
|
||||||
|
if [[ $IPv6_address ]]; then
|
||||||
|
ls /proc/net/if_inet6 &>/dev/null && IPV6_READY=true
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ip_check() {
|
||||||
|
header_write "IP Address Information"
|
||||||
|
# Get the current interface for Internet traffic
|
||||||
|
|
||||||
|
# Check if IPv6 enabled
|
||||||
|
local IPv6_interface
|
||||||
|
local IPv4_interface
|
||||||
|
ipv6_check && IPv6_interface=${piholeInterface:-$(ip -6 r | grep default | cut -d ' ' -f 5)}
|
||||||
|
# If declared in setupVars.conf use it, otherwise defer to default
|
||||||
|
# http://stackoverflow.com/questions/2013547/assigning-default-values-to-shell-variables-with-a-single-command-in-bash
|
||||||
|
IPv4_interface=${piholeInterface:-$(ip r | grep default | cut -d ' ' -f 5)}
|
||||||
|
|
||||||
|
|
||||||
|
if [[ IPV6_READY ]]; then
|
||||||
|
local IPv6_addr_list="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet6") print $(i+1) }')" \
|
||||||
|
&& (log_write "${IPv6_addr_list}" && echo "::: IPv6 addresses located") \
|
||||||
|
|| log_echo "No IPv6 addresses found."
|
||||||
|
|
||||||
|
local IPv6_def_gateway=$(ip -6 r | grep default | cut -d ' ' -f 3)
|
||||||
|
if [[ $? = 0 ]] && [[ -n ${IPv6_def_gateway} ]]; then
|
||||||
|
echo -n "::: Pinging default IPv6 gateway: "
|
||||||
|
local IPv6_def_gateway_check="$(ping6 -q -W 3 -c 3 -n "${IPv6_def_gateway}" -I "${IPv6_interface}"| tail -n3)" \
|
||||||
|
&& echo "Gateway Responded." \
|
||||||
|
|| echo "Gateway did not respond."
|
||||||
|
block_parse "${IPv6_def_gateway_check}"
|
||||||
|
|
||||||
|
echo -n "::: Pinging Internet via IPv6: "
|
||||||
|
local IPv6_inet_check=$(ping6 -q -W 3 -c 3 -n 2001:4860:4860::8888 -I "${IPv6_interface}"| tail -n3) \
|
||||||
|
&& echo "Query responded." \
|
||||||
|
|| echo "Query did not respond."
|
||||||
|
block_parse "${IPv6_inet_check}"
|
||||||
|
else
|
||||||
|
log_echo="No IPv6 Gateway Detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local IPv4_addr_list="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet") print $(i+1) }')" \
|
||||||
|
&& (block_parse "${IPv4_addr_list}" && echo "::: IPv4 addresses located")\
|
||||||
|
|| log_echo "No IPv4 addresses found."
|
||||||
|
|
||||||
|
local IPv4_def_gateway=$(ip r | grep default | cut -d ' ' -f 3)
|
||||||
|
if [[ $? = 0 ]]; then
|
||||||
|
echo -n "::: Pinging default IPv4 gateway: "
|
||||||
|
local IPv4_def_gateway_check="$(ping -q -w 3 -c 3 -n "${IPv4_def_gateway}" -I "${IPv4_interface}" | tail -n3)" \
|
||||||
|
&& echo "Gateway responded." \
|
||||||
|
|| echo "Gateway did not respond."
|
||||||
|
block_parse "${IPv4_def_gateway_check}"
|
||||||
|
|
||||||
|
echo -n "::: Pinging Internet via IPv4: "
|
||||||
|
local IPv4_inet_check="$(ping -q -w 5 -c 3 -n 8.8.8.8 -I "${IPv4_interface}" | tail -n3)" \
|
||||||
|
&& echo "Query responded." \
|
||||||
|
|| echo "Query did not respond."
|
||||||
|
block_parse "${IPv4_inet_check}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
port_check() {
|
||||||
|
local lsof_value
|
||||||
|
|
||||||
|
lsof_value=$(lsof -i ${1}:${2} -FcL | tr '\n' ' ') \
|
||||||
|
&& lsof_parse "${lsof_value}" "${3}" \
|
||||||
|
|| log_echo "Failure: IPv${1} Port not in use"
|
||||||
|
}
|
||||||
|
|
||||||
|
daemon_check() {
|
||||||
|
# Check for daemon ${1} on port ${2}
|
||||||
|
header_write "Daemon Process Information"
|
||||||
|
|
||||||
|
echo "::: Checking ${2} port for ${1} listener."
|
||||||
|
|
||||||
|
if [[ ${IPV6_READY} ]]; then
|
||||||
|
port_check 6 "${2}" "${1}"
|
||||||
|
fi
|
||||||
|
lsof_value=$(lsof -i 4:${2} -FcL | tr '\n' ' ') \
|
||||||
|
port_check 4 "${2}" "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
testResolver() {
|
||||||
|
header_write "Resolver Functions Check"
|
||||||
|
|
||||||
|
# Find a blocked url that has not been whitelisted.
|
||||||
|
TESTURL="doubleclick.com"
|
||||||
|
if [ -s "${WHITELISTMATCHES}" ]; then
|
||||||
|
while read -r line; do
|
||||||
|
CUTURL=${line#*" "}
|
||||||
|
if [ "${CUTURL}" != "Pi-Hole.IsWorking.OK" ]; then
|
||||||
|
while read -r line2; do
|
||||||
|
CUTURL2=${line2#*" "}
|
||||||
|
if [ "${CUTURL}" != "${CUTURL2}" ]; then
|
||||||
|
TESTURL="${CUTURL}"
|
||||||
|
break 2
|
||||||
|
fi
|
||||||
|
done < "${WHITELISTMATCHES}"
|
||||||
|
fi
|
||||||
|
done < "${GRAVITYFILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_write "Resolution of ${TESTURL} from Pi-hole:"
|
||||||
|
LOCALDIG=$(dig "${TESTURL}" @127.0.0.1)
|
||||||
|
if [[ $? = 0 ]]; then
|
||||||
|
log_write "${LOCALDIG}"
|
||||||
|
else
|
||||||
|
log_write "Failed to resolve ${TESTURL} on Pi-hole"
|
||||||
|
fi
|
||||||
|
log_write ""
|
||||||
|
|
||||||
|
|
||||||
|
log_write "Resolution of ${TESTURL} from 8.8.8.8:"
|
||||||
|
REMOTEDIG=$(dig "${TESTURL}" @8.8.8.8)
|
||||||
|
if [[ $? = 0 ]]; then
|
||||||
|
log_write "${REMOTEDIG}"
|
||||||
|
else
|
||||||
|
log_write "Failed to resolve ${TESTURL} on 8.8.8.8"
|
||||||
|
fi
|
||||||
|
log_write ""
|
||||||
|
|
||||||
|
log_write "Pi-hole dnsmasq specific records lookups"
|
||||||
|
log_write "Cache Size:"
|
||||||
|
dig +short chaos txt cachesize.bind >> ${DEBUG_LOG}
|
||||||
|
log_write "Upstream Servers:"
|
||||||
|
dig +short chaos txt servers.bind >> ${DEBUG_LOG}
|
||||||
|
log_write ""
|
||||||
|
}
|
||||||
|
|
||||||
|
checkProcesses() {
|
||||||
|
header_write "Processes Check"
|
||||||
|
|
||||||
|
echo "::: Logging status of lighttpd and dnsmasq..."
|
||||||
|
PROCESSES=( lighttpd dnsmasq )
|
||||||
|
for i in "${PROCESSES[@]}"; do
|
||||||
|
log_write ""
|
||||||
|
log_write "${i}"
|
||||||
|
log_write " processes status:"
|
||||||
|
systemctl -l status "${i}" >> "${DEBUG_LOG}"
|
||||||
|
done
|
||||||
|
log_write ""
|
||||||
|
}
|
||||||
|
|
||||||
|
debugLighttpd() {
|
||||||
|
echo "::: Checking for necessary lighttpd files."
|
||||||
|
files_check "${LIGHTTPDFILE}"
|
||||||
|
files_check "${LIGHTTPDERRFILE}"
|
||||||
|
echo ":::"
|
||||||
|
}
|
||||||
|
|
||||||
|
countdown() {
|
||||||
|
tuvix=${TIMEOUT}
|
||||||
|
printf "::: Logging will automatically teminate in ${TIMEOUT} seconds\n"
|
||||||
|
while [ $tuvix -ge 1 ]
|
||||||
|
do
|
||||||
|
printf ":::\t${tuvix} seconds left. \r"
|
||||||
|
sleep 5
|
||||||
|
tuvix=$(( tuvix - 5 ))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
### END FUNCTIONS ###
|
||||||
|
|
||||||
|
# Gather version of required packages / repositories
|
||||||
|
version_check || echo "REQUIRED FILES MISSING"
|
||||||
|
# Check for newer setupVars storage file
|
||||||
|
source_file "/etc/pihole/setupVars.conf"
|
||||||
|
# Gather information about the running distribution
|
||||||
|
distro_check || echo "Distro Check soft fail"
|
||||||
|
# Gather processor type
|
||||||
|
processor_check || echo "Processor Check soft fail"
|
||||||
|
|
||||||
|
ip_check
|
||||||
|
|
||||||
|
daemon_check lighttpd http
|
||||||
|
daemon_check dnsmasq domain
|
||||||
|
checkProcesses
|
||||||
|
testResolver
|
||||||
|
debugLighttpd
|
||||||
|
|
||||||
|
files_check "${DNSMASQFILE}"
|
||||||
|
files_check "${DNSMASQCONFFILE}"
|
||||||
|
files_check "${WHITELISTFILE}"
|
||||||
|
files_check "${BLACKLISTFILE}"
|
||||||
|
files_check "${ADLISTFILE}"
|
||||||
|
|
||||||
|
|
||||||
|
header_write "Analyzing gravity.list"
|
||||||
|
|
||||||
|
gravity_length=$(wc -l "${GRAVITYFILE}") \
|
||||||
|
&& log_write "${GRAVITYFILE} is ${gravity_length} lines long." \
|
||||||
|
|| log_echo "Warning: No gravity.list file found!"
|
||||||
|
|
||||||
|
# Continuously append the pihole.log file to the pihole_debug.log file
|
||||||
|
dumpPiHoleLog() {
|
||||||
|
trap '{ echo -e "\n::: Finishing debug write from interrupt... Quitting!" ; exit 1; }' INT
|
||||||
|
echo "::: "
|
||||||
|
echo "::: --= User Action Required =--"
|
||||||
|
echo -e "::: Try loading a site that you are having trouble with now from a client web browser.. \n:::\t(Press CTRL+C to finish logging.)"
|
||||||
|
header_write "pihole.log"
|
||||||
|
if [ -e "${PIHOLELOG}" ]; then
|
||||||
|
# Dummy process to use for flagging down tail to terminate
|
||||||
|
countdown &
|
||||||
|
tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG}
|
||||||
|
else
|
||||||
|
log_write "No pihole.log file found!"
|
||||||
|
printf ":::\tNo pihole.log file found!\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Anything to be done after capturing of pihole.log terminates
|
||||||
|
finalWork() {
|
||||||
|
local tricorder
|
||||||
|
echo "::: Finshed debugging!"
|
||||||
|
echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
|
||||||
|
read -r -p "::: Would you like to upload the log? [y/N] " response
|
||||||
|
case ${response} in
|
||||||
|
[yY][eE][sS]|[yY])
|
||||||
|
tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "::: Log will NOT be uploaded to tricorder."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if tricorder.pi-hole.net is reachable and provide token.
|
||||||
|
if [ -n "${tricorder}" ]; then
|
||||||
|
echo "::: Your debug token is : ${tricorder}"
|
||||||
|
echo "::: Please contact the Pi-hole team with your token for assistance."
|
||||||
|
echo "::: Thank you."
|
||||||
|
else
|
||||||
|
echo "::: There was an error uploading your debug log."
|
||||||
|
echo "::: Please try again or contact the Pi-hole team for assistance."
|
||||||
|
fi
|
||||||
|
echo "::: A local copy of the Debug log can be found at : /var/log/pihole_debug.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap finalWork EXIT
|
||||||
|
|
||||||
|
### Method calls for additional logging ###
|
||||||
|
dumpPiHoleLog
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
# Flushes /var/log/pihole.log
|
# Flushes /var/log/pihole.log
|
||||||
# (c) 2015 by Jacob Salmela
|
|
||||||
# This file is part of Pi-hole.
|
|
||||||
#
|
#
|
||||||
#Pi-hole is free software: you can redistribute it and/or modify
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
#it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
#the Free Software Foundation, either version 2 of the License, or
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
#(at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
truncate -s 0 /var/log/pihole.log
|
echo -n "::: Flushing /var/log/pihole.log ..."
|
||||||
|
echo " " > /var/log/pihole.log
|
||||||
|
echo "... done!"
|
||||||
|
|||||||
74
advanced/Scripts/setupLCD.sh
Executable file
74
advanced/Scripts/setupLCD.sh
Executable file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Automatically configures the Pi to use the 2.8 LCD screen to display stats on it (also works over ssh)
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
############ FUNCTIONS ###########
|
||||||
|
|
||||||
|
# Borrowed from adafruit-pitft-helper < borrowed from raspi-config
|
||||||
|
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334
|
||||||
|
getInitSys() {
|
||||||
|
if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
|
||||||
|
SYSTEMD=1
|
||||||
|
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
|
||||||
|
SYSTEMD=0
|
||||||
|
else
|
||||||
|
echo "Unrecognised init system"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Borrowed from adafruit-pitft-helper:
|
||||||
|
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285
|
||||||
|
autoLoginPiToConsole() {
|
||||||
|
if [ -e /etc/init.d/lightdm ]; then
|
||||||
|
if [ ${SYSTEMD} -eq 1 ]; then
|
||||||
|
systemctl set-default multi-user.target
|
||||||
|
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
|
||||||
|
else
|
||||||
|
update-rc.d lightdm disable 2
|
||||||
|
sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
######### SCRIPT ###########
|
||||||
|
# Set pi to log in automatically
|
||||||
|
getInitSys
|
||||||
|
autoLoginPiToConsole
|
||||||
|
|
||||||
|
# Set chronomter to run automatically when pi logs in
|
||||||
|
echo /usr/local/bin/chronometer.sh >> /home/pi/.bashrc
|
||||||
|
# OR
|
||||||
|
#$SUDO echo /usr/local/bin/chronometer.sh >> /etc/profile
|
||||||
|
|
||||||
|
# Set up the LCD screen based on Adafruits instuctions:
|
||||||
|
# https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/easy-install
|
||||||
|
curl -SLs https://apt.adafruit.com/add-pin | bash
|
||||||
|
apt-get -y install raspberrypi-bootloader
|
||||||
|
apt-get -y install adafruit-pitft-helper
|
||||||
|
adafruit-pitft-helper -t 28r
|
||||||
|
|
||||||
|
# Download the cmdline.txt file that prevents the screen from going blank after a period of time
|
||||||
|
mv /boot/cmdline.txt /boot/cmdline.orig
|
||||||
|
curl -o /boot/cmdline.txt https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/cmdline.txt
|
||||||
|
|
||||||
|
# Back up the original file and download the new one
|
||||||
|
mv /etc/default/console-setup /etc/default/console-setup.orig
|
||||||
|
curl -o /etc/default/console-setup https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/console-setup
|
||||||
|
|
||||||
|
# Instantly apply the font change to the LCD screen
|
||||||
|
setupcon
|
||||||
|
|
||||||
|
reboot
|
||||||
|
|
||||||
|
# Start showing the stats on the screen by running the command on another tty:
|
||||||
|
# http://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
|
||||||
|
#setsid sh -c 'exec /usr/local/bin/chronometer.sh <> /dev/tty1 >&0 2>&1'
|
||||||
194
advanced/Scripts/update.sh
Executable file
194
advanced/Scripts/update.sh
Executable file
@@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Check Pi-hole core and admin pages versions and determine what
|
||||||
|
# upgrade (if any) is required. Automatically updates and reinstalls
|
||||||
|
# application if update is detected.
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
|
||||||
|
readonly ADMIN_INTERFACE_GIT_URL="https://github.com/pi-hole/AdminLTE.git"
|
||||||
|
readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
|
||||||
|
readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
|
||||||
|
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
|
||||||
|
|
||||||
|
is_repo() {
|
||||||
|
# Use git to check if directory is currently under VCS, return the value
|
||||||
|
local directory="${1}"
|
||||||
|
local curdir
|
||||||
|
local rc
|
||||||
|
|
||||||
|
curdir="${PWD}"
|
||||||
|
cd "${directory}" &> /dev/null || return 1
|
||||||
|
git status --short &> /dev/null
|
||||||
|
rc=$?
|
||||||
|
cd "${curdir}" &> /dev/null || return 1
|
||||||
|
return "${rc}"
|
||||||
|
}
|
||||||
|
|
||||||
|
prep_repo() {
|
||||||
|
# Prepare directory for local repository building
|
||||||
|
local directory="${1}"
|
||||||
|
|
||||||
|
rm -rf "${directory}" &> /dev/null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
make_repo() {
|
||||||
|
# Remove the non-repod interface and clone the interface
|
||||||
|
local remoteRepo="${2}"
|
||||||
|
local directory="${1}"
|
||||||
|
|
||||||
|
(prep_repo "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
update_repo() {
|
||||||
|
local directory="${1}"
|
||||||
|
local curdir
|
||||||
|
|
||||||
|
curdir="${PWD}"
|
||||||
|
cd "${directory}" &> /dev/null || return 1
|
||||||
|
# Pull the latest commits
|
||||||
|
# Stash all files not tracked for later retrieval
|
||||||
|
git stash --all --quiet
|
||||||
|
# Force a clean working directory for cloning
|
||||||
|
git clean --force -d
|
||||||
|
# Fetch latest changes and apply
|
||||||
|
git pull --quiet
|
||||||
|
cd "${curdir}" &> /dev/null || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
getGitFiles() {
|
||||||
|
# Setup git repos for directory and repository passed
|
||||||
|
# as arguments 1 and 2
|
||||||
|
local directory="${1}"
|
||||||
|
local remoteRepo="${2}"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Checking for existing repository..."
|
||||||
|
if is_repo "${directory}"; then
|
||||||
|
echo -n "::: Updating repository in ${directory}..."
|
||||||
|
update_repo "${directory}" || (echo "*** Error: Could not update local repository. Contact support."; exit 1)
|
||||||
|
echo " done!"
|
||||||
|
else
|
||||||
|
echo -n "::: Cloning ${remoteRepo} into ${directory}..."
|
||||||
|
make_repo "${directory}" "${remoteRepo}" || (echo "Unable to clone repository, please contact support"; exit 1)
|
||||||
|
echo " done!"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
GitCheckUpdateAvail() {
|
||||||
|
local directory="${1}"
|
||||||
|
curdir=$PWD;
|
||||||
|
cd "${directory}"
|
||||||
|
|
||||||
|
# Fetch latest changes in this repo
|
||||||
|
git fetch --quiet origin
|
||||||
|
status="$(git status -sb)"
|
||||||
|
|
||||||
|
# Change back to original directory
|
||||||
|
cd "${curdir}"
|
||||||
|
|
||||||
|
if [[ $status == *"behind"* ]]; then
|
||||||
|
# Local branch is behind remote branch -> Update
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
# Local branch is up-to-date or in a situation
|
||||||
|
# where this updater cannot be used (like on a
|
||||||
|
# branch that exists only locally)
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local pihole_version_current
|
||||||
|
local web_version_current
|
||||||
|
|
||||||
|
#This is unlikely
|
||||||
|
if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then
|
||||||
|
echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
|
||||||
|
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "::: Checking for updates..."
|
||||||
|
|
||||||
|
if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}" ; then
|
||||||
|
core_update=true
|
||||||
|
echo "::: Pi-hole Core: update available"
|
||||||
|
else
|
||||||
|
core_update=false
|
||||||
|
echo "::: Pi-hole Core: up to date"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}" ; then
|
||||||
|
web_update=true
|
||||||
|
echo "::: Web Interface: update available"
|
||||||
|
else
|
||||||
|
web_update=false
|
||||||
|
echo "::: Web Interface: up to date"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Logic
|
||||||
|
# If Core up to date AND web up to date:
|
||||||
|
# Do nothing
|
||||||
|
# If Core up to date AND web NOT up to date:
|
||||||
|
# Pull web repo
|
||||||
|
# If Core NOT up to date AND web up to date:
|
||||||
|
# pull pihole repo, run install --unattended -- reconfigure
|
||||||
|
# if Core NOT up to date AND web NOT up to date:
|
||||||
|
# pull pihole repo run install --unattended
|
||||||
|
|
||||||
|
if ! ${core_update} && ! ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Everything is up to date!"
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
elif ! ${core_update} && ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Pi-hole Web Admin files out of date"
|
||||||
|
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
|
||||||
|
|
||||||
|
elif ${core_update} && ! ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Pi-hole core files out of date"
|
||||||
|
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
||||||
|
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
||||||
|
|
||||||
|
elif ${core_update} && ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Updating Everything"
|
||||||
|
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
||||||
|
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
||||||
|
else
|
||||||
|
echo "*** Update script has malfunctioned, fallthrough reached. Please contact support"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${web_update}" == true ]]; then
|
||||||
|
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Web Admin version is now at ${web_version_current}"
|
||||||
|
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${core_update}" == true ]]; then
|
||||||
|
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Pi-hole version is now at ${pihole_version_current}"
|
||||||
|
echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
#
|
|
||||||
# this script will update the pihole web interface files.
|
|
||||||
#
|
|
||||||
# if this is the first time running this script after an
|
|
||||||
# existing installation, the existing web interface files
|
|
||||||
# will be removed and replaced with the latest master
|
|
||||||
# branch from github. subsequent executions of this script
|
|
||||||
# will pull the latest version of the web interface.
|
|
||||||
#
|
|
||||||
# @TODO: add git as requirement to basic-install.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
WEB_INTERFACE_GIT_URL="https://github.com/pi-hole/AdminLTE.git"
|
|
||||||
WEB_INTERFACE_DIR="/var/www/html/admin"
|
|
||||||
|
|
||||||
main() {
|
|
||||||
prerequisites
|
|
||||||
if ! is_repo; then
|
|
||||||
make_repo
|
|
||||||
fi
|
|
||||||
update_repo
|
|
||||||
}
|
|
||||||
|
|
||||||
prerequisites() {
|
|
||||||
|
|
||||||
# must be root to update
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
sudo bash "$0" "$@"
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# web interface must already exist. this is a (lazy)
|
|
||||||
# check to make sure pihole is actually installed.
|
|
||||||
if [ ! -d "$WEB_INTERFACE_DIR" ]; then
|
|
||||||
echo "$WEB_INTERFACE_DIR not found. Exiting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! type "git" > /dev/null; then
|
|
||||||
apt-get -y install git
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_repo() {
|
|
||||||
# if the web interface directory does not have a .git folder
|
|
||||||
# it means its using the master.zip archive from the install
|
|
||||||
# script.
|
|
||||||
if [ ! -d "$WEB_INTERFACE_DIR/.git" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# removes the web interface installed from the master.zip archive and
|
|
||||||
# replaces it with the current master branch from github
|
|
||||||
make_repo() {
|
|
||||||
# remove the non-repod interface and clone the interface
|
|
||||||
rm -rf $WEB_INTERFACE_DIR
|
|
||||||
git clone "$WEB_INTERFACE_GIT_URL" "$WEB_INTERFACE_DIR"
|
|
||||||
}
|
|
||||||
|
|
||||||
# pulls the latest master branch from github
|
|
||||||
update_repo() {
|
|
||||||
# pull the latest commits
|
|
||||||
cd "$WEB_INTERFACE_DIR"
|
|
||||||
git pull
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
102
advanced/Scripts/version.sh
Executable file
102
advanced/Scripts/version.sh
Executable file
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# shows version numbers
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# Flags:
|
||||||
|
latest=false
|
||||||
|
current=false
|
||||||
|
|
||||||
|
DEFAULT="-1"
|
||||||
|
|
||||||
|
normalOutput() {
|
||||||
|
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
|
||||||
|
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
|
||||||
|
|
||||||
|
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
|
||||||
|
echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest:-${DEFAULT}})"
|
||||||
|
echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest:-${DEFAULT}})"
|
||||||
|
}
|
||||||
|
|
||||||
|
webOutput() {
|
||||||
|
for var in "$@"; do
|
||||||
|
case "${var}" in
|
||||||
|
"-l" | "--latest" ) latest=true;;
|
||||||
|
"-c" | "--current" ) current=true;;
|
||||||
|
* ) echo "::: Invalid Option!"; exit 1;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${latest}" == true && "${current}" == false ]]; then
|
||||||
|
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
echo "${webVersionLatest:--1}"
|
||||||
|
elif [[ "${latest}" == false && "${current}" == true ]]; then
|
||||||
|
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
|
||||||
|
echo "${webVersion}"
|
||||||
|
else
|
||||||
|
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
|
||||||
|
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest:-${DEFAULT}})"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
coreOutput() {
|
||||||
|
for var in "$@"; do
|
||||||
|
case "${var}" in
|
||||||
|
"-l" | "--latest" ) latest=true;;
|
||||||
|
"-c" | "--current" ) current=true;;
|
||||||
|
* ) echo "::: Invalid Option!"; exit 1;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${latest}" == true && "${current}" == false ]]; then
|
||||||
|
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
echo "${piholeVersionLatest:--1}"
|
||||||
|
elif [[ "${latest}" == false && "${current}" == true ]]; then
|
||||||
|
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
|
||||||
|
echo "${piholeVersion}"
|
||||||
|
else
|
||||||
|
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
|
||||||
|
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
|
||||||
|
echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest:-${DEFAULT}})"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
cat << EOM
|
||||||
|
:::
|
||||||
|
::: Show Pi-hole/Web Admin versions
|
||||||
|
:::
|
||||||
|
::: Usage: pihole -v [ -a | -p ] [ -l | -c ]
|
||||||
|
:::
|
||||||
|
::: Options:
|
||||||
|
::: -a, --admin Show both current and latest versions of web admin
|
||||||
|
::: -p, --pihole Show both current and latest versions of Pi-hole core files
|
||||||
|
::: -l, --latest (Only after -a | -p) Return only latest version
|
||||||
|
::: -c, --current (Only after -a | -p) Return only current version
|
||||||
|
::: -h, --help Show this help dialog
|
||||||
|
:::
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# = 0 ]]; then
|
||||||
|
normalOutput
|
||||||
|
fi
|
||||||
|
|
||||||
|
for var in "$@"; do
|
||||||
|
case "${var}" in
|
||||||
|
"-a" | "--admin" ) shift; webOutput "$@";;
|
||||||
|
"-p" | "--pihole" ) shift; coreOutput "$@" ;;
|
||||||
|
"-h" | "--help" ) helpFunc;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
318
advanced/Scripts/webpage.sh
Executable file
318
advanced/Scripts/webpage.sh
Executable file
@@ -0,0 +1,318 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Web interface settings
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
readonly setupVars="/etc/pihole/setupVars.conf"
|
||||||
|
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
|
||||||
|
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
cat << EOM
|
||||||
|
::: Set admin options for the web interface of pihole
|
||||||
|
:::
|
||||||
|
::: Usage: pihole -a [options]
|
||||||
|
:::
|
||||||
|
::: Options:
|
||||||
|
::: -p, password Set web interface password, an empty input will remove any previously set password
|
||||||
|
::: -c, celsius Set Celsius temperature unit
|
||||||
|
::: -f, fahrenheit Set Fahrenheit temperature unit
|
||||||
|
::: -k, kelvin Set Kelvin temperature unit
|
||||||
|
::: -h, --help Show this help dialog
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
add_setting() {
|
||||||
|
echo "${1}=${2}" >> "${setupVars}"
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_setting() {
|
||||||
|
sed -i "/${1}/d" "${setupVars}"
|
||||||
|
}
|
||||||
|
|
||||||
|
change_setting() {
|
||||||
|
delete_setting "${1}"
|
||||||
|
add_setting "${1}" "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
add_dnsmasq_setting() {
|
||||||
|
if [[ "${2}" != "" ]]; then
|
||||||
|
echo "${1}=${2}" >> "${dnsmasqconfig}"
|
||||||
|
else
|
||||||
|
echo "${1}" >> "${dnsmasqconfig}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_dnsmasq_setting() {
|
||||||
|
sed -i "/${1}/d" "${dnsmasqconfig}"
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTemperatureUnit(){
|
||||||
|
|
||||||
|
change_setting "TEMPERATUREUNIT" "${unit}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWebPassword(){
|
||||||
|
|
||||||
|
if [ "${SUDO_USER}" == "www-data" ]; then
|
||||||
|
echo "Security measure: user www-data is not allowed to change webUI password!"
|
||||||
|
echo "Exiting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${SUDO_USER}" == "lighttpd" ]; then
|
||||||
|
echo "Security measure: user lighttpd is not allowed to change webUI password!"
|
||||||
|
echo "Exiting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set password only if there is one to be set
|
||||||
|
if (( ${#args[2]} > 0 )) ; then
|
||||||
|
# Compute password hash twice to avoid rainbow table vulnerability
|
||||||
|
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
|
||||||
|
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
|
||||||
|
# Save hash to file
|
||||||
|
change_setting "WEBPASSWORD" "${hash}"
|
||||||
|
echo "New password set"
|
||||||
|
else
|
||||||
|
change_setting "WEBPASSWORD" ""
|
||||||
|
echo "Password removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessDNSSettings() {
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
delete_dnsmasq_setting "server="
|
||||||
|
add_dnsmasq_setting "server" "${PIHOLE_DNS_1}"
|
||||||
|
|
||||||
|
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
|
||||||
|
add_dnsmasq_setting "server" "${PIHOLE_DNS_2}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
delete_dnsmasq_setting "domain-needed"
|
||||||
|
|
||||||
|
if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then
|
||||||
|
add_dnsmasq_setting "domain-needed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
delete_dnsmasq_setting "bogus-priv"
|
||||||
|
|
||||||
|
if [[ "${DNS_BOGUS_PRIV}" == true ]]; then
|
||||||
|
add_dnsmasq_setting "bogus-priv"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDNSServers(){
|
||||||
|
|
||||||
|
# Save setting to file
|
||||||
|
change_setting "PIHOLE_DNS_1" "${args[2]}"
|
||||||
|
|
||||||
|
if [[ "${args[3]}" != "none" ]]; then
|
||||||
|
change_setting "PIHOLE_DNS_2" "${args[3]}"
|
||||||
|
else
|
||||||
|
change_setting "PIHOLE_DNS_2" ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${args[4]}" == "domain-needed" ]]; then
|
||||||
|
change_setting "DNS_FQDN_REQUIRED" "true"
|
||||||
|
else
|
||||||
|
change_setting "DNS_FQDN_REQUIRED" "false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${args[4]}" == "bogus-priv" || "${args[5]}" == "bogus-priv" ]]; then
|
||||||
|
change_setting "DNS_BOGUS_PRIV" "true"
|
||||||
|
else
|
||||||
|
change_setting "DNS_BOGUS_PRIV" "false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ProcessDnsmasqSettings
|
||||||
|
|
||||||
|
# Restart dnsmasq to load new configuration
|
||||||
|
RestartDNS
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetExcludeDomains(){
|
||||||
|
|
||||||
|
change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetExcludeClients(){
|
||||||
|
|
||||||
|
change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Reboot(){
|
||||||
|
|
||||||
|
nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null &
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RestartDNS(){
|
||||||
|
|
||||||
|
if [ -x "$(command -v systemctl)" ]; then
|
||||||
|
systemctl restart dnsmasq &> /dev/null
|
||||||
|
else
|
||||||
|
service dnsmasq restart &> /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetQueryLogOptions(){
|
||||||
|
|
||||||
|
change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessDHCPSettings() {
|
||||||
|
|
||||||
|
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
|
||||||
|
|
||||||
|
# Use eth0 as fallback interface
|
||||||
|
if [ -z ${interface} ]; then
|
||||||
|
interface="eth0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
|
||||||
|
PIHOLE_DOMAIN="local"
|
||||||
|
change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
|
||||||
|
leasetime="infinite"
|
||||||
|
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
|
||||||
|
leasetime="24h"
|
||||||
|
change_setting "DHCP_LEASETIME" "${leasetime}"
|
||||||
|
else
|
||||||
|
leasetime="${DHCP_LEASETIME}h"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Write settings to file
|
||||||
|
echo "###############################################################################
|
||||||
|
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
|
||||||
|
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
|
||||||
|
###############################################################################
|
||||||
|
dhcp-authoritative
|
||||||
|
dhcp-range=${DHCP_START},${DHCP_END},${leasetime}
|
||||||
|
dhcp-option=option:router,${DHCP_ROUTER}
|
||||||
|
dhcp-leasefile=/etc/pihole/dhcp.leases
|
||||||
|
domain=${PIHOLE_DOMAIN}
|
||||||
|
#quiet-dhcp
|
||||||
|
#quiet-dhcp6
|
||||||
|
#enable-ra
|
||||||
|
dhcp-option=option6:dns-server,[::]
|
||||||
|
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
|
||||||
|
ra-param=*,0,0
|
||||||
|
" > "${dhcpconfig}"
|
||||||
|
|
||||||
|
else
|
||||||
|
rm "${dhcpconfig}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableDHCP(){
|
||||||
|
|
||||||
|
change_setting "DHCP_ACTIVE" "true"
|
||||||
|
change_setting "DHCP_START" "${args[2]}"
|
||||||
|
change_setting "DHCP_END" "${args[3]}"
|
||||||
|
change_setting "DHCP_ROUTER" "${args[4]}"
|
||||||
|
change_setting "DHCP_LEASETIME" "${args[5]}"
|
||||||
|
change_setting "PIHOLE_DOMAIN" "${args[6]}"
|
||||||
|
|
||||||
|
# Remove possible old setting from file
|
||||||
|
delete_dnsmasq_setting "dhcp-"
|
||||||
|
delete_dnsmasq_setting "quiet-dhcp"
|
||||||
|
|
||||||
|
ProcessDHCPSettings
|
||||||
|
|
||||||
|
RestartDNS
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableDHCP(){
|
||||||
|
|
||||||
|
change_setting "DHCP_ACTIVE" "false"
|
||||||
|
|
||||||
|
# Remove possible old setting from file
|
||||||
|
delete_dnsmasq_setting "dhcp-"
|
||||||
|
delete_dnsmasq_setting "quiet-dhcp"
|
||||||
|
|
||||||
|
ProcessDHCPSettings
|
||||||
|
|
||||||
|
RestartDNS
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWebUILayout(){
|
||||||
|
|
||||||
|
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPrivacyMode(){
|
||||||
|
|
||||||
|
if [[ "${args[2]}" == "true" ]] ; then
|
||||||
|
change_setting "API_PRIVACY_MODE" "true"
|
||||||
|
else
|
||||||
|
change_setting "API_PRIVACY_MODE" "false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolutionSettings() {
|
||||||
|
|
||||||
|
typ="${args[2]}"
|
||||||
|
state="${args[3]}"
|
||||||
|
|
||||||
|
if [[ "${typ}" == "forward" ]]; then
|
||||||
|
change_setting "API_GET_UPSTREAM_DNS_HOSTNAME" "${state}"
|
||||||
|
elif [[ "${typ}" == "clients" ]]; then
|
||||||
|
change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
args=("$@")
|
||||||
|
|
||||||
|
case "${args[1]}" in
|
||||||
|
"-p" | "password" ) SetWebPassword;;
|
||||||
|
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
|
||||||
|
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
|
||||||
|
"-k" | "kelvin" ) unit="K"; SetTemperatureUnit;;
|
||||||
|
"setdns" ) SetDNSServers;;
|
||||||
|
"setexcludedomains" ) SetExcludeDomains;;
|
||||||
|
"setexcludeclients" ) SetExcludeClients;;
|
||||||
|
"reboot" ) Reboot;;
|
||||||
|
"restartdns" ) RestartDNS;;
|
||||||
|
"setquerylog" ) SetQueryLogOptions;;
|
||||||
|
"enabledhcp" ) EnableDHCP;;
|
||||||
|
"disabledhcp" ) DisableDHCP;;
|
||||||
|
"layout" ) SetWebUILayout;;
|
||||||
|
"-h" | "--help" ) helpFunc;;
|
||||||
|
"privacymode" ) SetPrivacyMode;;
|
||||||
|
"resolve" ) ResolutionSettings;;
|
||||||
|
* ) helpFunc;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ $# = 0 ]]; then
|
||||||
|
helpFunc
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# (c) 2015 by Jacob Salmela
|
|
||||||
# This file is part of Pi-hole.
|
|
||||||
#
|
|
||||||
# Pi-hole is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
if [[ $# = 0 ]]; then
|
|
||||||
echo "Immediately whitelists one or more domains in the hosts file"
|
|
||||||
echo " "
|
|
||||||
echo "Usage: whitelist.sh domain1 [domain2 ...]"
|
|
||||||
echo " "
|
|
||||||
echo "Options:"
|
|
||||||
echo " -d, --delmode Remove domains from the whitelist"
|
|
||||||
echo " -nr, --noreload Update Whitelist without refreshing dnsmasq"
|
|
||||||
echo " -f, --force Force updating of the hosts files, even if there are no changes"
|
|
||||||
echo " -q, --quiet output is less verbose"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#globals
|
|
||||||
whitelist=/etc/pihole/whitelist.txt
|
|
||||||
adList=/etc/pihole/gravity.list
|
|
||||||
reload=true
|
|
||||||
addmode=true
|
|
||||||
force=false
|
|
||||||
versbose=true
|
|
||||||
domList=()
|
|
||||||
domToRemoveList=()
|
|
||||||
|
|
||||||
piholeIPfile=/tmp/piholeIP
|
|
||||||
piholeIPv6file=/etc/pihole/.useIPv6
|
|
||||||
|
|
||||||
# Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script
|
|
||||||
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
|
|
||||||
piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}')
|
|
||||||
piholeIP=${piholeIPCIDR%/*}
|
|
||||||
|
|
||||||
modifyHost=false
|
|
||||||
|
|
||||||
|
|
||||||
if [[ -f $piholeIPv6file ]];then
|
|
||||||
# If the file exists, then the user previously chose to use IPv6 in the automated installer
|
|
||||||
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
function HandleOther(){
|
|
||||||
#check validity of domain
|
|
||||||
validDomain=$(echo $1 | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
|
|
||||||
|
|
||||||
if [ -z "$validDomain" ]; then
|
|
||||||
echo "::: $1 is not a valid argument or domain name"
|
|
||||||
else
|
|
||||||
domList=("${domList[@]}" $validDomain)
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function PopWhitelistFile(){
|
|
||||||
#check whitelist file exists, and if not, create it
|
|
||||||
if [[ ! -f $whitelist ]];then
|
|
||||||
touch $whitelist
|
|
||||||
fi
|
|
||||||
for dom in "${domList[@]}"
|
|
||||||
do
|
|
||||||
if $addmode; then
|
|
||||||
AddDomain $dom
|
|
||||||
else
|
|
||||||
RemoveDomain $dom
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddDomain(){
|
|
||||||
#| sed 's/\./\\./g'
|
|
||||||
bool=false
|
|
||||||
|
|
||||||
grep -Ex -q "$1" $whitelist || bool=true
|
|
||||||
if $bool; then
|
|
||||||
#domain not found in the whitelist file, add it!
|
|
||||||
if $versbose; then
|
|
||||||
echo -n "::: Adding $1 to whitelist.txt..."
|
|
||||||
fi
|
|
||||||
echo $1 >> $whitelist
|
|
||||||
modifyHost=true
|
|
||||||
if $versbose; then
|
|
||||||
echo " done!"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: $1 already exists in whitelist.txt, no need to add!"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function RemoveDomain(){
|
|
||||||
|
|
||||||
bool=false
|
|
||||||
grep -Ex -q "$1" $whitelist || bool=true
|
|
||||||
if $bool; then
|
|
||||||
#Domain is not in the whitelist file, no need to Remove
|
|
||||||
if $versbose; then
|
|
||||||
echo "::: $1 is NOT whitelisted! No need to remove"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
#Domain is in the whitelist file, add to a temporary array and remove from whitelist file
|
|
||||||
#if $versbose; then
|
|
||||||
#echo "::: Un-whitelisting $dom..."
|
|
||||||
#fi
|
|
||||||
domToRemoveList=("${domToRemoveList[@]}" $1)
|
|
||||||
modifyHost=true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function ModifyHostFile(){
|
|
||||||
if $addmode; then
|
|
||||||
#remove domains in from hosts file
|
|
||||||
if [[ -r $whitelist ]];then
|
|
||||||
# Remove whitelist entries
|
|
||||||
numberOf=$(cat $whitelist | sed '/^\s*$/d' | wc -l)
|
|
||||||
plural=; [[ "$numberOf" != "1" ]] && plural=s
|
|
||||||
echo ":::"
|
|
||||||
echo -n "::: Modifying HOSTS file to whitelist $numberOf domain${plural}..."
|
|
||||||
awk -F':' '{print $1}' $whitelist | while read line; do echo "$piholeIP $line"; done > /etc/pihole/whitelist.tmp
|
|
||||||
awk -F':' '{print $1}' $whitelist | while read line; do echo "$piholeIPv6 $line"; done >> /etc/pihole/whitelist.tmp
|
|
||||||
echo "l" >> /etc/pihole/whitelist.tmp
|
|
||||||
grep -F -x -v -f /etc/pihole/whitelist.tmp /etc/pihole/gravity.list > /etc/pihole/gravity.tmp
|
|
||||||
rm /etc/pihole/gravity.list
|
|
||||||
mv /etc/pihole/gravity.tmp /etc/pihole/gravity.list
|
|
||||||
rm /etc/pihole/whitelist.tmp
|
|
||||||
echo " done!"
|
|
||||||
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
#we need to add the removed domains to the hosts file
|
|
||||||
echo ":::"
|
|
||||||
echo "::: Modifying HOSTS file to un-whitelist domains..."
|
|
||||||
for rdom in "${domToRemoveList[@]}"
|
|
||||||
do
|
|
||||||
if [[ -n $piholeIPv6 ]];then
|
|
||||||
echo -n "::: Un-whitelisting $rdom on IPv4 and IPv6..."
|
|
||||||
echo $rdom | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList
|
|
||||||
echo " done!"
|
|
||||||
else
|
|
||||||
echo -n "::: Un-whitelisting $rdom on IPv4"
|
|
||||||
echo $rdom | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList
|
|
||||||
echo " done!"
|
|
||||||
fi
|
|
||||||
echo -n "::: Removing $rdom from whitelist.txt..."
|
|
||||||
echo $rdom| sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $whitelist
|
|
||||||
echo " done!"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function Reload() {
|
|
||||||
# Reload hosts file
|
|
||||||
echo ":::"
|
|
||||||
echo -n "::: Refresh lists in dnsmasq..."
|
|
||||||
dnsmasqPid=$(pidof dnsmasq)
|
|
||||||
|
|
||||||
if [[ $dnsmasqPid ]]; then
|
|
||||||
# service already running - reload config
|
|
||||||
sudo kill -HUP $dnsmasqPid
|
|
||||||
else
|
|
||||||
# service not running, start it up
|
|
||||||
sudo service dnsmasq start
|
|
||||||
fi
|
|
||||||
echo " done!"
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
for var in "$@"
|
|
||||||
do
|
|
||||||
case "$var" in
|
|
||||||
"-nr"| "--noreload" ) reload=false;;
|
|
||||||
"-d" | "--delmode" ) addmode=false;;
|
|
||||||
"-f" | "--force" ) force=true;;
|
|
||||||
"-q" | "--quiet" ) versbose=false;;
|
|
||||||
* ) HandleOther $var;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
PopWhitelistFile
|
|
||||||
|
|
||||||
if $modifyHost || $force; then
|
|
||||||
ModifyHostFile
|
|
||||||
else
|
|
||||||
if $versbose; then
|
|
||||||
echo ":::"
|
|
||||||
echo "::: No changes need to be made"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $reload; then
|
|
||||||
Reload
|
|
||||||
fi
|
|
||||||
11
advanced/bash-completion/pihole
Normal file
11
advanced/bash-completion/pihole
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
_pihole() {
|
||||||
|
local cur prev opts
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
opts="admin blacklist chronometer debug disable enable flush help logging query reconfigure restartdns setupLCD status tail uninstall updateGravity updatePihole version whitelist"
|
||||||
|
|
||||||
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
complete -F _pihole pihole
|
||||||
136
advanced/blockingpage.css
Normal file
136
advanced/blockingpage.css
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/* CSS Reset */
|
||||||
|
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; }
|
||||||
|
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
|
||||||
|
body { line-height: 1; }
|
||||||
|
ol, ul { list-style: none; }
|
||||||
|
blockquote, q { quotes: none; }
|
||||||
|
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
|
||||||
|
table { border-collapse: collapse; border-spacing: 0; }
|
||||||
|
html { height: 100%; overflow-x: hidden; }
|
||||||
|
|
||||||
|
/* General Style */
|
||||||
|
a { color: rgba(0,60,120,0.95); text-decoration: none; } /* 1E3C5A */
|
||||||
|
a:hover { color: rgba(210,120,0,0.95); transition-duration: .2s; } /* 255, 128, 0 */
|
||||||
|
divs a { border-bottom: 1px dashed rgba(30,60,90,0.3); }
|
||||||
|
b { font-weight: bold; }
|
||||||
|
i { font-style: italic; }
|
||||||
|
|
||||||
|
footer, pre, td { font-family: monospace; padding-left: 15px; }
|
||||||
|
/*body, header { background: #E1E1E1; }*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(240,240,240,0.95), rgba(190,190,190,0.95));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(240,240,240,0.95), rgba(190,190,190,0.95));
|
||||||
|
background-attachment: fixed;
|
||||||
|
color: rgba(64,64,64,0.95);
|
||||||
|
font: 14px, sans-serif;
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
min-width: 320px;
|
||||||
|
width: 100%;
|
||||||
|
text-shadow: 0 1px rgba(255,255,255,0.6);
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
border-top-color: rgba(255,255,255,0.85);
|
||||||
|
border-style: solid none;
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(240,240,240,0.95), rgba(220,220,220,0.95));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(240,240,240,0.95), rgba(220,220,220,0.95));
|
||||||
|
box-shadow: 0 0 1px 1px rgba(0,0,0,0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1, header div {
|
||||||
|
display: table-cell;
|
||||||
|
color: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 0;
|
||||||
|
text-indent: 32px;
|
||||||
|
background: url("http://pi.hole/admin/img/logo.svg") left no-repeat;
|
||||||
|
background-size: 30px 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 a, h1 a:hover { color: inherit; }
|
||||||
|
header .alt { width: 85px; font-size: 0.8em; padding-right: 4px; text-align: right; line-height: 1.25em; }
|
||||||
|
.active { color: green; }
|
||||||
|
.inactive { color: red; }
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: block;
|
||||||
|
width: 80%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: rgba(255,255,255,0.85);
|
||||||
|
margin: 8px auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
box-shadow: 4px 4px rgba(0,0,0,0.1);
|
||||||
|
line-height: 1.2em;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 { /* Rgba is shared with .transparent th */
|
||||||
|
font: 1.15em sans-serif;
|
||||||
|
background-color: rgba(255,0,0,0.4);
|
||||||
|
text-shadow: none;
|
||||||
|
line-height: 1.1em;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
background: -webkit-linear-gradient(left, rgba(0,0,0,0.25), transparent 80%) no-repeat;
|
||||||
|
background: linear-gradient(to right, rgba(0,0,0,0.25), transparent 80%) no-repeat;
|
||||||
|
background-size: 100% 1px;
|
||||||
|
background-position: 0 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2:first-child { margin-top: 0; }
|
||||||
|
h2 ~ *:not(h2) { margin-left: 4px; }
|
||||||
|
li { padding: 2px 0; }
|
||||||
|
li::before { content: "\00BB\00a0"; }
|
||||||
|
li a { position: relative; top: 1px; } /* Center bullet-point arrows */
|
||||||
|
|
||||||
|
/* Button Style */
|
||||||
|
.buttons a, button, input, .transparent th a { /* Swapped rgba is shared with input[type='url'] */
|
||||||
|
display: inline-block;
|
||||||
|
color: rgba(32,32,32,0.9);
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-shadow: 0 1px rgba(255,255,255,0.2);
|
||||||
|
line-height: 0.86em;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background: #FAFAFA;
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.05), rgba(0,0,0,0.05));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(255,255,255,0.05), rgba(0,0,0,0.05));
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 1px 0 rgba(0,0,0,0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons { white-space: nowrap; width: 100%; display: table; }
|
||||||
|
.buttons33 { white-space: nowrap; width: 33.333%; display: table; text-align: center; margin-left: 33.333% }
|
||||||
|
.mini a { width: 50%; }
|
||||||
|
a.safe { background-color: rgba(0,220,0,0.5); }
|
||||||
|
button.safe { background-color: rgba(0,220,0,0.5); }
|
||||||
|
a.warn { background-color: rgba(220,0,0,0.5); }
|
||||||
|
|
||||||
|
.blocked a, .mini a { display: table-cell; }
|
||||||
|
.blocked a.safe50 { width: 50%; background-color: rgba(0,220,0,0.5); }
|
||||||
|
.blocked a.safe33 { width: 33.333%; background-color: rgba(0,220,0,0.5); }
|
||||||
|
|
||||||
|
/* Types of text */
|
||||||
|
.msg { white-space: pre; overflow: auto; -webkit-overflow-scrolling: touch; display: block; line-height: 1.2em; font-weight: bold; font-size: 1.15em; margin: 4px 8px 8px 8px; white-space: pre-line; }
|
||||||
|
|
||||||
|
footer { font-size: 0.8em; text-align: center; width: 87%; margin: 4px auto; }
|
||||||
1
advanced/cmdline.txt
Normal file
1
advanced/cmdline.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fbcon=map:10 fbcon=font:VGA8x8 consoleblank=0
|
||||||
17
advanced/console-setup
Normal file
17
advanced/console-setup
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# CONFIGURATION FILE FOR SETUPCON
|
||||||
|
|
||||||
|
# Consult the console-setup(5) manual page.
|
||||||
|
|
||||||
|
ACTIVE_CONSOLES="/dev/tty[1-6]"
|
||||||
|
|
||||||
|
CHARMAP="UTF-8"
|
||||||
|
|
||||||
|
# For best results with the Adafruit 2.8 LCD and Pi-hole's chronometer
|
||||||
|
CODESET="guess"
|
||||||
|
FONTFACE="Terminus"
|
||||||
|
FONTSIZE="10x20"
|
||||||
|
|
||||||
|
VIDEOMODE=
|
||||||
|
|
||||||
|
# The following is an example how to use a braille font
|
||||||
|
# FONT='lat9w-08.psf.gz brl-8x8.psf'
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# If you want dnsmasq to read another file, as well as /etc/hosts, use
|
|
||||||
# this.
|
|
||||||
addn-hosts=/etc/pihole/gravity.list
|
|
||||||
|
|
||||||
# The following two options make you a better netizen, since they
|
|
||||||
# tell dnsmasq to filter out queries which the public DNS cannot
|
|
||||||
# answer, and which load the servers (especially the root servers)
|
|
||||||
# unnecessarily. If you have a dial-on-demand link they also stop
|
|
||||||
# these requests from bringing up the link unnecessarily.
|
|
||||||
|
|
||||||
# Never forward plain names (without a dot or domain part)
|
|
||||||
domain-needed
|
|
||||||
# Never forward addresses in the non-routed address spaces.
|
|
||||||
bogus-priv
|
|
||||||
|
|
||||||
# If you don't want dnsmasq to read /etc/resolv.conf or any other
|
|
||||||
# file, getting its servers from this file instead (see below), then
|
|
||||||
# uncomment this.
|
|
||||||
no-resolv
|
|
||||||
|
|
||||||
# Add other name servers here, with domain specs if they are for
|
|
||||||
# non-public domains.
|
|
||||||
server=8.8.8.8
|
|
||||||
server=8.8.4.4
|
|
||||||
|
|
||||||
# If you want dnsmasq to listen for DHCP and DNS requests only on
|
|
||||||
# specified interfaces (and the loopback) give the name of the
|
|
||||||
# interface (eg eth0) here.
|
|
||||||
interface=@INT@
|
|
||||||
# Or which to listen on by address (remember to include 127.0.0.1 if
|
|
||||||
# you use this.)
|
|
||||||
listen-address=127.0.0.1
|
|
||||||
|
|
||||||
# Set the cachesize here.
|
|
||||||
cache-size=10000
|
|
||||||
|
|
||||||
# For debugging purposes, log each DNS query as it passes through
|
|
||||||
# dnsmasq.
|
|
||||||
log-queries
|
|
||||||
log-facility=/var/log/pihole.log
|
|
||||||
|
|
||||||
# Normally responses which come from /etc/hosts and the DHCP lease
|
|
||||||
# file have Time-To-Live set as zero, which conventionally means
|
|
||||||
# do not cache further. If you are happy to trade lower load on the
|
|
||||||
# server for potentially stale date, you can set a time-to-live (in
|
|
||||||
# seconds) here.
|
|
||||||
local-ttl=300
|
|
||||||
|
|
||||||
# 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
|
|
||||||
648
advanced/dnsmasq.conf.original
Normal file
648
advanced/dnsmasq.conf.original
Normal file
@@ -0,0 +1,648 @@
|
|||||||
|
# Configuration file for dnsmasq.
|
||||||
|
#
|
||||||
|
# Format is one option per line, legal options are the same
|
||||||
|
# as the long options legal on the command line. See
|
||||||
|
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
|
||||||
|
|
||||||
|
# Listen on this specific port instead of the standard DNS port
|
||||||
|
# (53). Setting this to zero completely disables DNS function,
|
||||||
|
# leaving only DHCP and/or TFTP.
|
||||||
|
#port=5353
|
||||||
|
|
||||||
|
# The following two options make you a better netizen, since they
|
||||||
|
# tell dnsmasq to filter out queries which the public DNS cannot
|
||||||
|
# answer, and which load the servers (especially the root servers)
|
||||||
|
# unnecessarily. If you have a dial-on-demand link they also stop
|
||||||
|
# these requests from bringing up the link unnecessarily.
|
||||||
|
|
||||||
|
# Never forward plain names (without a dot or domain part)
|
||||||
|
#domain-needed
|
||||||
|
# Never forward addresses in the non-routed address spaces.
|
||||||
|
#bogus-priv
|
||||||
|
|
||||||
|
# Uncomment these to enable DNSSEC validation and caching:
|
||||||
|
# (Requires dnsmasq to be built with DNSSEC option.)
|
||||||
|
#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
|
||||||
|
#dnssec
|
||||||
|
|
||||||
|
# Replies which are not DNSSEC signed may be legitimate, because the domain
|
||||||
|
# is unsigned, or may be forgeries. Setting this option tells dnsmasq to
|
||||||
|
# check that an unsigned reply is OK, by finding a secure proof that a DS
|
||||||
|
# record somewhere between the root and the domain does not exist.
|
||||||
|
# The cost of setting this is that even queries in unsigned domains will need
|
||||||
|
# one or more extra DNS queries to verify.
|
||||||
|
#dnssec-check-unsigned
|
||||||
|
|
||||||
|
# Uncomment this to filter useless windows-originated DNS requests
|
||||||
|
# which can trigger dial-on-demand links needlessly.
|
||||||
|
# Note that (amongst other things) this blocks all SRV requests,
|
||||||
|
# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk.
|
||||||
|
# This option only affects forwarding, SRV records originating for
|
||||||
|
# dnsmasq (via srv-host= lines) are not suppressed by it.
|
||||||
|
#filterwin2k
|
||||||
|
|
||||||
|
# Change this line if you want dns to get its upstream servers from
|
||||||
|
# somewhere other that /etc/resolv.conf
|
||||||
|
#resolv-file=
|
||||||
|
|
||||||
|
# By default, dnsmasq will send queries to any of the upstream
|
||||||
|
# servers it knows about and tries to favour servers to are known
|
||||||
|
# to be up. Uncommenting this forces dnsmasq to try each query
|
||||||
|
# with each server strictly in the order they appear in
|
||||||
|
# /etc/resolv.conf
|
||||||
|
#strict-order
|
||||||
|
|
||||||
|
# If you don't want dnsmasq to read /etc/resolv.conf or any other
|
||||||
|
# file, getting its servers from this file instead (see below), then
|
||||||
|
# uncomment this.
|
||||||
|
#no-resolv
|
||||||
|
|
||||||
|
# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
|
||||||
|
# files for changes and re-read them then uncomment this.
|
||||||
|
#no-poll
|
||||||
|
|
||||||
|
# Add other name servers here, with domain specs if they are for
|
||||||
|
# non-public domains.
|
||||||
|
#server=/localnet/192.168.0.1
|
||||||
|
|
||||||
|
# Example of routing PTR queries to nameservers: this will send all
|
||||||
|
# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
|
||||||
|
#server=/3.168.192.in-addr.arpa/10.1.2.3
|
||||||
|
|
||||||
|
# Add local-only domains here, queries in these domains are answered
|
||||||
|
# from /etc/hosts or DHCP only.
|
||||||
|
#local=/localnet/
|
||||||
|
|
||||||
|
# Add domains which you want to force to an IP address here.
|
||||||
|
# The example below send any host in double-click.net to a local
|
||||||
|
# web-server.
|
||||||
|
#address=/double-click.net/127.0.0.1
|
||||||
|
|
||||||
|
# --address (and --server) work with IPv6 addresses too.
|
||||||
|
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
|
||||||
|
|
||||||
|
# Add the IPs of all queries to yahoo.com, google.com, and their
|
||||||
|
# subdomains to the vpn and search ipsets:
|
||||||
|
#ipset=/yahoo.com/google.com/vpn,search
|
||||||
|
|
||||||
|
# You can control how dnsmasq talks to a server: this forces
|
||||||
|
# queries to 10.1.2.3 to be routed via eth1
|
||||||
|
# server=10.1.2.3@eth1
|
||||||
|
|
||||||
|
# and this sets the source (ie local) address used to talk to
|
||||||
|
# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that
|
||||||
|
# IP on the machine, obviously).
|
||||||
|
# server=10.1.2.3@192.168.1.1#55
|
||||||
|
|
||||||
|
# If you want dnsmasq to change uid and gid to something other
|
||||||
|
# than the default, edit the following lines.
|
||||||
|
#user=
|
||||||
|
#group=
|
||||||
|
|
||||||
|
# If you want dnsmasq to listen for DHCP and DNS requests only on
|
||||||
|
# specified interfaces (and the loopback) give the name of the
|
||||||
|
# interface (eg eth0) here.
|
||||||
|
# Repeat the line for more than one interface.
|
||||||
|
#interface=
|
||||||
|
# Or you can specify which interface _not_ to listen on
|
||||||
|
#except-interface=
|
||||||
|
# Or which to listen on by address (remember to include 127.0.0.1 if
|
||||||
|
# you use this.)
|
||||||
|
#listen-address=
|
||||||
|
# If you want dnsmasq to provide only DNS service on an interface,
|
||||||
|
# configure it as shown above, and then use the following line to
|
||||||
|
# disable DHCP and TFTP on it.
|
||||||
|
#no-dhcp-interface=
|
||||||
|
|
||||||
|
# On systems which support it, dnsmasq binds the wildcard address,
|
||||||
|
# even when it is listening on only some interfaces. It then discards
|
||||||
|
# requests that it shouldn't reply to. This has the advantage of
|
||||||
|
# working even when interfaces come and go and change address. If you
|
||||||
|
# want dnsmasq to really bind only the interfaces it is listening on,
|
||||||
|
# uncomment this option. About the only time you may need this is when
|
||||||
|
# running another nameserver on the same machine.
|
||||||
|
#bind-interfaces
|
||||||
|
|
||||||
|
# If you don't want dnsmasq to read /etc/hosts, uncomment the
|
||||||
|
# following line.
|
||||||
|
#no-hosts
|
||||||
|
# or if you want it to read another file, as well as /etc/hosts, use
|
||||||
|
# this.
|
||||||
|
#addn-hosts=/etc/banner_add_hosts
|
||||||
|
|
||||||
|
# Set this (and domain: see below) if you want to have a domain
|
||||||
|
# automatically added to simple names in a hosts-file.
|
||||||
|
#expand-hosts
|
||||||
|
|
||||||
|
# Set the domain for dnsmasq. this is optional, but if it is set, it
|
||||||
|
# does the following things.
|
||||||
|
# 1) Allows DHCP hosts to have fully qualified domain names, as long
|
||||||
|
# as the domain part matches this setting.
|
||||||
|
# 2) Sets the "domain" DHCP option thereby potentially setting the
|
||||||
|
# domain of all systems configured by DHCP
|
||||||
|
# 3) Provides the domain part for "expand-hosts"
|
||||||
|
#domain=thekelleys.org.uk
|
||||||
|
|
||||||
|
# Set a different domain for a particular subnet
|
||||||
|
#domain=wireless.thekelleys.org.uk,192.168.2.0/24
|
||||||
|
|
||||||
|
# Same idea, but range rather then subnet
|
||||||
|
#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200
|
||||||
|
|
||||||
|
# Uncomment this to enable the integrated DHCP server, you need
|
||||||
|
# to supply the range of addresses available for lease and optionally
|
||||||
|
# a lease time. If you have more than one network, you will need to
|
||||||
|
# repeat this for each network on which you want to supply DHCP
|
||||||
|
# service.
|
||||||
|
#dhcp-range=192.168.0.50,192.168.0.150,12h
|
||||||
|
|
||||||
|
# This is an example of a DHCP range where the netmask is given. This
|
||||||
|
# is needed for networks we reach the dnsmasq DHCP server via a relay
|
||||||
|
# agent. If you don't know what a DHCP relay agent is, you probably
|
||||||
|
# don't need to worry about this.
|
||||||
|
#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h
|
||||||
|
|
||||||
|
# This is an example of a DHCP range which sets a tag, so that
|
||||||
|
# some DHCP options may be set only for this network.
|
||||||
|
#dhcp-range=set:red,192.168.0.50,192.168.0.150
|
||||||
|
|
||||||
|
# Use this DHCP range only when the tag "green" is set.
|
||||||
|
#dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h
|
||||||
|
|
||||||
|
# Specify a subnet which can't be used for dynamic address allocation,
|
||||||
|
# is available for hosts with matching --dhcp-host lines. Note that
|
||||||
|
# dhcp-host declarations will be ignored unless there is a dhcp-range
|
||||||
|
# of some type for the subnet in question.
|
||||||
|
# In this case the netmask is implied (it comes from the network
|
||||||
|
# configuration on the machine running dnsmasq) it is possible to give
|
||||||
|
# an explicit netmask instead.
|
||||||
|
#dhcp-range=192.168.0.0,static
|
||||||
|
|
||||||
|
# Enable DHCPv6. Note that the prefix-length does not need to be specified
|
||||||
|
# and defaults to 64 if missing/
|
||||||
|
#dhcp-range=1234::2, 1234::500, 64, 12h
|
||||||
|
|
||||||
|
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||||
|
#dhcp-range=1234::, ra-only
|
||||||
|
|
||||||
|
# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and
|
||||||
|
# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack
|
||||||
|
# hosts. Use the DHCPv4 lease to derive the name, network segment and
|
||||||
|
# MAC address and assume that the host will also have an
|
||||||
|
# IPv6 address calculated using the SLAAC alogrithm.
|
||||||
|
#dhcp-range=1234::, ra-names
|
||||||
|
|
||||||
|
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||||
|
# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
|
||||||
|
#dhcp-range=1234::, ra-only, 48h
|
||||||
|
|
||||||
|
# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA
|
||||||
|
# so that clients can use SLAAC addresses as well as DHCP ones.
|
||||||
|
#dhcp-range=1234::2, 1234::500, slaac
|
||||||
|
|
||||||
|
# Do Router Advertisements and stateless DHCP for this subnet. Clients will
|
||||||
|
# not get addresses from DHCP, but they will get other configuration information.
|
||||||
|
# They will use SLAAC for addresses.
|
||||||
|
#dhcp-range=1234::, ra-stateless
|
||||||
|
|
||||||
|
# Do stateless DHCP, SLAAC, and generate DNS names for SLAAC addresses
|
||||||
|
# from DHCPv4 leases.
|
||||||
|
#dhcp-range=1234::, ra-stateless, ra-names
|
||||||
|
|
||||||
|
# Do router advertisements for all subnets where we're doing DHCPv6
|
||||||
|
# Unless overriden by ra-stateless, ra-names, et al, the router
|
||||||
|
# advertisements will have the M and O bits set, so that the clients
|
||||||
|
# get addresses and configuration from DHCPv6, and the A bit reset, so the
|
||||||
|
# clients don't use SLAAC addresses.
|
||||||
|
#enable-ra
|
||||||
|
|
||||||
|
# Supply parameters for specified hosts using DHCP. There are lots
|
||||||
|
# of valid alternatives, so we will give examples of each. Note that
|
||||||
|
# IP addresses DO NOT have to be in the range given above, they just
|
||||||
|
# need to be on the same network. The order of the parameters in these
|
||||||
|
# do not matter, it's permissible to give name, address and MAC in any
|
||||||
|
# order.
|
||||||
|
|
||||||
|
# Always allocate the host with Ethernet address 11:22:33:44:55:66
|
||||||
|
# The IP address 192.168.0.60
|
||||||
|
#dhcp-host=11:22:33:44:55:66,192.168.0.60
|
||||||
|
|
||||||
|
# Always set the name of the host with hardware address
|
||||||
|
# 11:22:33:44:55:66 to be "fred"
|
||||||
|
#dhcp-host=11:22:33:44:55:66,fred
|
||||||
|
|
||||||
|
# Always give the host with Ethernet address 11:22:33:44:55:66
|
||||||
|
# the name fred and IP address 192.168.0.60 and lease time 45 minutes
|
||||||
|
#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m
|
||||||
|
|
||||||
|
# Give a host with Ethernet address 11:22:33:44:55:66 or
|
||||||
|
# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume
|
||||||
|
# that these two Ethernet interfaces will never be in use at the same
|
||||||
|
# time, and give the IP address to the second, even if it is already
|
||||||
|
# in use by the first. Useful for laptops with wired and wireless
|
||||||
|
# addresses.
|
||||||
|
#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60
|
||||||
|
|
||||||
|
# Give the machine which says its name is "bert" IP address
|
||||||
|
# 192.168.0.70 and an infinite lease
|
||||||
|
#dhcp-host=bert,192.168.0.70,infinite
|
||||||
|
|
||||||
|
# Always give the host with client identifier 01:02:02:04
|
||||||
|
# the IP address 192.168.0.60
|
||||||
|
#dhcp-host=id:01:02:02:04,192.168.0.60
|
||||||
|
|
||||||
|
# Always give the host with client identifier "marjorie"
|
||||||
|
# the IP address 192.168.0.60
|
||||||
|
#dhcp-host=id:marjorie,192.168.0.60
|
||||||
|
|
||||||
|
# Enable the address given for "judge" in /etc/hosts
|
||||||
|
# to be given to a machine presenting the name "judge" when
|
||||||
|
# it asks for a DHCP lease.
|
||||||
|
#dhcp-host=judge
|
||||||
|
|
||||||
|
# Never offer DHCP service to a machine whose Ethernet
|
||||||
|
# address is 11:22:33:44:55:66
|
||||||
|
#dhcp-host=11:22:33:44:55:66,ignore
|
||||||
|
|
||||||
|
# Ignore any client-id presented by the machine with Ethernet
|
||||||
|
# address 11:22:33:44:55:66. This is useful to prevent a machine
|
||||||
|
# being treated differently when running under different OS's or
|
||||||
|
# between PXE boot and OS boot.
|
||||||
|
#dhcp-host=11:22:33:44:55:66,id:*
|
||||||
|
|
||||||
|
# Send extra options which are tagged as "red" to
|
||||||
|
# the machine with Ethernet address 11:22:33:44:55:66
|
||||||
|
#dhcp-host=11:22:33:44:55:66,set:red
|
||||||
|
|
||||||
|
# Send extra options which are tagged as "red" to
|
||||||
|
# any machine with Ethernet address starting 11:22:33:
|
||||||
|
#dhcp-host=11:22:33:*:*:*,set:red
|
||||||
|
|
||||||
|
# Give a fixed IPv6 address and name to client with
|
||||||
|
# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
|
||||||
|
# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
|
||||||
|
# Note also the they [] around the IPv6 address are obilgatory.
|
||||||
|
#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
|
||||||
|
|
||||||
|
# Ignore any clients which are not specified in dhcp-host lines
|
||||||
|
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
||||||
|
# This relies on the special "known" tag which is set when
|
||||||
|
# a host is matched.
|
||||||
|
#dhcp-ignore=tag:!known
|
||||||
|
|
||||||
|
# Send extra options which are tagged as "red" to any machine whose
|
||||||
|
# DHCP vendorclass string includes the substring "Linux"
|
||||||
|
#dhcp-vendorclass=set:red,Linux
|
||||||
|
|
||||||
|
# Send extra options which are tagged as "red" to any machine one
|
||||||
|
# of whose DHCP userclass strings includes the substring "accounts"
|
||||||
|
#dhcp-userclass=set:red,accounts
|
||||||
|
|
||||||
|
# Send extra options which are tagged as "red" to any machine whose
|
||||||
|
# MAC address matches the pattern.
|
||||||
|
#dhcp-mac=set:red,00:60:8C:*:*:*
|
||||||
|
|
||||||
|
# If this line is uncommented, dnsmasq will read /etc/ethers and act
|
||||||
|
# on the ethernet-address/IP pairs found there just as if they had
|
||||||
|
# been given as --dhcp-host options. Useful if you keep
|
||||||
|
# MAC-address/host mappings there for other purposes.
|
||||||
|
#read-ethers
|
||||||
|
|
||||||
|
# Send options to hosts which ask for a DHCP lease.
|
||||||
|
# See RFC 2132 for details of available options.
|
||||||
|
# Common options can be given to dnsmasq by name:
|
||||||
|
# run "dnsmasq --help dhcp" to get a list.
|
||||||
|
# Note that all the common settings, such as netmask and
|
||||||
|
# broadcast address, DNS server and default route, are given
|
||||||
|
# sane defaults by dnsmasq. You very likely will not need
|
||||||
|
# any dhcp-options. If you use Windows clients and Samba, there
|
||||||
|
# are some options which are recommended, they are detailed at the
|
||||||
|
# end of this section.
|
||||||
|
|
||||||
|
# Override the default route supplied by dnsmasq, which assumes the
|
||||||
|
# router is the same machine as the one running dnsmasq.
|
||||||
|
#dhcp-option=3,1.2.3.4
|
||||||
|
|
||||||
|
# Do the same thing, but using the option name
|
||||||
|
#dhcp-option=option:router,1.2.3.4
|
||||||
|
|
||||||
|
# Override the default route supplied by dnsmasq and send no default
|
||||||
|
# route at all. Note that this only works for the options sent by
|
||||||
|
# default (1, 3, 6, 12, 28) the same line will send a zero-length option
|
||||||
|
# for all other option numbers.
|
||||||
|
#dhcp-option=3
|
||||||
|
|
||||||
|
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||||
|
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
||||||
|
|
||||||
|
# Send DHCPv6 option. Note [] around IPv6 addresses.
|
||||||
|
#dhcp-option=option6:dns-server,[1234::77],[1234::88]
|
||||||
|
|
||||||
|
# Send DHCPv6 option for namservers as the machine running
|
||||||
|
# dnsmasq and another.
|
||||||
|
#dhcp-option=option6:dns-server,[::],[1234::88]
|
||||||
|
|
||||||
|
# Ask client to poll for option changes every six hours. (RFC4242)
|
||||||
|
#dhcp-option=option6:information-refresh-time,6h
|
||||||
|
|
||||||
|
# Set the NTP time server address to be the same machine as
|
||||||
|
# is running dnsmasq
|
||||||
|
#dhcp-option=42,0.0.0.0
|
||||||
|
|
||||||
|
# Set the NIS domain name to "welly"
|
||||||
|
#dhcp-option=40,welly
|
||||||
|
|
||||||
|
# Set the default time-to-live to 50
|
||||||
|
#dhcp-option=23,50
|
||||||
|
|
||||||
|
# Set the "all subnets are local" flag
|
||||||
|
#dhcp-option=27,1
|
||||||
|
|
||||||
|
# Send the etherboot magic flag and then etherboot options (a string).
|
||||||
|
#dhcp-option=128,e4:45:74:68:00:00
|
||||||
|
#dhcp-option=129,NIC=eepro100
|
||||||
|
|
||||||
|
# Specify an option which will only be sent to the "red" network
|
||||||
|
# (see dhcp-range for the declaration of the "red" network)
|
||||||
|
# Note that the tag: part must precede the option: part.
|
||||||
|
#dhcp-option = tag:red, option:ntp-server, 192.168.1.1
|
||||||
|
|
||||||
|
# The following DHCP options set up dnsmasq in the same way as is specified
|
||||||
|
# for the ISC dhcpcd in
|
||||||
|
# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
||||||
|
# adapted for a typical dnsmasq installation where the host running
|
||||||
|
# dnsmasq is also the host running samba.
|
||||||
|
# you may want to uncomment some or all of them if you use
|
||||||
|
# Windows clients and Samba.
|
||||||
|
#dhcp-option=19,0 # option ip-forwarding off
|
||||||
|
#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
|
||||||
|
#dhcp-option=45,0.0.0.0 # netbios datagram distribution server
|
||||||
|
#dhcp-option=46,8 # netbios node type
|
||||||
|
|
||||||
|
# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave.
|
||||||
|
#dhcp-option=252,"\n"
|
||||||
|
|
||||||
|
# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
|
||||||
|
# probably doesn't support this......
|
||||||
|
#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
|
||||||
|
|
||||||
|
# Send RFC-3442 classless static routes (note the netmask encoding)
|
||||||
|
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
|
||||||
|
|
||||||
|
# Send vendor-class specific options encapsulated in DHCP option 43.
|
||||||
|
# The meaning of the options is defined by the vendor-class so
|
||||||
|
# options are sent only when the client supplied vendor class
|
||||||
|
# matches the class given here. (A substring match is OK, so "MSFT"
|
||||||
|
# matches "MSFT" and "MSFT 5.0"). This example sets the
|
||||||
|
# mtftp address to 0.0.0.0 for PXEClients.
|
||||||
|
#dhcp-option=vendor:PXEClient,1,0.0.0.0
|
||||||
|
|
||||||
|
# Send microsoft-specific option to tell windows to release the DHCP lease
|
||||||
|
# when it shuts down. Note the "i" flag, to tell dnsmasq to send the
|
||||||
|
# value as a four-byte integer - that's what microsoft wants. See
|
||||||
|
# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
|
||||||
|
#dhcp-option=vendor:MSFT,2,1i
|
||||||
|
|
||||||
|
# Send the Encapsulated-vendor-class ID needed by some configurations of
|
||||||
|
# Etherboot to allow is to recognise the DHCP server.
|
||||||
|
#dhcp-option=vendor:Etherboot,60,"Etherboot"
|
||||||
|
|
||||||
|
# Send options to PXELinux. Note that we need to send the options even
|
||||||
|
# though they don't appear in the parameter request list, so we need
|
||||||
|
# to use dhcp-option-force here.
|
||||||
|
# See http://syslinux.zytor.com/pxe.php#special for details.
|
||||||
|
# Magic number - needed before anything else is recognised
|
||||||
|
#dhcp-option-force=208,f1:00:74:7e
|
||||||
|
# Configuration file name
|
||||||
|
#dhcp-option-force=209,configs/common
|
||||||
|
# Path prefix
|
||||||
|
#dhcp-option-force=210,/tftpboot/pxelinux/files/
|
||||||
|
# Reboot time. (Note 'i' to send 32-bit value)
|
||||||
|
#dhcp-option-force=211,30i
|
||||||
|
|
||||||
|
# Set the boot filename for netboot/PXE. You will only need
|
||||||
|
# this is you want to boot machines over the network and you will need
|
||||||
|
# a TFTP server; either dnsmasq's built in TFTP server or an
|
||||||
|
# external one. (See below for how to enable the TFTP server.)
|
||||||
|
#dhcp-boot=pxelinux.0
|
||||||
|
|
||||||
|
# The same as above, but use custom tftp-server instead machine running dnsmasq
|
||||||
|
#dhcp-boot=pxelinux,server.name,192.168.1.100
|
||||||
|
|
||||||
|
# Boot for Etherboot gPXE. The idea is to send two different
|
||||||
|
# filenames, the first loads gPXE, and the second tells gPXE what to
|
||||||
|
# load. The dhcp-match sets the gpxe tag for requests from gPXE.
|
||||||
|
#dhcp-match=set:gpxe,175 # gPXE sends a 175 option.
|
||||||
|
#dhcp-boot=tag:!gpxe,undionly.kpxe
|
||||||
|
#dhcp-boot=mybootimage
|
||||||
|
|
||||||
|
# Encapsulated options for Etherboot gPXE. All the options are
|
||||||
|
# encapsulated within option 175
|
||||||
|
#dhcp-option=encap:175, 1, 5b # priority code
|
||||||
|
#dhcp-option=encap:175, 176, 1b # no-proxydhcp
|
||||||
|
#dhcp-option=encap:175, 177, string # bus-id
|
||||||
|
#dhcp-option=encap:175, 189, 1b # BIOS drive code
|
||||||
|
#dhcp-option=encap:175, 190, user # iSCSI username
|
||||||
|
#dhcp-option=encap:175, 191, pass # iSCSI password
|
||||||
|
|
||||||
|
# Test for the architecture of a netboot client. PXE clients are
|
||||||
|
# supposed to send their architecture as option 93. (See RFC 4578)
|
||||||
|
#dhcp-match=peecees, option:client-arch, 0 #x86-32
|
||||||
|
#dhcp-match=itanics, option:client-arch, 2 #IA64
|
||||||
|
#dhcp-match=hammers, option:client-arch, 6 #x86-64
|
||||||
|
#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64
|
||||||
|
|
||||||
|
# Do real PXE, rather than just booting a single file, this is an
|
||||||
|
# alternative to dhcp-boot.
|
||||||
|
#pxe-prompt="What system shall I netboot?"
|
||||||
|
# or with timeout before first available action is taken:
|
||||||
|
#pxe-prompt="Press F8 for menu.", 60
|
||||||
|
|
||||||
|
# Available boot services. for PXE.
|
||||||
|
#pxe-service=x86PC, "Boot from local disk"
|
||||||
|
|
||||||
|
# Loads <tftp-root>/pxelinux.0 from dnsmasq TFTP server.
|
||||||
|
#pxe-service=x86PC, "Install Linux", pxelinux
|
||||||
|
|
||||||
|
# Loads <tftp-root>/pxelinux.0 from TFTP server at 1.2.3.4.
|
||||||
|
# Beware this fails on old PXE ROMS.
|
||||||
|
#pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4
|
||||||
|
|
||||||
|
# Use bootserver on network, found my multicast or broadcast.
|
||||||
|
#pxe-service=x86PC, "Install windows from RIS server", 1
|
||||||
|
|
||||||
|
# Use bootserver at a known IP address.
|
||||||
|
#pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4
|
||||||
|
|
||||||
|
# If you have multicast-FTP available,
|
||||||
|
# information for that can be passed in a similar way using options 1
|
||||||
|
# to 5. See page 19 of
|
||||||
|
# http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf
|
||||||
|
|
||||||
|
|
||||||
|
# Enable dnsmasq's built-in TFTP server
|
||||||
|
#enable-tftp
|
||||||
|
|
||||||
|
# Set the root directory for files available via FTP.
|
||||||
|
#tftp-root=/var/ftpd
|
||||||
|
|
||||||
|
# Make the TFTP server more secure: with this set, only files owned by
|
||||||
|
# the user dnsmasq is running as will be send over the net.
|
||||||
|
#tftp-secure
|
||||||
|
|
||||||
|
# This option stops dnsmasq from negotiating a larger blocksize for TFTP
|
||||||
|
# transfers. It will slow things down, but may rescue some broken TFTP
|
||||||
|
# clients.
|
||||||
|
#tftp-no-blocksize
|
||||||
|
|
||||||
|
# Set the boot file name only when the "red" tag is set.
|
||||||
|
#dhcp-boot=tag:red,pxelinux.red-net
|
||||||
|
|
||||||
|
# An example of dhcp-boot with an external TFTP server: the name and IP
|
||||||
|
# address of the server are given after the filename.
|
||||||
|
# Can fail with old PXE ROMS. Overridden by --pxe-service.
|
||||||
|
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3
|
||||||
|
|
||||||
|
# If there are multiple external tftp servers having a same name
|
||||||
|
# (using /etc/hosts) then that name can be specified as the
|
||||||
|
# tftp_servername (the third option to dhcp-boot) and in that
|
||||||
|
# case dnsmasq resolves this name and returns the resultant IP
|
||||||
|
# addresses in round robin fasion. This facility can be used to
|
||||||
|
# load balance the tftp load among a set of servers.
|
||||||
|
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
|
||||||
|
|
||||||
|
# Set the limit on DHCP leases, the default is 150
|
||||||
|
#dhcp-lease-max=150
|
||||||
|
|
||||||
|
# The DHCP server needs somewhere on disk to keep its lease database.
|
||||||
|
# This defaults to a sane location, but if you want to change it, use
|
||||||
|
# the line below.
|
||||||
|
#dhcp-leasefile=/var/lib/misc/dnsmasq.leases
|
||||||
|
|
||||||
|
# Set the DHCP server to authoritative mode. In this mode it will barge in
|
||||||
|
# and take over the lease for any client which broadcasts on the network,
|
||||||
|
# whether it has a record of the lease or not. This avoids long timeouts
|
||||||
|
# when a machine wakes up on a new network. DO NOT enable this if there's
|
||||||
|
# the slightest chance that you might end up accidentally configuring a DHCP
|
||||||
|
# server for your campus/company accidentally. The ISC server uses
|
||||||
|
# the same option, and this URL provides more information:
|
||||||
|
# http://www.isc.org/files/auth.html
|
||||||
|
#dhcp-authoritative
|
||||||
|
|
||||||
|
# Run an executable when a DHCP lease is created or destroyed.
|
||||||
|
# The arguments sent to the script are "add" or "del",
|
||||||
|
# then the MAC address, the IP address and finally the hostname
|
||||||
|
# if there is one.
|
||||||
|
#dhcp-script=/bin/echo
|
||||||
|
|
||||||
|
# Set the cachesize here.
|
||||||
|
#cache-size=150
|
||||||
|
|
||||||
|
# If you want to disable negative caching, uncomment this.
|
||||||
|
#no-negcache
|
||||||
|
|
||||||
|
# Normally responses which come from /etc/hosts and the DHCP lease
|
||||||
|
# file have Time-To-Live set as zero, which conventionally means
|
||||||
|
# do not cache further. If you are happy to trade lower load on the
|
||||||
|
# server for potentially stale date, you can set a time-to-live (in
|
||||||
|
# seconds) here.
|
||||||
|
#local-ttl=
|
||||||
|
|
||||||
|
# If you want dnsmasq to detect attempts by Verisign to send queries
|
||||||
|
# to unregistered .com and .net hosts to its sitefinder service and
|
||||||
|
# have dnsmasq instead return the correct NXDOMAIN response, uncomment
|
||||||
|
# this line. You can add similar lines to do the same for other
|
||||||
|
# registries which have implemented wildcard A records.
|
||||||
|
#bogus-nxdomain=64.94.110.11
|
||||||
|
|
||||||
|
# If you want to fix up DNS results from upstream servers, use the
|
||||||
|
# alias option. This only works for IPv4.
|
||||||
|
# This alias makes a result of 1.2.3.4 appear as 5.6.7.8
|
||||||
|
#alias=1.2.3.4,5.6.7.8
|
||||||
|
# and this maps 1.2.3.x to 5.6.7.x
|
||||||
|
#alias=1.2.3.0,5.6.7.0,255.255.255.0
|
||||||
|
# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
||||||
|
#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
||||||
|
|
||||||
|
# Change these lines if you want dnsmasq to serve MX records.
|
||||||
|
|
||||||
|
# Return an MX record named "maildomain.com" with target
|
||||||
|
# servermachine.com and preference 50
|
||||||
|
#mx-host=maildomain.com,servermachine.com,50
|
||||||
|
|
||||||
|
# Set the default target for MX records created using the localmx option.
|
||||||
|
#mx-target=servermachine.com
|
||||||
|
|
||||||
|
# Return an MX record pointing to the mx-target for all local
|
||||||
|
# machines.
|
||||||
|
#localmx
|
||||||
|
|
||||||
|
# Return an MX record pointing to itself for all local machines.
|
||||||
|
#selfmx
|
||||||
|
|
||||||
|
# Change the following lines if you want dnsmasq to serve SRV
|
||||||
|
# records. These are useful if you want to serve ldap requests for
|
||||||
|
# Active Directory and other windows-originated DNS requests.
|
||||||
|
# See RFC 2782.
|
||||||
|
# You may add multiple srv-host lines.
|
||||||
|
# The fields are <name>,<target>,<port>,<priority>,<weight>
|
||||||
|
# If the domain part if missing from the name (so that is just has the
|
||||||
|
# service and protocol sections) then the domain given by the domain=
|
||||||
|
# config option is used. (Note that expand-hosts does not need to be
|
||||||
|
# set for this to work.)
|
||||||
|
|
||||||
|
# A SRV record sending LDAP for the example.com domain to
|
||||||
|
# ldapserver.example.com port 389
|
||||||
|
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
|
||||||
|
|
||||||
|
# A SRV record sending LDAP for the example.com domain to
|
||||||
|
# ldapserver.example.com port 389 (using domain=)
|
||||||
|
#domain=example.com
|
||||||
|
#srv-host=_ldap._tcp,ldapserver.example.com,389
|
||||||
|
|
||||||
|
# Two SRV records for LDAP, each with different priorities
|
||||||
|
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
|
||||||
|
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
|
||||||
|
|
||||||
|
# A SRV record indicating that there is no LDAP server for the domain
|
||||||
|
# example.com
|
||||||
|
#srv-host=_ldap._tcp.example.com
|
||||||
|
|
||||||
|
# The following line shows how to make dnsmasq serve an arbitrary PTR
|
||||||
|
# record. This is useful for DNS-SD. (Note that the
|
||||||
|
# domain-name expansion done for SRV records _does_not
|
||||||
|
# occur for PTR records.)
|
||||||
|
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
|
||||||
|
|
||||||
|
# Change the following lines to enable dnsmasq to serve TXT records.
|
||||||
|
# These are used for things like SPF and zeroconf. (Note that the
|
||||||
|
# domain-name expansion done for SRV records _does_not
|
||||||
|
# occur for TXT records.)
|
||||||
|
|
||||||
|
#Example SPF.
|
||||||
|
#txt-record=example.com,"v=spf1 a -all"
|
||||||
|
|
||||||
|
#Example zeroconf
|
||||||
|
#txt-record=_http._tcp.example.com,name=value,paper=A4
|
||||||
|
|
||||||
|
# Provide an alias for a "local" DNS name. Note that this _only_ works
|
||||||
|
# for targets which are names from DHCP or /etc/hosts. Give host
|
||||||
|
# "bert" another name, bertrand
|
||||||
|
#cname=bertand,bert
|
||||||
|
|
||||||
|
# For debugging purposes, log each DNS query as it passes through
|
||||||
|
# dnsmasq.
|
||||||
|
#log-queries
|
||||||
|
|
||||||
|
# Log lots of extra information about DHCP transactions.
|
||||||
|
#log-dhcp
|
||||||
|
|
||||||
|
# Include another lot of configuration options.
|
||||||
|
#conf-file=/etc/dnsmasq.more.conf
|
||||||
|
#conf-dir=/etc/dnsmasq.d
|
||||||
|
|
||||||
|
# Include all the files in a directory except those ending in .bak
|
||||||
|
#conf-dir=/etc/dnsmasq.d,.bak
|
||||||
|
|
||||||
|
# Include all files in a directory which end in .conf
|
||||||
|
#conf-dir=/etc/dnsmasq.d/*.conf
|
||||||
@@ -1 +0,0 @@
|
|||||||
CONF_SWAPSIZE=500
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
1
advanced/index.js
Normal file
1
advanced/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
var x = "Pi-hole: A black hole for Internet advertisements."
|
||||||
162
advanced/index.php
Normal file
162
advanced/index.php
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<?php
|
||||||
|
/* Detailed Pi-Hole Block Page: Show "Website Blocked" if user browses to site, but not to image/file requests based on the work of WaLLy3K for DietPi & Pi-Hole */
|
||||||
|
|
||||||
|
$uri = escapeshellcmd($_SERVER['REQUEST_URI']);
|
||||||
|
$serverName = escapeshellcmd($_SERVER['SERVER_NAME']);
|
||||||
|
|
||||||
|
// Retrieve server URI extension (EG: jpg, exe, php)
|
||||||
|
$uriExt = pathinfo($uri, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
|
// Define which URL extensions get rendered as "Website Blocked"
|
||||||
|
$webExt = array('asp', 'htm', 'html', 'php', 'rss', 'xml');
|
||||||
|
|
||||||
|
if(in_array($uriExt, $webExt) || empty($uriExt))
|
||||||
|
{
|
||||||
|
// Requested resource has an extension listed in $webExt
|
||||||
|
// or no extension (index access to some folder incl. the root dir)
|
||||||
|
$showPage = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something else
|
||||||
|
$showPage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming URI types
|
||||||
|
if (!$showPage)
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>window.close();</script></head>
|
||||||
|
<body>
|
||||||
|
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<?php
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Pi-Hole version
|
||||||
|
$piHoleVersion = exec('cd /etc/.pihole/ && git describe --tags --abbrev=0');
|
||||||
|
|
||||||
|
// Don't show the URI if it is the root directory
|
||||||
|
if($uri == "/")
|
||||||
|
{
|
||||||
|
$uri = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset='UTF-8'/>
|
||||||
|
<title>Website Blocked</title>
|
||||||
|
<link rel='stylesheet' href='http://pi.hole/pihole/blockingpage.css'/>
|
||||||
|
<link rel='shortcut icon' href='http://pi.hole/admin/img/favicon.png' type='image/png'/>
|
||||||
|
<meta name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0, user-scalable=no'/>
|
||||||
|
<meta name='robots' content='noindex,nofollow'/>
|
||||||
|
</head>
|
||||||
|
<body id="body">
|
||||||
|
<header>
|
||||||
|
<h1><a href='/'>Website Blocked</a></h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div>Access to the following site has been blocked:<br/>
|
||||||
|
<span class='pre msg'><?php echo $serverName.$uri; ?></span></div>
|
||||||
|
<div>If you have an ongoing use for this website, please ask the owner of the Pi-hole in your network to have it whitelisted.</div>
|
||||||
|
<input id="domain" type="hidden" value="<?php echo $serverName; ?>">
|
||||||
|
<input id="quiet" type="hidden" value="yes">
|
||||||
|
<button id="btnSearch" class="buttons blocked" type="button" style="visibility: hidden;"></button>
|
||||||
|
This page is blocked because it is explicitly contained within the following block list(s):
|
||||||
|
<pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre><br/>
|
||||||
|
<div class='buttons blocked'>
|
||||||
|
<a class='safe33' href='javascript:history.back()'>Go back</a>
|
||||||
|
<a class='safe33' id="whitelisting">Whitelist this page</a>
|
||||||
|
<a class='safe33' href='javascript:window.close()'>Close window</a>
|
||||||
|
</div>
|
||||||
|
<div style="width: 98%; text-align: center; padding: 10px;" hidden="true" id="whitelistingform">Password required!<br/>
|
||||||
|
<form>
|
||||||
|
<input name="list" type="hidden" value="white"><br/>
|
||||||
|
Domain:<br/>
|
||||||
|
<input name="domain" value="<?php echo $serverName ?>" disabled><br/><br/>
|
||||||
|
Password:<br/>
|
||||||
|
<input type="password" id="pw" name="pw"><br/><br/>
|
||||||
|
<button class="buttons33 safe" id="btnAdd" type="button">Whitelist</button>
|
||||||
|
</form><br/>
|
||||||
|
<pre id="whitelistingoutput" style="width: 100%; height: 100%; padding: 5px;" hidden="true"></pre><br/>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer>Generated <?php echo date('D g:i A, M d'); ?> by Pi-hole <?php echo $piHoleVersion; ?></footer>
|
||||||
|
<script src="http://pi.hole/admin/scripts/vendor/jquery.min.js"></script>
|
||||||
|
<script src="http://pi.hole/admin/scripts/pi-hole/js/queryads.js"></script>
|
||||||
|
<script>
|
||||||
|
function inIframe () {
|
||||||
|
try {
|
||||||
|
return window.self !== window.top;
|
||||||
|
} catch (e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to detect if page is loaded within iframe
|
||||||
|
if(inIframe())
|
||||||
|
{
|
||||||
|
// Within iframe
|
||||||
|
// hide content of page
|
||||||
|
$('#body').hide();
|
||||||
|
// remove background
|
||||||
|
document.body.style.backgroundImage = "none";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Query adlists
|
||||||
|
$( "#btnSearch" ).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$( "#whitelisting" ).on( "click", function(){ $( "#whitelistingform" ).removeAttr( "hidden" ); });
|
||||||
|
|
||||||
|
function add() {
|
||||||
|
var domain = $("#domain");
|
||||||
|
var pw = $("#pw");
|
||||||
|
if(domain.val().length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "admin/scripts/pi-hole/php/add.php",
|
||||||
|
method: "post",
|
||||||
|
data: {"domain":domain.val(), "list":"white", "pw":pw.val()},
|
||||||
|
success: function(response) {
|
||||||
|
$( "#whitelistingoutput" ).removeAttr( "hidden" );
|
||||||
|
if(response.indexOf("Pi-hole blocking") !== -1)
|
||||||
|
{
|
||||||
|
// Reload page after 5 seconds
|
||||||
|
setTimeout(function(){window.location.reload(1);}, 5000);
|
||||||
|
$( "#whitelistingoutput" ).html("---> Success <---<br/>You may have to flush your DNS cache");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$( "#whitelistingoutput" ).html("---> "+response+" <---");
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(jqXHR, exception) {
|
||||||
|
$( "#whitelistingoutput" ).removeAttr( "hidden" );
|
||||||
|
$( "#whitelistingoutput" ).html("---> Unknown Error <---");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Handle enter button for adding domains
|
||||||
|
$(document).keypress(function(e) {
|
||||||
|
if(e.which === 13 && $("#pw").is(":focus")) {
|
||||||
|
add();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle buttons
|
||||||
|
$("#btnAdd").on("click", function() {
|
||||||
|
add();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,15 +1,27 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# lighttpd config for Pi-hole
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
server.modules = (
|
server.modules = (
|
||||||
"mod_access",
|
"mod_access",
|
||||||
"mod_accesslog",
|
"mod_accesslog",
|
||||||
|
"mod_auth",
|
||||||
"mod_expire",
|
"mod_expire",
|
||||||
"mod_compress",
|
"mod_compress",
|
||||||
"mod_redirect",
|
"mod_redirect",
|
||||||
"mod_setenv",
|
"mod_setenv",
|
||||||
"mod_rewrite"
|
"mod_rewrite"
|
||||||
)
|
)
|
||||||
|
|
||||||
server.document-root = "/var/www/html"
|
server.document-root = "/var/www/html"
|
||||||
server.error-handler-404 = "pihole/index.html"
|
server.error-handler-404 = "pihole/index.php"
|
||||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||||
server.errorlog = "/var/log/lighttpd/error.log"
|
server.errorlog = "/var/log/lighttpd/error.log"
|
||||||
server.pid-file = "/var/run/lighttpd.pid"
|
server.pid-file = "/var/run/lighttpd.pid"
|
||||||
@@ -35,11 +47,20 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
|||||||
# If the URL starts with /admin, it is the Web interface
|
# If the URL starts with /admin, it is the Web interface
|
||||||
$HTTP["url"] =~ "^/admin/" {
|
$HTTP["url"] =~ "^/admin/" {
|
||||||
# Create a response header for debugging using curl -I
|
# Create a response header for debugging using curl -I
|
||||||
setenv.add-response-header = ( "X-Pi-hole" => "The Pi-hole Web interface is working!" )
|
setenv.add-response-header = (
|
||||||
|
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||||
|
"X-Frame-Options" => "DENY"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Rewite js requests, must be out of $HTTP block due to bug #2526
|
||||||
|
url.rewrite = ( "^(?!/admin/).*\.js$" => "pihole/index.js" )
|
||||||
|
|
||||||
# If the URL does not start with /admin, then it is a query for an ad domain
|
# If the URL does not start with /admin, then it is a query for an ad domain
|
||||||
$HTTP["url"] =~ "^(?!/admin)/.*" {
|
$HTTP["url"] =~ "^(?!/admin)/.*" {
|
||||||
# Create a response header for debugging using curl -I
|
# Create a response header for debugging using curl -I
|
||||||
setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." )
|
setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add user chosen options held in external file
|
||||||
|
include_shell "cat external.conf 2>/dev/null"
|
||||||
83
advanced/lighttpd.conf.fedora
Normal file
83
advanced/lighttpd.conf.fedora
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# lighttpd config for Pi-hole
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
server.modules = (
|
||||||
|
"mod_access",
|
||||||
|
"mod_auth",
|
||||||
|
"mod_fastcgi",
|
||||||
|
"mod_accesslog",
|
||||||
|
"mod_expire",
|
||||||
|
"mod_compress",
|
||||||
|
"mod_redirect",
|
||||||
|
"mod_setenv",
|
||||||
|
"mod_rewrite"
|
||||||
|
)
|
||||||
|
|
||||||
|
server.document-root = "/var/www/html"
|
||||||
|
server.error-handler-404 = "pihole/index.php"
|
||||||
|
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||||
|
server.errorlog = "/var/log/lighttpd/error.log"
|
||||||
|
server.pid-file = "/var/run/lighttpd.pid"
|
||||||
|
server.username = "lighttpd"
|
||||||
|
server.groupname = "lighttpd"
|
||||||
|
server.port = 80
|
||||||
|
accesslog.filename = "/var/log/lighttpd/access.log"
|
||||||
|
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||||
|
|
||||||
|
|
||||||
|
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
|
||||||
|
url.access-deny = ( "~", ".inc" )
|
||||||
|
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
|
||||||
|
|
||||||
|
compress.cache-dir = "/var/cache/lighttpd/compress/"
|
||||||
|
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
|
||||||
|
|
||||||
|
mimetype.assign = ( ".png" => "image/png",
|
||||||
|
".jpg" => "image/jpeg",
|
||||||
|
".jpeg" => "image/jpeg",
|
||||||
|
".html" => "text/html",
|
||||||
|
".css" => "text/css; charset=utf-8",
|
||||||
|
".js" => "application/javascript",
|
||||||
|
".json" => "application/json",
|
||||||
|
".txt" => "text/plain",
|
||||||
|
".svg" => "image/svg+xml" )
|
||||||
|
|
||||||
|
# default listening port for IPv6 falls back to the IPv4 port
|
||||||
|
#include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||||
|
#include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
||||||
|
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||||
|
|
||||||
|
fastcgi.server = ( ".php" =>
|
||||||
|
( "localhost" =>
|
||||||
|
(
|
||||||
|
"socket" => "/tmp/php-fastcgi.socket",
|
||||||
|
"bin-path" => "/usr/bin/php-cgi"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# If the URL starts with /admin, it is the Web interface
|
||||||
|
$HTTP["url"] =~ "^/admin/" {
|
||||||
|
# Create a response header for debugging using curl -I
|
||||||
|
setenv.add-response-header = ( "X-Pi-hole" => "The Pi-hole Web interface is working!" )
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rewite js requests, must be out of $HTTP block due to bug #2526
|
||||||
|
url.rewrite = ( "^(?!/admin/).*\.js$" => "pihole/index.js" )
|
||||||
|
|
||||||
|
# If the URL does not start with /admin, then it is a query for an ad domain
|
||||||
|
$HTTP["url"] =~ "^(?!/admin)/.*" {
|
||||||
|
# Create a response header for debugging using curl -I
|
||||||
|
setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." )
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add user chosen options held in external file
|
||||||
|
include_shell "cat external.conf 2>/dev/null"
|
||||||
@@ -1,15 +1,26 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Updates ad sources every week
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This file is under source-control of the Pi-hole installation and update
|
||||||
|
# scripts, any changes made to this file will be overwritten when the softare
|
||||||
|
# is updated or re-installed. Please make any changes to the appropriate crontab
|
||||||
|
# or other cron file snippets.
|
||||||
|
|
||||||
# Pi-hole: Update the ad sources once a week on Sunday at 01:59
|
# Pi-hole: Update the ad sources once a week on Sunday at 01:59
|
||||||
# Download any updates from the ad lists
|
# Download any updates from the adlists
|
||||||
59 1 * * 7 root /usr/local/bin/gravity.sh
|
59 1 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updateGravity
|
||||||
|
|
||||||
# Pi-hole: Update the Web interface shortly after gravity runs
|
# Pi-hole: Update Pi-hole! Uncomment to enable auto update
|
||||||
# This should also update the version number if it is changed in the dashboard repo
|
#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updatePihole
|
||||||
30 2 * * 7 root /usr/local/bin/updateDashboard.sh
|
|
||||||
|
|
||||||
# Pi-hole: Parse the log file before it is flushed and save the stats to a database
|
# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
|
||||||
# This will be used for a historical view of your Pi-hole's performance
|
|
||||||
#50 23 * * * root /usr/local/bin/dailyLog.sh
|
|
||||||
|
|
||||||
# Pi-hole: Flush the log daily at 11:58 so it doesn't get out of control
|
|
||||||
# Stats will be viewable in the Web interface thanks to the cron job above
|
# Stats will be viewable in the Web interface thanks to the cron job above
|
||||||
58 23 * * * root /usr/local/bin/piholeLogFlush.sh
|
00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush
|
||||||
|
|||||||
11
advanced/pihole.sudo
Normal file
11
advanced/pihole.sudo
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Allows the WebUI to use Pi-hole commands
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
224
automated install/uninstall.sh
Normal file → Executable file
224
automated install/uninstall.sh
Normal file → Executable file
@@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Completely uninstalls the Pi-hole
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
# (c) 2015 by Jacob Salmela
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
# This file is part of Pi-hole.
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Completely uninstalls Pi-hole
|
||||||
#
|
#
|
||||||
# Pi-hole is free software: you can redistribute it and/or modify
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -9,63 +11,171 @@
|
|||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
# Must be root to uninstall
|
# Must be root to uninstall
|
||||||
if [[ $EUID -eq 0 ]];then
|
if [[ ${EUID} -eq 0 ]]; then
|
||||||
echo "You are root."
|
echo "::: You are root."
|
||||||
else
|
else
|
||||||
echo "sudo will be used for the install."
|
echo "::: Sudo will be used for the uninstall."
|
||||||
# Check if it is actually installed
|
# Check if it is actually installed
|
||||||
# If it isn't, exit because the unnstall cannot complete
|
# If it isn't, exit because the unnstall cannot complete
|
||||||
if [[ $(dpkg-query -s sudo) ]];then
|
if [ -x "$(command -v sudo)" ]; then
|
||||||
export SUDO="sudo"
|
export SUDO="sudo"
|
||||||
else
|
else
|
||||||
echo "Please install sudo or run this as root."
|
echo "::: Please install sudo or run this as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Compatability
|
||||||
|
if [ -x "$(command -v rpm)" ]; then
|
||||||
|
# Fedora Family
|
||||||
|
if [ -x "$(command -v dnf)" ]; then
|
||||||
|
PKG_MANAGER="dnf"
|
||||||
|
else
|
||||||
|
PKG_MANAGER="yum"
|
||||||
|
fi
|
||||||
|
PKG_REMOVE="${PKG_MANAGER} remove -y"
|
||||||
|
PIHOLE_DEPS=( bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common git curl unzip wget findutils )
|
||||||
|
package_check() {
|
||||||
|
rpm -qa | grep ^$1- > /dev/null
|
||||||
|
}
|
||||||
|
package_cleanup() {
|
||||||
|
${SUDO} ${PKG_MANAGER} -y autoremove
|
||||||
|
}
|
||||||
|
elif [ -x "$(command -v apt-get)" ]; then
|
||||||
|
# Debian Family
|
||||||
|
PKG_MANAGER="apt-get"
|
||||||
|
PKG_REMOVE="${PKG_MANAGER} -y remove --purge"
|
||||||
|
PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd php5-common git curl unzip wget )
|
||||||
|
package_check() {
|
||||||
|
dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed"
|
||||||
|
}
|
||||||
|
package_cleanup() {
|
||||||
|
${SUDO} ${PKG_MANAGER} -y autoremove
|
||||||
|
${SUDO} ${PKG_MANAGER} -y autoclean
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo "OS distribution not supported"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
spinner() {
|
||||||
|
local pid=$1
|
||||||
|
local delay=0.50
|
||||||
|
local spinstr='/-\|'
|
||||||
|
while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
|
||||||
|
local temp=${spinstr#?}
|
||||||
|
printf " [%c] " "${spinstr}"
|
||||||
|
local spinstr=${temp}${spinstr%"$temp}"}
|
||||||
|
sleep ${delay}
|
||||||
|
printf "\b\b\b\b\b\b"
|
||||||
|
done
|
||||||
|
printf " \b\b\b\b"
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAndPurge() {
|
||||||
|
# Purge dependencies
|
||||||
|
echo ":::"
|
||||||
|
for i in "${PIHOLE_DEPS[@]}"; do
|
||||||
|
package_check ${i} > /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
while true; do
|
||||||
|
read -rp "::: Do you wish to remove ${i} from your system? [y/n]: " yn
|
||||||
|
case ${yn} in
|
||||||
|
[Yy]* ) printf ":::\tRemoving %s..." "${i}"; ${SUDO} ${PKG_REMOVE} "${i}" &> /dev/null & spinner $!; printf "done!\n"; break;;
|
||||||
|
[Nn]* ) printf ":::\tSkipping %s\n" "${i}"; break;;
|
||||||
|
* ) printf "::: You must answer yes or no!\n";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
else
|
||||||
|
printf ":::\tPackage %s not installed... Not removing.\n" "${i}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove dependency config files
|
||||||
|
echo "::: Removing dnsmasq config files..."
|
||||||
|
${SUDO} rm /etc/dnsmasq.conf /etc/dnsmasq.conf.orig /etc/dnsmasq.d/01-pihole.conf &> /dev/null
|
||||||
|
|
||||||
|
# Take care of any additional package cleaning
|
||||||
|
printf "::: Auto removing & cleaning remaining dependencies..."
|
||||||
|
package_cleanup &> /dev/null & spinner $!; printf "done!\n";
|
||||||
|
|
||||||
|
# Call removeNoPurge to remove PiHole specific files
|
||||||
|
removeNoPurge
|
||||||
|
}
|
||||||
|
|
||||||
|
removeNoPurge() {
|
||||||
|
echo ":::"
|
||||||
|
# Only web directories/files that are created by pihole should be removed.
|
||||||
|
echo "::: Removing the Pi-hole Web server files..."
|
||||||
|
${SUDO} rm -rf /var/www/html/admin &> /dev/null
|
||||||
|
${SUDO} rm -rf /var/www/html/pihole &> /dev/null
|
||||||
|
${SUDO} rm /var/www/html/index.lighttpd.orig &> /dev/null
|
||||||
|
|
||||||
|
# If the web directory is empty after removing these files, then the parent html folder can be removed.
|
||||||
|
if [ -d "/var/www/html" ]; then
|
||||||
|
if [[ ! "$(ls -A /var/www/html)" ]]; then
|
||||||
|
${SUDO} rm -rf /var/www/html &> /dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to preserve backwards compatibility with older versions
|
||||||
|
# to guarantee no additional changes were made to /etc/crontab after
|
||||||
|
# the installation of pihole, /etc/crontab.pihole should be permanently
|
||||||
|
# preserved.
|
||||||
|
if [[ -f /etc/crontab.orig ]]; then
|
||||||
|
echo "::: Initial Pi-hole cron detected. Restoring the default system cron..."
|
||||||
|
${SUDO} mv /etc/crontab /etc/crontab.pihole
|
||||||
|
${SUDO} mv /etc/crontab.orig /etc/crontab
|
||||||
|
${SUDO} service cron restart
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to preserve backwards compatibility with older versions
|
||||||
|
if [[ -f /etc/cron.d/pihole ]];then
|
||||||
|
echo "::: Removing cron.d/pihole..."
|
||||||
|
${SUDO} rm /etc/cron.d/pihole &> /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "::: Removing config files and scripts..."
|
||||||
|
package_check lighttpd > /dev/null
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
${SUDO} rm -rf /etc/lighttpd/ &> /dev/null
|
||||||
|
else
|
||||||
|
if [ -f /etc/lighttpd/lighttpd.conf.orig ]; then
|
||||||
|
${SUDO} mv /etc/lighttpd/lighttpd.conf.orig /etc/lighttpd/lighttpd.conf
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
${SUDO} rm /etc/dnsmasq.d/adList.conf &> /dev/null
|
||||||
|
${SUDO} rm /etc/dnsmasq.d/01-pihole.conf &> /dev/null
|
||||||
|
${SUDO} rm -rf /var/log/*pihole* &> /dev/null
|
||||||
|
${SUDO} rm -rf /etc/pihole/ &> /dev/null
|
||||||
|
${SUDO} rm -rf /etc/.pihole/ &> /dev/null
|
||||||
|
${SUDO} rm -rf /opt/pihole/ &> /dev/null
|
||||||
|
${SUDO} rm /usr/local/bin/pihole &> /dev/null
|
||||||
|
${SUDO} rm /etc/bash_completion.d/pihole &> /dev/null
|
||||||
|
${SUDO} rm /etc/sudoers.d/pihole &> /dev/null
|
||||||
|
|
||||||
|
# If the pihole user exists, then remove
|
||||||
|
if id "pihole" >/dev/null 2>&1; then
|
||||||
|
echo "::: Removing pihole user..."
|
||||||
|
${SUDO} userdel -r pihole
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ":::"
|
||||||
|
printf "::: Finished removing PiHole from your system. Sorry to see you go!\n"
|
||||||
|
printf "::: Reach out to us at https://github.com/pi-hole/pi-hole/issues if you need help\n"
|
||||||
|
printf "::: Reinstall by simpling running\n:::\n:::\tcurl -L https://install.pi-hole.net | bash\n:::\n::: at any time!\n:::\n"
|
||||||
|
printf "::: PLEASE RESET YOUR DNS ON YOUR ROUTER/CLIENTS TO RESTORE INTERNET CONNECTIVITY!\n"
|
||||||
|
}
|
||||||
|
|
||||||
######### SCRIPT ###########
|
######### SCRIPT ###########
|
||||||
$SUDO apt-get -y remove --purge dnsutils bc toilet
|
echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system."
|
||||||
$SUDO apt-get -y remove --purge dnsmasq
|
echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)"
|
||||||
$SUDO apt-get -y remove --purge lighttpd php5-common php5-cgi php5
|
while true; do
|
||||||
|
read -rp "::: Do you wish to purge PiHole's dependencies from your OS? (You will be prompted for each package) [y/n]: " yn
|
||||||
# Only web directories/files that are created by pihole should be removed.
|
case ${yn} in
|
||||||
echo "Removing the Pi-hole Web server files..."
|
[Yy]* ) removeAndPurge; break;;
|
||||||
$SUDO rm -rf /var/www/html/admin
|
|
||||||
$SUDO rm -rf /var/www/html/pihole
|
[Nn]* ) removeNoPurge; break;;
|
||||||
$SUDO rm /var/www/html/index.lighttpd.orig
|
esac
|
||||||
|
done
|
||||||
# If the web directory is empty after removing these files, then the parent html folder can be removed.
|
|
||||||
if [[ ! "$(ls -A /var/www/html)" ]]; then
|
|
||||||
$SUDO rm -rf /var/www/html
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Removing dnsmasq config files..."
|
|
||||||
$SUDO rm /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
|
|
||||||
|
|
||||||
# Attempt to preserve backwards compatibility with older versions
|
|
||||||
# to guarantee no additional changes were made to /etc/crontab after
|
|
||||||
# the installation of pihole, /etc/crontab.pihole should be permanently
|
|
||||||
# preserved.
|
|
||||||
if [[ -f /etc/crontab.orig ]]; then
|
|
||||||
echo "Initial Pi-hole cron detected. Restoring the default system cron..."
|
|
||||||
$SUDO mv /etc/crontab /etc/crontab.pihole
|
|
||||||
$SUDO mv /etc/crontab.orig /etc/crontab
|
|
||||||
$SUDO service cron restart
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Attempt to preserve backwards compatibility with older versions
|
|
||||||
if [[ -f /etc/cron.d/pihole ]];then
|
|
||||||
echo "Removing cron.d/pihole..."
|
|
||||||
$SUDO rm /etc/cron.d/pihole
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Removing config files and scripts..."
|
|
||||||
$SUDO rm /etc/dnsmasq.conf
|
|
||||||
$SUDO rm -rf /etc/lighttpd/
|
|
||||||
$SUDO rm /var/log/pihole.log
|
|
||||||
$SUDO rm /usr/local/bin/gravity.sh
|
|
||||||
$SUDO rm /usr/local/bin/chronometer.sh
|
|
||||||
$SUDO rm /usr/local/bin/whitelist.sh
|
|
||||||
$SUDO rm /usr/local/bin/piholeLogFlush.sh
|
|
||||||
$SUDO rm -rf /etc/pihole/
|
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Lighttpd config file for Pi-hole
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
server.modules = (
|
server.modules = (
|
||||||
"mod_access",
|
"mod_access",
|
||||||
"mod_alias",
|
"mod_alias",
|
||||||
@@ -27,6 +38,6 @@ include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
|||||||
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
||||||
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||||
|
|
||||||
$HTTP["host"] =~ "ads.hulu.com|ads-v-darwin.hulu.com" {
|
$HTTP["host"] =~ "ads.hulu.com|ads-v-darwin.hulu.com|ads-e-darwin.hulu.com" {
|
||||||
url.redirect = ( ".*" => "http://192.168.1.101:8200/MediaItems/19.mov")
|
url.redirect = ( ".*" => "http://192.168.1.101:8200/MediaItems/19.mov")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# MiniDLNA config file for Pi-hole
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
media_dir=V,/var/lib/minidlna/videos/
|
media_dir=V,/var/lib/minidlna/videos/
|
||||||
port=8200
|
port=8200
|
||||||
friendly_name=pihole
|
friendly_name=pihole
|
||||||
serial=12345678
|
serial=12345678
|
||||||
model_number=1
|
model_number=1
|
||||||
inotify=yes
|
inotify=yes
|
||||||
|
|||||||
502
gravity.sh
502
gravity.sh
@@ -12,126 +12,127 @@
|
|||||||
|
|
||||||
# Run this script as root or under sudo
|
# Run this script as root or under sudo
|
||||||
echo ":::"
|
echo ":::"
|
||||||
if [[ $EUID -eq 0 ]];then
|
|
||||||
echo "::: You are root."
|
helpFunc() {
|
||||||
|
cat << EOM
|
||||||
|
::: Pull in domains from adlists
|
||||||
|
:::
|
||||||
|
::: Usage: pihole -g
|
||||||
|
:::
|
||||||
|
::: Options:
|
||||||
|
::: -f, --force Force lists to be downloaded, even if they don't need updating.
|
||||||
|
::: -h, --help Show this help dialog
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
adListFile=/etc/pihole/adlists.list
|
||||||
|
adListDefault=/etc/pihole/adlists.default
|
||||||
|
whitelistScript="pihole -w"
|
||||||
|
whitelistFile=/etc/pihole/whitelist.txt
|
||||||
|
blacklistFile=/etc/pihole/blacklist.txt
|
||||||
|
|
||||||
|
#Source the setupVars from install script for the IP
|
||||||
|
setupVars=/etc/pihole/setupVars.conf
|
||||||
|
if [[ -f ${setupVars} ]];then
|
||||||
|
. /etc/pihole/setupVars.conf
|
||||||
else
|
else
|
||||||
echo "::: sudo will be used."
|
echo "::: WARNING: /etc/pihole/setupVars.conf missing. Possible installation failure."
|
||||||
# Check if it is actually installed
|
echo "::: Please run 'pihole -r', and choose the 'reconfigure' option to reconfigure."
|
||||||
# If it isn't, exit because the install cannot complete
|
exit 1
|
||||||
if [[ $(dpkg-query -s sudo) ]];then
|
|
||||||
export SUDO="sudo"
|
|
||||||
else
|
|
||||||
echo "::: Please install sudo or run this script as root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
piholeIPfile=/tmp/piholeIP
|
#Remove the /* from the end of the IPv4addr.
|
||||||
piholeIPv6file=/etc/pihole/.useIPv6
|
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
|
||||||
|
IPV6_ADDRESS=${IPV6_ADDRESS}
|
||||||
if [[ -f $piholeIPfile ]];then
|
|
||||||
# If the file exists, it means it was exported from the installation script and we should use that value instead of detecting it in this script
|
|
||||||
piholeIP=$(cat $piholeIPfile)
|
|
||||||
rm $piholeIPfile
|
|
||||||
else
|
|
||||||
# Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script
|
|
||||||
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
|
|
||||||
piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}')
|
|
||||||
piholeIP=${piholeIPCIDR%/*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f $piholeIPv6file ]];then
|
|
||||||
# If the file exists, then the user previously chose to use IPv6 in the automated installer
|
|
||||||
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ad-list sources--one per line in single quotes
|
|
||||||
# The mahakala source is commented out due to many users having issues with it blocking legitimate domains.
|
|
||||||
# Uncomment at your own risk
|
|
||||||
sources=('https://adaway.org/hosts.txt'
|
|
||||||
'http://adblock.gjtech.net/?format=unix-hosts'
|
|
||||||
#'http://adblock.mahakala.is/'
|
|
||||||
'http://hosts-file.net/ad_servers.txt'
|
|
||||||
'http://www.malwaredomainlist.com/hostslist/hosts.txt'
|
|
||||||
'http://pgl.yoyo.org/adservers/serverlist.php?'
|
|
||||||
'http://someonewhocares.org/hosts/hosts'
|
|
||||||
'http://winhelp2002.mvps.org/hosts.txt'
|
|
||||||
'http://mirror1.malwaredomains.com/files/justdomains')
|
|
||||||
|
|
||||||
# Variables for various stages of downloading and formatting the list
|
# Variables for various stages of downloading and formatting the list
|
||||||
basename=pihole
|
basename=pihole
|
||||||
piholeDir=/etc/$basename
|
piholeDir=/etc/${basename}
|
||||||
adList=$piholeDir/gravity.list
|
adList=${piholeDir}/gravity.list
|
||||||
blacklist=$piholeDir/blacklist.txt
|
localList=${piholeDir}/local.list
|
||||||
whitelist=$piholeDir/whitelist.txt
|
|
||||||
latentWhitelist=$piholeDir/latentWhitelist.txt
|
|
||||||
justDomainsExtension=domains
|
justDomainsExtension=domains
|
||||||
matterandlight=$basename.0.matterandlight.txt
|
matterAndLight=${basename}.0.matterandlight.txt
|
||||||
supernova=$basename.1.supernova.txt
|
supernova=${basename}.1.supernova.txt
|
||||||
eventHorizon=$basename.2.eventHorizon.txt
|
preEventHorizon=list.preEventHorizon
|
||||||
accretionDisc=$basename.3.accretionDisc.txt
|
eventHorizon=${basename}.2.supernova.txt
|
||||||
eyeOfTheNeedle=$basename.4.wormhole.txt
|
accretionDisc=${basename}.3.accretionDisc.txt
|
||||||
|
|
||||||
# After setting defaults, check if there's local overrides
|
skipDownload=false
|
||||||
if [[ -r $piholeDir/pihole.conf ]];then
|
|
||||||
echo "::: Local calibration requested..."
|
# Warn users still using pihole.conf that it no longer has any effect (I imagine about 2 people use it)
|
||||||
. $piholeDir/pihole.conf
|
if [[ -r ${piholeDir}/pihole.conf ]]; then
|
||||||
|
echo "::: pihole.conf file no longer supported. Over-rides in this file are ignored."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
spinner(){
|
|
||||||
local pid=$1
|
|
||||||
local delay=0.001
|
|
||||||
local spinstr='/-\|'
|
|
||||||
|
|
||||||
spin='-\|/'
|
|
||||||
i=0
|
|
||||||
while $SUDO kill -0 $pid 2>/dev/null
|
|
||||||
do
|
|
||||||
i=$(( (i+1) %4 ))
|
|
||||||
printf "\b${spin:$i:1}"
|
|
||||||
sleep .1
|
|
||||||
done
|
|
||||||
printf "\b"
|
|
||||||
}
|
|
||||||
###########################
|
###########################
|
||||||
# collapse - begin formation of pihole
|
# collapse - begin formation of pihole
|
||||||
function gravity_collapse() {
|
gravity_collapse() {
|
||||||
echo -n "::: Neutrino emissions detected..."
|
echo "::: Neutrino emissions detected..."
|
||||||
|
echo ":::"
|
||||||
# Create the pihole resource directory if it doesn't exist. Future files will be stored here
|
#Decide if we're using a custom ad block list, or defaults.
|
||||||
if [[ -d $piholeDir ]];then
|
if [ -f ${adListFile} ]; then
|
||||||
# Temporary hack to allow non-root access to pihole directory
|
#custom file found, use this instead of default
|
||||||
# Will update later, needed for existing installs, new installs should
|
echo -n "::: Custom adList file detected. Reading..."
|
||||||
# create this directory as non-root
|
sources=()
|
||||||
$SUDO chmod 777 $piholeDir
|
while read -r line; do
|
||||||
find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $!
|
#Do not read commented out or blank lines
|
||||||
echo "."
|
if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then
|
||||||
|
echo "" > /dev/null
|
||||||
|
else
|
||||||
|
sources+=(${line})
|
||||||
|
fi
|
||||||
|
done < ${adListFile}
|
||||||
|
echo " done!"
|
||||||
else
|
else
|
||||||
echo -n "::: Creating pihole directory..."
|
#no custom file found, use defaults!
|
||||||
mkdir $piholeDir & spinner $!
|
echo -n "::: No custom adlist file detected, reading from default file..."
|
||||||
echo " done!"
|
sources=()
|
||||||
|
while read -r line; do
|
||||||
|
#Do not read commented out or blank lines
|
||||||
|
if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then
|
||||||
|
echo "" > /dev/null
|
||||||
|
else
|
||||||
|
sources+=(${line})
|
||||||
|
fi
|
||||||
|
done < ${adListDefault}
|
||||||
|
echo " done!"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# patternCheck - check to see if curl downloaded any new files.
|
# patternCheck - check to see if curl downloaded any new files.
|
||||||
function gravity_patternCheck() {
|
gravity_patternCheck() {
|
||||||
patternBuffer=$1
|
patternBuffer=$1
|
||||||
# check if the patternbuffer is a non-zero length file
|
success=$2
|
||||||
if [[ -s "$patternBuffer" ]];then
|
error=$3
|
||||||
# Some of the blocklists are copyright, they need to be downloaded
|
if [ $success = true ]; then
|
||||||
# and stored as is. They can be processed for content after they
|
# check if download was successful but list has not been modified
|
||||||
# have been saved.
|
if [ "${error}" == "304" ]; then
|
||||||
cp $patternBuffer $saveLocation
|
echo "::: No changes detected, transport skipped!"
|
||||||
echo " List updated, transport successful!"
|
# check if the patternbuffer is a non-zero length file
|
||||||
|
elif [[ -s "${patternBuffer}" ]]; then
|
||||||
|
# Some of the blocklists are copyright, they need to be downloaded
|
||||||
|
# and stored as is. They can be processed for content after they
|
||||||
|
# have been saved.
|
||||||
|
mv "${patternBuffer}" "${saveLocation}"
|
||||||
|
echo "::: List updated, transport successful!"
|
||||||
|
else
|
||||||
|
# Empty file -> use previously downloaded list
|
||||||
|
echo "::: Received empty file, using cached one (list not updated!)"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
# curl didn't download any host files, probably because of the date check
|
# check if cached list exists
|
||||||
echo " No changes detected, transport skipped!"
|
if [[ -r "${saveLocation}" ]]; then
|
||||||
|
echo "::: List download failed, using cached list (list not updated!)"
|
||||||
|
else
|
||||||
|
echo "::: Download failed and no cached list available (list will not be considered)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# transport - curl the specified url with any needed command extentions
|
# transport - curl the specified url with any needed command extentions
|
||||||
function gravity_transport() {
|
gravity_transport() {
|
||||||
url=$1
|
url=$1
|
||||||
cmd_ext=$2
|
cmd_ext=$2
|
||||||
agent=$3
|
agent=$3
|
||||||
@@ -139,193 +140,270 @@ function gravity_transport() {
|
|||||||
# tmp file, so we don't have to store the (long!) lists in RAM
|
# tmp file, so we don't have to store the (long!) lists in RAM
|
||||||
patternBuffer=$(mktemp)
|
patternBuffer=$(mktemp)
|
||||||
heisenbergCompensator=""
|
heisenbergCompensator=""
|
||||||
if [[ -r $saveLocation ]]; then
|
if [[ -r ${saveLocation} ]]; then
|
||||||
# if domain has been saved, add file for date check to only download newer
|
# if domain has been saved, add file for date check to only download newer
|
||||||
heisenbergCompensator="-z $saveLocation"
|
heisenbergCompensator="-z ${saveLocation}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Silently curl url
|
# Silently curl url
|
||||||
curl -s $cmd_ext $heisenbergCompensator -A "$agent" $url > $patternBuffer
|
err=$(curl -s -L ${cmd_ext} ${heisenbergCompensator} -w %{http_code} -A "${agent}" ${url} -o ${patternBuffer})
|
||||||
# Check for list updates
|
|
||||||
gravity_patternCheck $patternBuffer
|
echo " done"
|
||||||
|
# Analyze http response
|
||||||
|
echo -n "::: Status: "
|
||||||
|
case "$err" in
|
||||||
|
"200" ) echo "Success (OK)"; success=true;;
|
||||||
|
"304" ) echo "Not modified"; success=true;;
|
||||||
|
"403" ) echo "Forbidden"; success=false;;
|
||||||
|
"404" ) echo "Not found"; success=false;;
|
||||||
|
"408" ) echo "Time-out"; success=false;;
|
||||||
|
"451" ) echo "Unavailable For Legal Reasons"; success=false;;
|
||||||
|
"521" ) echo "Web Server Is Down (Cloudflare)"; success=false;;
|
||||||
|
"522" ) echo "Connection Timed Out (Cloudflare)"; success=false;;
|
||||||
|
"500" ) echo "Internal Server Error"; success=false;;
|
||||||
|
* ) echo "Status $err"; success=false;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Process result
|
||||||
|
gravity_patternCheck "${patternBuffer}" ${success} "${err}"
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
rm -f $patternBuffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# spinup - main gravity function
|
# spinup - main gravity function
|
||||||
function gravity_spinup() {
|
gravity_spinup() {
|
||||||
echo "::: "
|
echo ":::"
|
||||||
# Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines
|
# Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines
|
||||||
for ((i = 0; i < "${#sources[@]}"; i++))
|
for ((i = 0; i < "${#sources[@]}"; i++)); do
|
||||||
do
|
url=${sources[$i]}
|
||||||
url=${sources[$i]}
|
# Get just the domain from the URL
|
||||||
# Get just the domain from the URL
|
domain=$(echo "${url}" | cut -d'/' -f3)
|
||||||
domain=$(echo "$url" | cut -d'/' -f3)
|
|
||||||
|
|
||||||
# Save the file as list.#.domain
|
# Save the file as list.#.domain
|
||||||
saveLocation=$piholeDir/list.$i.$domain.$justDomainsExtension
|
saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension}
|
||||||
activeDomains[$i]=$saveLocation
|
activeDomains[$i]=${saveLocation}
|
||||||
|
|
||||||
agent="Mozilla/10.0"
|
agent="Mozilla/10.0"
|
||||||
|
|
||||||
echo -n "::: Getting $domain list..."
|
# Use a case statement to download lists that need special cURL commands
|
||||||
|
# to complete properly and reset the user agent when required
|
||||||
|
case "${domain}" in
|
||||||
|
"adblock.mahakala.is")
|
||||||
|
agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
|
||||||
|
cmd_ext="-e http://forum.xda-developers.com/"
|
||||||
|
;;
|
||||||
|
|
||||||
# Use a case statement to download lists that need special cURL commands
|
"pgl.yoyo.org")
|
||||||
# to complete properly and reset the user agent when required
|
cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
|
||||||
case "$domain" in
|
;;
|
||||||
"adblock.mahakala.is")
|
|
||||||
agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0'
|
|
||||||
cmd_ext="-e http://forum.xda-developers.com/"
|
|
||||||
;;
|
|
||||||
|
|
||||||
"pgl.yoyo.org")
|
# Default is a simple request
|
||||||
cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
|
*) cmd_ext=""
|
||||||
;;
|
|
||||||
|
|
||||||
# Default is a simple request
|
|
||||||
*) cmd_ext=""
|
|
||||||
esac
|
esac
|
||||||
gravity_transport $url $cmd_ext $agent
|
if [[ "${skipDownload}" == false ]]; then
|
||||||
|
echo -n "::: Getting $domain list..."
|
||||||
|
gravity_transport "$url" "$cmd_ext" "$agent"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Schwarzchild - aggregate domains to one list and add blacklisted domains
|
# Schwarzchild - aggregate domains to one list and add blacklisted domains
|
||||||
function gravity_Schwarzchild() {
|
gravity_Schwarzchild() {
|
||||||
echo "::: "
|
echo "::: "
|
||||||
# Find all active domains and compile them into one file and remove CRs
|
# Find all active domains and compile them into one file and remove CRs
|
||||||
echo -n "::: Aggregating list of domains..."
|
echo -n "::: Aggregating list of domains..."
|
||||||
truncate -s 0 $piholeDir/$matterandlight & spinner $!
|
truncate -s 0 ${piholeDir}/${matterAndLight}
|
||||||
for i in "${activeDomains[@]}"
|
for i in "${activeDomains[@]}"; do
|
||||||
do
|
# Only assimilate list if it is available (download might have faild permanently)
|
||||||
cat $i |tr -d '\r' >> $piholeDir/$matterandlight
|
if [[ -r "${i}" ]]; then
|
||||||
|
cat "${i}" | tr -d '\r' >> ${piholeDir}/${matterAndLight}
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
echo " done!"
|
echo " done!"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gravity_Blacklist() {
|
||||||
|
# Append blacklist entries to eventHorizon if they exist
|
||||||
|
if [[ -f "${blacklistFile}" ]]; then
|
||||||
|
numBlacklisted=$(wc -l < "${blacklistFile}")
|
||||||
|
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
|
||||||
|
echo -n "::: Blacklisting $numBlacklisted domain${plural}..."
|
||||||
|
cat ${blacklistFile} >> ${piholeDir}/${eventHorizon}
|
||||||
|
echo " done!"
|
||||||
|
else
|
||||||
|
echo "::: Nothing to blacklist!"
|
||||||
|
fi
|
||||||
|
|
||||||
function gravity_Blacklist(){
|
|
||||||
# Append blacklist entries if they exist
|
|
||||||
echo -n "::: Running blacklist script to update HOSTS file...."
|
|
||||||
blacklist.sh -f -nr -q > /dev/null & spinner $!
|
|
||||||
|
|
||||||
numBlacklisted=$(wc -l < "/etc/pihole/blacklist.txt")
|
|
||||||
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
|
|
||||||
echo " $numBlacklisted domain${plural} blacklisted!"
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gravity_Whitelist() {
|
||||||
function gravity_Whitelist() {
|
#${piholeDir}/${eventHorizon})
|
||||||
echo ":::"
|
echo ":::"
|
||||||
# Prevent our sources from being pulled into the hole
|
# Prevent our sources from being pulled into the hole
|
||||||
plural=; [[ "${sources[@]}" != "1" ]] && plural=s
|
plural=; [[ "${sources[@]}" != "1" ]] && plural=s
|
||||||
echo -n "::: Adding ${#sources[@]} ad list source${plural} to the whitelist..."
|
echo -n "::: Adding adlist source${plural} to the whitelist..."
|
||||||
|
|
||||||
urls=()
|
urls=()
|
||||||
for url in ${sources[@]}
|
for url in "${sources[@]}"; do
|
||||||
do
|
tmp=$(echo "${url}" | awk -F '/' '{print $3}')
|
||||||
tmp=$(echo "$url" | awk -F '/' '{print $3}')
|
urls=("${urls[@]}" ${tmp})
|
||||||
urls=("${urls[@]}" $tmp)
|
|
||||||
done
|
done
|
||||||
echo " done!"
|
echo " done!"
|
||||||
|
|
||||||
echo -n "::: Running whitelist script to update HOSTS file...."
|
# Ensure adlist domains are in whitelist.txt
|
||||||
whitelist.sh -f -nr -q ${urls[@]} > /dev/null & spinner $!
|
${whitelistScript} -nr -q "${urls[@]}" > /dev/null
|
||||||
|
|
||||||
numWhitelisted=$(wc -l < "/etc/pihole/whitelist.txt")
|
# Check whitelist.txt exists.
|
||||||
plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
|
if [[ -f "${whitelistFile}" ]]; then
|
||||||
echo " $numWhitelisted domain${plural} whitelisted!"
|
# Remove anything in whitelist.txt from the Event Horizon
|
||||||
|
numWhitelisted=$(wc -l < "${whitelistFile}")
|
||||||
|
plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
|
||||||
|
echo -n "::: Whitelisting $numWhitelisted domain${plural}..."
|
||||||
|
#print everything from preEventHorizon into eventHorizon EXCEPT domains in whitelist.txt
|
||||||
|
grep -F -x -v -f ${whitelistFile} ${piholeDir}/${preEventHorizon} > ${piholeDir}/${eventHorizon}
|
||||||
|
echo " done!"
|
||||||
|
else
|
||||||
|
echo "::: Nothing to whitelist!"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function gravity_unique() {
|
gravity_unique() {
|
||||||
# Sort and remove duplicates
|
# Sort and remove duplicates
|
||||||
echo -n "::: Removing duplicate domains...."
|
echo -n "::: Removing duplicate domains...."
|
||||||
sort -u $piholeDir/$supernova > $piholeDir/$eventHorizon & spinner $!
|
sort -u ${piholeDir}/${supernova} > ${piholeDir}/${preEventHorizon}
|
||||||
echo " done!"
|
echo " done!"
|
||||||
numberOf=$(wc -l < $piholeDir/$eventHorizon)
|
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
|
||||||
echo "::: $numberOf unique domains trapped in the event horizon."
|
echo "::: $numberOf unique domains trapped in the event horizon."
|
||||||
}
|
}
|
||||||
|
|
||||||
function gravity_hostFormat() {
|
gravity_hostFormat() {
|
||||||
# Format domain list as "192.168.x.x domain.com"
|
# Format domain list as "192.168.x.x domain.com"
|
||||||
echo "::: Formatting domains into a HOSTS file..."
|
echo -n "::: Formatting domains into a HOSTS file..."
|
||||||
# If there is a value in the $piholeIPv6, then IPv6 will be used, so the awk command modified to create a line for both protocols
|
|
||||||
if [[ -n $piholeIPv6 ]];then
|
if [[ -f /etc/hostname ]]; then
|
||||||
#Add dummy domain Pi-Hole.IsWorking.OK to the top of gravity.list to make ping result return a friendlier looking domain!
|
hostname=$(</etc/hostname)
|
||||||
echo -e "$piholeIP Pi-Hole.IsWorking.OK \n$piholeIPv6 Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc
|
elif [ -x "$(command -v hostname)" ]; then
|
||||||
cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $piholeDir/$accretionDisc
|
hostname=$(hostname -f)
|
||||||
|
else
|
||||||
else
|
echo "::: Error: Unable to determine fully qualified domain name of host"
|
||||||
# Otherwise, just create gravity.list as normal using IPv4
|
fi
|
||||||
#Add dummy domain Pi-Hole.IsWorking.OK to the top of gravity.list to make ping result return a friendlier looking domain!
|
# Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
|
||||||
echo -e "$piholeIP Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc
|
if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
|
||||||
cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >> $piholeDir/$accretionDisc
|
|
||||||
|
echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV6_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole\n${IPV6_ADDRESS} pi.hole" > ${localList}
|
||||||
|
# Both IPv4 and IPv6
|
||||||
|
cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
|
||||||
|
|
||||||
|
elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
|
||||||
|
|
||||||
|
echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole" > ${localList}
|
||||||
|
# Only IPv4
|
||||||
|
cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
|
||||||
|
|
||||||
|
elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
|
||||||
|
|
||||||
|
echo -e "${IPV6_ADDRESS} ${hostname}\n${IPV6_ADDRESS} pi.hole" > ${localList}
|
||||||
|
# Only IPv6
|
||||||
|
cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
|
||||||
|
|
||||||
|
elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
|
||||||
|
echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
|
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
|
||||||
cp $piholeDir/$accretionDisc $adList
|
cp ${piholeDir}/${accretionDisc} ${adList}
|
||||||
|
echo " done!"
|
||||||
}
|
}
|
||||||
|
|
||||||
# blackbody - remove any remnant files from script processes
|
# blackbody - remove any remnant files from script processes
|
||||||
function gravity_blackbody() {
|
gravity_blackbody() {
|
||||||
# Loop through list files
|
# Loop through list files
|
||||||
for file in $piholeDir/*.$justDomainsExtension
|
for file in ${piholeDir}/*.${justDomainsExtension}; do
|
||||||
do
|
|
||||||
# If list is in active array then leave it (noop) else rm the list
|
# If list is in active array then leave it (noop) else rm the list
|
||||||
if [[ " ${activeDomains[@]} " =~ " ${file} " ]]; then
|
if [[ " ${activeDomains[@]} " =~ ${file} ]]; then
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
rm -f $file
|
rm -f "${file}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function gravity_advanced() {
|
gravity_advanced() {
|
||||||
|
|
||||||
|
|
||||||
# Remove comments and print only the domain name
|
# Remove comments and print only the domain name
|
||||||
# Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious
|
# Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious
|
||||||
# This helps with that and makes it easier to read
|
# This helps with that and makes it easier to read
|
||||||
# It also helps with debugging so each stage of the script can be researched more in depth
|
# It also helps with debugging so each stage of the script can be researched more in depth
|
||||||
echo -n "::: Formatting list of domains to remove comments...."
|
echo -n "::: Formatting list of domains to remove comments...."
|
||||||
awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' $piholeDir/$matterandlight | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > $piholeDir/$supernova & spinner $!
|
#awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' ${piholeDir}/${matterAndLight} | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
|
||||||
echo " done!"
|
#Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
|
||||||
|
#Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
|
||||||
numberOf=$(wc -l < $piholeDir/$supernova)
|
#Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
|
||||||
echo "::: $numberOf domains being pulled in by gravity..."
|
#+ the right (IP address), otherwise grab the single field.
|
||||||
|
cat ${piholeDir}/${matterAndLight} | \
|
||||||
|
awk -F '#' '{print $1}' | \
|
||||||
|
awk -F '/' '{print $1}' | \
|
||||||
|
awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | \
|
||||||
|
sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
|
||||||
|
echo " done!"
|
||||||
|
|
||||||
|
numberOf=$(wc -l < ${piholeDir}/${supernova})
|
||||||
|
echo "::: ${numberOf} domains being pulled in by gravity..."
|
||||||
|
|
||||||
gravity_unique
|
gravity_unique
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function gravity_reload() {
|
gravity_reload() {
|
||||||
|
#Clear no longer needed files...
|
||||||
|
echo ":::"
|
||||||
|
echo -n "::: Cleaning up un-needed files..."
|
||||||
|
rm ${piholeDir}/pihole.*.txt
|
||||||
|
echo " done!"
|
||||||
|
|
||||||
# Reload hosts file
|
# Reload hosts file
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: Refresh lists in dnsmasq..."
|
echo -n "::: Refresh lists in dnsmasq..."
|
||||||
dnsmasqPid=$(pidof dnsmasq)
|
|
||||||
|
|
||||||
if [[ $dnsmasqPid ]]; then
|
#ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list!
|
||||||
# service already running - reload config
|
#First escape forward slashes in the path:
|
||||||
$SUDO kill -HUP $dnsmasqPid & spinner $!
|
adList=${adList//\//\\\/}
|
||||||
else
|
#Now replace the line in dnsmasq file
|
||||||
# service not running, start it up
|
# sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
|
||||||
$SUDO service dnsmasq start & spinner $!
|
|
||||||
fi
|
pihole restartdns
|
||||||
echo " done!"
|
echo " done!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for var in "$@"; do
|
||||||
|
case "${var}" in
|
||||||
|
"-f" | "--force" ) forceGrav=true;;
|
||||||
|
"-h" | "--help" ) helpFunc;;
|
||||||
|
"-sd" | "--skip-download" ) skipDownload=true;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${forceGrav}" == true ]]; then
|
||||||
|
echo -n "::: Deleting exising list cache..."
|
||||||
|
rm /etc/pihole/list.*
|
||||||
|
echo " done!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Overwrite adlists.default from /etc/.pihole in case any changes have been made. Changes should be saved in /etc/adlists.list
|
||||||
|
#cp /etc/.pihole/adlists.default /etc/pihole/adlists.default
|
||||||
gravity_collapse
|
gravity_collapse
|
||||||
gravity_spinup
|
gravity_spinup
|
||||||
gravity_Schwarzchild
|
if [[ "${skipDownload}" == false ]]; then
|
||||||
gravity_advanced
|
gravity_Schwarzchild
|
||||||
gravity_hostFormat
|
gravity_advanced
|
||||||
gravity_blackbody
|
else
|
||||||
|
echo "::: Using cached Event Horizon list..."
|
||||||
|
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
|
||||||
|
echo "::: $numberOf unique domains trapped in the event horizon."
|
||||||
|
fi
|
||||||
gravity_Whitelist
|
gravity_Whitelist
|
||||||
gravity_Blacklist
|
gravity_Blacklist
|
||||||
|
|
||||||
|
gravity_hostFormat
|
||||||
|
gravity_blackbody
|
||||||
|
|
||||||
gravity_reload
|
gravity_reload
|
||||||
|
pihole status
|
||||||
|
|||||||
297
pihole
Executable file
297
pihole
Executable file
@@ -0,0 +1,297 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2015, 2016 by Jacob Salmela
|
||||||
|
# Network-wide ad blocking via your Raspberry Pi
|
||||||
|
# http://pi-hole.net
|
||||||
|
# Controller for all pihole scripts and functions.
|
||||||
|
#
|
||||||
|
# Pi-hole is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||||
|
# Must be root to use this tool
|
||||||
|
if [[ ! $EUID -eq 0 ]];then
|
||||||
|
if [ -x "$(command -v sudo)" ];then
|
||||||
|
exec sudo bash "$0" "$@"
|
||||||
|
exit $?
|
||||||
|
else
|
||||||
|
echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
webpageFunc() {
|
||||||
|
source /opt/pihole/webpage.sh
|
||||||
|
main "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
whitelistFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/list.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
blacklistFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/list.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
debugFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
flushFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePiholeFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/update.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
reconfigurePiholeFunc() {
|
||||||
|
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGravityFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/gravity.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setupLCDFunction() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/setupLCD.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
scanList(){
|
||||||
|
domain="${1}"
|
||||||
|
list="${2}"
|
||||||
|
method="${3}"
|
||||||
|
if [[ ${method} == "-exact" ]] ; then
|
||||||
|
grep -i -E "(^|\s)${domain}($|\s)" "${list}"
|
||||||
|
else
|
||||||
|
grep -i "${domain}" "${list}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
queryFunc() {
|
||||||
|
domain="${2}"
|
||||||
|
method="${3}"
|
||||||
|
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
|
||||||
|
for list in ${lists[@]}; do
|
||||||
|
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 ""
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
chronometerFunc() {
|
||||||
|
shift
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/chronometer.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uninstallFunc() {
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
versionFunc() {
|
||||||
|
shift
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
restartDNS() {
|
||||||
|
dnsmasqPid=$(pidof dnsmasq)
|
||||||
|
if [[ ${dnsmasqPid} ]]; then
|
||||||
|
# service already running - reload config
|
||||||
|
if [ -x "$(command -v systemctl)" ]; then
|
||||||
|
systemctl restart dnsmasq
|
||||||
|
else
|
||||||
|
service dnsmasq restart
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# service not running, start it up
|
||||||
|
if [ -x "$(command -v systemctl)" ]; then
|
||||||
|
systemctl start dnsmasq
|
||||||
|
else
|
||||||
|
service dnsmasq start
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
piholeEnable() {
|
||||||
|
if [[ "${1}" == "0" ]] ; then
|
||||||
|
#Disable Pihole
|
||||||
|
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
|
||||||
|
echo "::: Blocking has been disabled!"
|
||||||
|
if [[ $# > 1 ]] ; then
|
||||||
|
if [[ ${2} == *"s"* ]] ; then
|
||||||
|
tt=${2%"s"}
|
||||||
|
echo "::: Blocking will be re-enabled in ${tt} seconds"
|
||||||
|
nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null &
|
||||||
|
elif [[ ${2} == *"m"* ]] ; then
|
||||||
|
tt=${2%"m"}
|
||||||
|
echo "::: Blocking will be re-enabled in ${tt} minutes"
|
||||||
|
tt=$((${tt}*60))
|
||||||
|
nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null &
|
||||||
|
else
|
||||||
|
echo "::: Unknown format for delayed reactivation of the blocking!"
|
||||||
|
echo "::: Example:"
|
||||||
|
echo "::: pihole disable 5s - will disable blocking for 5 seconds"
|
||||||
|
echo "::: pihole disable 7m - will disable blocking for 7 minutes"
|
||||||
|
echo "::: Blocking will not automatically be re-enabled!"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
#Enable pihole
|
||||||
|
echo "::: Blocking has been enabled!"
|
||||||
|
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
|
||||||
|
fi
|
||||||
|
restartDNS
|
||||||
|
}
|
||||||
|
|
||||||
|
piholeLogging() {
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ "${1}" == "off" ]] ; then
|
||||||
|
#Disable Logging
|
||||||
|
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
|
||||||
|
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
|
||||||
|
pihole -f
|
||||||
|
echo "::: Logging has been disabled!"
|
||||||
|
elif [[ "${1}" == "on" ]] ; then
|
||||||
|
#Enable logging
|
||||||
|
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
|
||||||
|
sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
|
||||||
|
echo "::: Logging has been enabled!"
|
||||||
|
else
|
||||||
|
echo "::: Invalid option passed, please pass 'on' or 'off'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
restartDNS
|
||||||
|
}
|
||||||
|
|
||||||
|
piholeStatus() {
|
||||||
|
if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then
|
||||||
|
if [[ "${1}" != "web" ]] ; then
|
||||||
|
echo "::: DNS service is running"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
echo "-1";
|
||||||
|
else
|
||||||
|
echo "::: DNS service is NOT running"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
|
||||||
|
#list is commented out
|
||||||
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
echo 0;
|
||||||
|
else
|
||||||
|
echo "::: Pi-hole blocking is Disabled";
|
||||||
|
fi
|
||||||
|
elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
|
||||||
|
#list set
|
||||||
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
echo 1;
|
||||||
|
else
|
||||||
|
echo "::: Pi-hole blocking is Enabled";
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
#addn-host not found
|
||||||
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
echo 99
|
||||||
|
else
|
||||||
|
echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
|
||||||
|
fi
|
||||||
|
#add addn-host= to dnsmasq
|
||||||
|
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
|
||||||
|
restartDNS
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
tailFunc() {
|
||||||
|
echo "Press Ctrl-C to exit"
|
||||||
|
tail -F /var/log/pihole.log
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
cat << EOM
|
||||||
|
::: Control all PiHole specific functions!
|
||||||
|
:::
|
||||||
|
::: Usage: pihole [options]
|
||||||
|
::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage
|
||||||
|
:::
|
||||||
|
::: Options:
|
||||||
|
::: -w, whitelist Whitelist domains
|
||||||
|
::: -b, blacklist Blacklist domains
|
||||||
|
::: -d, debug Start a debugging session if having trouble
|
||||||
|
::: -f, flush Flush the pihole.log file
|
||||||
|
::: -t, tail Output the last lines of the pihole.log file. Lines are appended as the file grows
|
||||||
|
::: -up, updatePihole Update Pi-hole
|
||||||
|
::: -r, reconfigure Reconfigure or Repair Pi-hole
|
||||||
|
::: -g, updateGravity Update the list of ad-serving domains
|
||||||
|
::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it
|
||||||
|
::: -c, chronometer Calculates stats and displays to an LCD
|
||||||
|
::: -h, help Show this help dialog
|
||||||
|
::: -v, version Show current versions
|
||||||
|
::: -q, query Query the adlists for a specific domain
|
||||||
|
::: Use pihole -q domain -exact if you want to see exact matches only
|
||||||
|
::: -l, logging Enable or Disable logging (pass 'on' or 'off')
|
||||||
|
::: -a, admin Admin webpage options
|
||||||
|
::: uninstall Uninstall Pi-Hole from your system :(!
|
||||||
|
::: status Is Pi-Hole Enabled or Disabled
|
||||||
|
::: enable Enable Pi-Hole DNS Blocking
|
||||||
|
::: disable Disable Pi-Hole DNS Blocking
|
||||||
|
::: Blocking can also be disabled only temporarily, e.g.,
|
||||||
|
::: pihole disable 5m - will disable blocking for 5 minutes
|
||||||
|
::: restartdns Restart dnsmasq
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# = 0 ]]; then
|
||||||
|
helpFunc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle redirecting to specific functions based on arguments
|
||||||
|
case "${1}" in
|
||||||
|
"-w" | "whitelist" ) whitelistFunc "$@";;
|
||||||
|
"-b" | "blacklist" ) blacklistFunc "$@";;
|
||||||
|
"-d" | "debug" ) debugFunc;;
|
||||||
|
"-f" | "flush" ) flushFunc;;
|
||||||
|
"-up" | "updatePihole" ) updatePiholeFunc;;
|
||||||
|
"-r" | "reconfigure" ) reconfigurePiholeFunc;;
|
||||||
|
"-g" | "updateGravity" ) updateGravityFunc "$@";;
|
||||||
|
"-s" | "setupLCD" ) setupLCDFunction;;
|
||||||
|
"-c" | "chronometer" ) chronometerFunc "$@";;
|
||||||
|
"-h" | "help" ) helpFunc;;
|
||||||
|
"-v" | "version" ) versionFunc "$@";;
|
||||||
|
"-q" | "query" ) queryFunc "$@";;
|
||||||
|
"-l" | "logging" ) piholeLogging "$@";;
|
||||||
|
"uninstall" ) uninstallFunc;;
|
||||||
|
"enable" ) piholeEnable 1;;
|
||||||
|
"disable" ) piholeEnable 0 $2;;
|
||||||
|
"status" ) piholeStatus "$2";;
|
||||||
|
"restartdns" ) restartDNS;;
|
||||||
|
"-a" | "admin" ) webpageFunc "$@";;
|
||||||
|
"-t" | "tail" ) tailFunc;;
|
||||||
|
* ) helpFunc;;
|
||||||
|
esac
|
||||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
docker-compose
|
||||||
|
pytest
|
||||||
|
pytest-xdist
|
||||||
|
pytest-cov
|
||||||
|
testinfra
|
||||||
0
test/__init__.py
Normal file
0
test/__init__.py
Normal file
16
test/centos.Dockerfile
Normal file
16
test/centos.Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM centos:7
|
||||||
|
|
||||||
|
ENV GITDIR /etc/.pihole
|
||||||
|
ENV SCRIPTDIR /opt/pihole
|
||||||
|
|
||||||
|
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
|
||||||
|
ADD . $GITDIR
|
||||||
|
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
|
||||||
|
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
||||||
|
|
||||||
|
RUN true && \
|
||||||
|
chmod +x $SCRIPTDIR/*
|
||||||
|
|
||||||
|
ENV PH_TEST true
|
||||||
|
|
||||||
|
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
||||||
61
test/conftest.py
Normal file
61
test/conftest.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import pytest
|
||||||
|
import testinfra
|
||||||
|
|
||||||
|
check_output = testinfra.get_backend(
|
||||||
|
"local://"
|
||||||
|
).get_module("Command").check_output
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def Pihole(Docker):
|
||||||
|
''' used to contain some script stubbing, now pretty much an alias.
|
||||||
|
Also provides bash as the default run function shell '''
|
||||||
|
def run_bash(self, command, *args, **kwargs):
|
||||||
|
cmd = self.get_command(command, *args)
|
||||||
|
if self.user is not None:
|
||||||
|
out = self.run_local(
|
||||||
|
"docker exec -u %s %s /bin/bash -c %s",
|
||||||
|
self.user, self.name, cmd)
|
||||||
|
else:
|
||||||
|
out = self.run_local(
|
||||||
|
"docker exec %s /bin/bash -c %s", self.name, cmd)
|
||||||
|
out.command = self.encode(cmd)
|
||||||
|
return out
|
||||||
|
|
||||||
|
funcType = type(Docker.run)
|
||||||
|
Docker.run = funcType(run_bash, Docker, testinfra.backend.docker.DockerBackend)
|
||||||
|
return Docker
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def Docker(request, args, image, cmd):
|
||||||
|
''' combine our fixtures into a docker run command and setup finalizer to cleanup '''
|
||||||
|
assert 'docker' in check_output('id'), "Are you in the docker group?"
|
||||||
|
docker_run = "docker run {} {} {}".format(args, image, cmd)
|
||||||
|
docker_id = check_output(docker_run)
|
||||||
|
|
||||||
|
def teardown():
|
||||||
|
check_output("docker rm -f %s", docker_id)
|
||||||
|
request.addfinalizer(teardown)
|
||||||
|
|
||||||
|
docker_container = testinfra.get_backend("docker://" + docker_id)
|
||||||
|
docker_container.id = docker_id
|
||||||
|
return docker_container
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def args(request):
|
||||||
|
''' -t became required when tput began being used '''
|
||||||
|
return '-t -d'
|
||||||
|
|
||||||
|
@pytest.fixture(params=['debian', 'centos'])
|
||||||
|
def tag(request):
|
||||||
|
''' consumed by image to make the test matrix '''
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def image(request, tag):
|
||||||
|
''' built by test_000_build_containers.py '''
|
||||||
|
return 'pytest_pihole:{}'.format(tag)
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def cmd(request):
|
||||||
|
''' default to doing nothing by tailing null, but don't exit '''
|
||||||
|
return 'tail -f /dev/null'
|
||||||
16
test/debian.Dockerfile
Normal file
16
test/debian.Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM debian:jessie
|
||||||
|
|
||||||
|
ENV GITDIR /etc/.pihole
|
||||||
|
ENV SCRIPTDIR /opt/pihole
|
||||||
|
|
||||||
|
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
|
||||||
|
ADD . $GITDIR
|
||||||
|
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
|
||||||
|
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
||||||
|
|
||||||
|
RUN true && \
|
||||||
|
chmod +x $SCRIPTDIR/*
|
||||||
|
|
||||||
|
ENV PH_TEST true
|
||||||
|
|
||||||
|
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
||||||
18
test/test_000_build_containers.py
Normal file
18
test/test_000_build_containers.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
''' This file starts with 000 to make it run first '''
|
||||||
|
import pytest
|
||||||
|
import testinfra
|
||||||
|
|
||||||
|
run_local = testinfra.get_backend(
|
||||||
|
"local://"
|
||||||
|
).get_module("Command").run
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("image,tag", [
|
||||||
|
( 'test/debian.Dockerfile', 'pytest_pihole:debian' ),
|
||||||
|
( 'test/centos.Dockerfile', 'pytest_pihole:centos' ),
|
||||||
|
])
|
||||||
|
def test_build_pihole_image(image, tag):
|
||||||
|
build_cmd = run_local('docker build -f {} -t {} .'.format(image, tag))
|
||||||
|
if build_cmd.rc != 0:
|
||||||
|
print build_cmd.stdout
|
||||||
|
print build_cmd.stderr
|
||||||
|
assert build_cmd.rc == 0
|
||||||
100
test/test_automated_install.py
Normal file
100
test/test_automated_install.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import pytest
|
||||||
|
from textwrap import dedent
|
||||||
|
|
||||||
|
SETUPVARS = {
|
||||||
|
'PIHOLE_INTERFACE' : 'eth99',
|
||||||
|
'IPV4_ADDRESS' : '1.1.1.1',
|
||||||
|
'IPV6_ADDRESS' : 'FE80::240:D0FF:FE48:4672',
|
||||||
|
'PIHOLE_DNS_1' : '4.2.2.1',
|
||||||
|
'PIHOLE_DNS_2' : '4.2.2.2'
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_setupVars_are_sourced_to_global_scope(Pihole):
|
||||||
|
''' currently update_dialogs sources setupVars with a dot,
|
||||||
|
then various other functions use the variables.
|
||||||
|
This confirms the sourced variables are in scope between functions '''
|
||||||
|
setup_var_file = 'cat <<EOF> /etc/pihole/setupVars.conf\n'
|
||||||
|
for k,v in SETUPVARS.iteritems():
|
||||||
|
setup_var_file += "{}={}\n".format(k, v)
|
||||||
|
setup_var_file += "EOF\n"
|
||||||
|
Pihole.run(setup_var_file)
|
||||||
|
|
||||||
|
script = dedent('''\
|
||||||
|
set -e
|
||||||
|
printSetupVars() {
|
||||||
|
# Currently debug test function only
|
||||||
|
echo "Outputting sourced variables"
|
||||||
|
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
|
||||||
|
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
|
||||||
|
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
|
||||||
|
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
|
||||||
|
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
|
||||||
|
}
|
||||||
|
update_dialogs() {
|
||||||
|
. /etc/pihole/setupVars.conf
|
||||||
|
}
|
||||||
|
update_dialogs
|
||||||
|
printSetupVars
|
||||||
|
''')
|
||||||
|
|
||||||
|
output = run_script(Pihole, script).stdout
|
||||||
|
|
||||||
|
for k,v in SETUPVARS.iteritems():
|
||||||
|
assert "{}={}".format(k, v) in output
|
||||||
|
|
||||||
|
def test_setupVars_saved_to_file(Pihole):
|
||||||
|
''' confirm saved settings are written to a file for future updates to re-use '''
|
||||||
|
set_setup_vars = '\n' # dedent works better with this and padding matching script below
|
||||||
|
for k,v in SETUPVARS.iteritems():
|
||||||
|
set_setup_vars += " {}={}\n".format(k, v)
|
||||||
|
Pihole.run(set_setup_vars).stdout
|
||||||
|
|
||||||
|
script = dedent('''\
|
||||||
|
set -e
|
||||||
|
echo start
|
||||||
|
TERM=xterm
|
||||||
|
source /opt/pihole/basic-install.sh
|
||||||
|
{}
|
||||||
|
finalExports
|
||||||
|
cat /etc/pihole/setupVars.conf
|
||||||
|
'''.format(set_setup_vars))
|
||||||
|
|
||||||
|
output = run_script(Pihole, script).stdout
|
||||||
|
|
||||||
|
for k,v in SETUPVARS.iteritems():
|
||||||
|
assert "{}={}".format(k, v) in output
|
||||||
|
|
||||||
|
def test_configureFirewall_firewalld_no_errors(Pihole):
|
||||||
|
''' confirms firewalld rules are applied when appopriate '''
|
||||||
|
mock_command('firewall-cmd', '0', Pihole)
|
||||||
|
configureFirewall = Pihole.run('''
|
||||||
|
source /opt/pihole/basic-install.sh
|
||||||
|
configureFirewall
|
||||||
|
''')
|
||||||
|
expected_stdout = '::: Configuring FirewallD for httpd and dnsmasq.'
|
||||||
|
assert expected_stdout in configureFirewall.stdout
|
||||||
|
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
|
||||||
|
assert 'firewall-cmd --state' in firewall_calls
|
||||||
|
assert 'firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp' in firewall_calls
|
||||||
|
assert 'firewall-cmd --reload' in firewall_calls
|
||||||
|
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
def mock_command(script, result, container):
|
||||||
|
''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
|
||||||
|
''' TODO: support array of results that enable the results to change over multiple executions of a command '''
|
||||||
|
full_script_path = '/usr/local/bin/{}'.format(script)
|
||||||
|
mock_script = dedent('''\
|
||||||
|
#!/bin/bash -e
|
||||||
|
echo "\$0 \$@" >> /var/log/{script}
|
||||||
|
exit {retcode}
|
||||||
|
'''.format(script=script, retcode=result))
|
||||||
|
container.run('''
|
||||||
|
cat <<EOF> {script}\n{content}\nEOF
|
||||||
|
chmod +x {script}
|
||||||
|
'''.format(script=full_script_path, content=mock_script))
|
||||||
|
|
||||||
|
def run_script(Pihole, script):
|
||||||
|
result = Pihole.run(script)
|
||||||
|
assert result.rc == 0
|
||||||
|
return result
|
||||||
13
test/test_shellcheck.py
Normal file
13
test/test_shellcheck.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import pytest
|
||||||
|
import testinfra
|
||||||
|
|
||||||
|
run_local = testinfra.get_backend(
|
||||||
|
"local://"
|
||||||
|
).get_module("Command").run
|
||||||
|
|
||||||
|
def test_scripts_pass_shellcheck():
|
||||||
|
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
|
||||||
|
shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\"; done;"
|
||||||
|
results = run_local(shellcheck)
|
||||||
|
print results.stdout
|
||||||
|
assert '' == results.stdout
|
||||||
Reference in New Issue
Block a user