freedombone-utils-firewall 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # Firewall functions
  10. #
  11. # TODO: in future investigate using nftables
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
  17. #
  18. # This program is free software: you can redistribute it and/or modify
  19. # it under the terms of the GNU Affero General Public License as published by
  20. # the Free Software Foundation, either version 3 of the License, or
  21. # (at your option) any later version.
  22. #
  23. # This program is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU Affero General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU Affero General Public License
  29. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. FIREWALL_CONFIG=$HOME/${PROJECT_NAME}-firewall.cfg
  31. FIREWALL_DOMAINS=$HOME/${PROJECT_NAME}-firewall-domains.cfg
  32. FIREWALL_EIFACE=eth0
  33. EXTERNAL_IPV4_ADDRESS=
  34. FIREFOX_TELEMETRY_IP='52.88.27.118'
  35. function save_firewall_settings {
  36. iptables-save > /etc/firewall.conf
  37. ip6tables-save > /etc/firewall6.conf
  38. if [ ! -d /etc/network/if-up.d ]; then
  39. mkdir /etc/network/if-up.d
  40. fi
  41. printf '#!/bin/sh\n' > /etc/network/if-up.d/iptables
  42. printf 'iptables-restore < /etc/firewall.conf\n' >> /etc/network/if-up.d/iptables
  43. printf 'ip6tables-restore < /etc/firewall6.conf\n' >> /etc/network/if-up.d/iptables
  44. if [ -f /etc/network/if-up.d/iptables ]; then
  45. chmod +x /etc/network/if-up.d/iptables
  46. fi
  47. }
  48. function block_firefox_telemetry {
  49. # This shouldn't be needed on a server, but we'll do it anyway
  50. # to be on the safe side
  51. # Within firefox source code see submit_telemetry_data.py
  52. if ! grep -q 'telemetry.mozilla' /etc/hosts; then
  53. echo '127.0.0.1 telemetry.mozilla.org' >> /etc/hosts
  54. echo '127.0.0.1 incoming.telemetry.mozilla.org' >> /etc/hosts
  55. fi
  56. if grep -q "$FIREFOX_TELEMETRY_IP" /etc/firewall.conf; then
  57. return
  58. fi
  59. iptables -A INPUT -s $FIREFOX_TELEMETRY_IP -j DROP
  60. iptables -A OUTPUT -s $FIREFOX_TELEMETRY_IP -j DROP
  61. save_firewall_settings
  62. }
  63. function firewall_block_bad_ip_ranges {
  64. if [ "$INSTALLING_MESH" ]; then
  65. return
  66. fi
  67. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  68. return
  69. fi
  70. # There are various blocklists out there, but they're difficult
  71. # to verify. Indiscriminately blocking ranges without evidence
  72. # would be a bad idea.
  73. # From Wikipedia and elsewhere: US military addresses
  74. iptables -A INPUT -s 6.0.0.0/8 -j DROP
  75. iptables -A OUTPUT -s 6.0.0.0/8 -j DROP
  76. iptables -A INPUT -s 7.0.0.0/8 -j DROP
  77. iptables -A OUTPUT -s 7.0.0.0/8 -j DROP
  78. iptables -A INPUT -s 11.0.0.0/8 -j DROP
  79. iptables -A OUTPUT -s 11.0.0.0/8 -j DROP
  80. iptables -A INPUT -s 21.0.0.0/8 -j DROP
  81. iptables -A OUTPUT -s 21.0.0.0/8 -j DROP
  82. iptables -A INPUT -s 22.0.0.0/8 -j DROP
  83. iptables -A OUTPUT -s 22.0.0.0/8 -j DROP
  84. iptables -A INPUT -s 26.0.0.0/8 -j DROP
  85. iptables -A OUTPUT -s 26.0.0.0/8 -j DROP
  86. iptables -A INPUT -s 28.0.0.0/8 -j DROP
  87. iptables -A OUTPUT -s 28.0.0.0/8 -j DROP
  88. iptables -A INPUT -s 29.0.0.0/8 -j DROP
  89. iptables -A OUTPUT -s 29.0.0.0/8 -j DROP
  90. iptables -A INPUT -s 30.0.0.0/8 -j DROP
  91. iptables -A OUTPUT -s 30.0.0.0/8 -j DROP
  92. iptables -A INPUT -s 33.0.0.0/8 -j DROP
  93. iptables -A OUTPUT -s 33.0.0.0/8 -j DROP
  94. iptables -A INPUT -s 55.0.0.0/8 -j DROP
  95. iptables -A OUTPUT -s 55.0.0.0/8 -j DROP
  96. iptables -A INPUT -s 214.0.0.0/8 -j DROP
  97. iptables -A OUTPUT -s 214.0.0.0/8 -j DROP
  98. iptables -A INPUT -s 215.0.0.0/8 -j DROP
  99. iptables -A OUTPUT -s 215.0.0.0/8 -j DROP
  100. save_firewall_settings
  101. mark_completed "${FUNCNAME[0]}"
  102. }
  103. function global_rate_limit {
  104. if ! grep -q "tcp_challenge_ack_limit" /etc/sysctl.conf; then
  105. echo 'net.ipv4.tcp_challenge_ack_limit = 999999999' >> /etc/sysctl.conf
  106. sysctl -p -q
  107. else
  108. if ! grep -q "net.ipv4.tcp_challenge_ack_limit = 999999999" /etc/sysctl.conf; then
  109. sed -i 's|net.ipv4.tcp_challenge_ack_limit.*|net.ipv4.tcp_challenge_ack_limit = 999999999|g' /etc/sysctl.conf
  110. sysctl -p -q
  111. fi
  112. fi
  113. }
  114. function enable_ipv6 {
  115. # endure that ipv6 is enabled and can route
  116. sed -i 's/net.ipv6.conf.all.disable_ipv6.*/net.ipv6.conf.all.disable_ipv6 = 0/g' /etc/sysctl.conf
  117. #sed -i "s/net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 1/g" /etc/sysctl.conf
  118. #sed -i "s/net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 1/g" /etc/sysctl.conf
  119. sed -i "s/net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=1/g" /etc/sysctl.conf
  120. echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
  121. }
  122. function firewall_disable_vpn {
  123. firewall_remove VPN 1194
  124. iptables -D INPUT -i ${FIREWALL_EIFACE} -m state --state NEW -p tcp --dport 1194 -j ACCEPT
  125. iptables -D INPUT -i tun+ -j ACCEPT
  126. iptables -D FORWARD -i tun+ -j ACCEPT
  127. iptables -D FORWARD -i tun+ -o ${FIREWALL_EIFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
  128. iptables -D FORWARD -i ${FIREWALL_EIFACE} -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
  129. iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o ${FIREWALL_EIFACE} -j MASQUERADE
  130. iptables -D OUTPUT -o tun+ -j ACCEPT
  131. save_firewall_settings
  132. }
  133. function firewall_enable_vpn {
  134. firewall_add VPN 1194 tcp
  135. iptables -A INPUT -i ${FIREWALL_EIFACE} -m state --state NEW -p tcp --dport 1194 -j ACCEPT
  136. iptables -A INPUT -i tun+ -j ACCEPT
  137. iptables -A FORWARD -i tun+ -j ACCEPT
  138. iptables -A FORWARD -i tun+ -o ${FIREWALL_EIFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
  139. iptables -A FORWARD -i ${FIREWALL_EIFACE} -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
  140. iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ${FIREWALL_EIFACE} -j MASQUERADE
  141. iptables -A OUTPUT -o tun+ -j ACCEPT
  142. save_firewall_settings
  143. }
  144. function configure_firewall {
  145. if [ "$INSTALLING_MESH" ]; then
  146. mesh_firewall
  147. return
  148. fi
  149. if grep -q "RELATED" /etc/firewall.conf; then
  150. # recreate the firewall to remove RELATED
  151. sed -i "/firewall/d" "$COMPLETION_FILE"
  152. fi
  153. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  154. return
  155. fi
  156. if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then
  157. # docker does its own firewalling
  158. return
  159. fi
  160. iptables -P INPUT ACCEPT
  161. ip6tables -P INPUT ACCEPT
  162. iptables -F
  163. ip6tables -F
  164. iptables -t nat -F
  165. ip6tables -t nat -F
  166. iptables -X
  167. ip6tables -X
  168. iptables -P INPUT DROP
  169. ip6tables -P INPUT DROP
  170. iptables -P FORWARD DROP
  171. ip6tables -P FORWARD DROP
  172. iptables -A INPUT -i lo -j ACCEPT
  173. iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
  174. # Drop invalid packets
  175. iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
  176. # Make sure incoming tcp connections are SYN packets
  177. iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
  178. iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
  179. # Drop SYN packets with suspicious MSS value
  180. iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
  181. # Drop packets with incoming fragments
  182. iptables -A INPUT -f -j DROP
  183. # Drop bogons
  184. iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
  185. iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
  186. iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  187. iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
  188. iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
  189. iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  190. iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
  191. iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
  192. iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
  193. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
  194. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
  195. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
  196. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
  197. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
  198. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
  199. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
  200. iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  201. # Incoming malformed NULL packets:
  202. iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
  203. mark_completed "${FUNCNAME[0]}"
  204. }
  205. function firewall_drop_telnet {
  206. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  207. return
  208. fi
  209. # telnet isn't enabled as an input and we can also
  210. # drop any outgoing telnet, just in case
  211. iptables -A OUTPUT -p tcp --dport telnet -j REJECT
  212. iptables -A OUTPUT -p udp --dport telnet -j REJECT
  213. function_check save_firewall_settings
  214. save_firewall_settings
  215. mark_completed "${FUNCNAME[0]}"
  216. }
  217. function configure_firewall_ping {
  218. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  219. return
  220. fi
  221. # Only allow ping for mesh installs
  222. if [[ $SYSTEM_TYPE != "mesh"* ]]; then
  223. return
  224. fi
  225. iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  226. iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  227. function_check save_firewall_settings
  228. save_firewall_settings
  229. mark_completed "${FUNCNAME[0]}"
  230. }
  231. function configure_internet_protocol {
  232. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  233. return
  234. fi
  235. if [[ $SYSTEM_TYPE == "mesh"* ]]; then
  236. return
  237. fi
  238. sed -i "s/#net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies=1/g" /etc/sysctl.conf
  239. sed -i "s/#net.ipv4.conf.all.accept_redirects.*/net.ipv4.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
  240. sed -i "s/#net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
  241. sed -i "s/#net.ipv4.conf.all.send_redirects.*/net.ipv4.conf.all.send_redirects = 0/g" /etc/sysctl.conf
  242. sed -i "s/#net.ipv4.conf.all.accept_source_route.*/net.ipv4.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
  243. sed -i "s/#net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
  244. sed -i "s/#net.ipv4.conf.default.rp_filter.*/net.ipv4.conf.default.rp_filter=1/g" /etc/sysctl.conf
  245. sed -i "s/#net.ipv4.conf.all.rp_filter.*/net.ipv4.conf.all.rp_filter=1/g" /etc/sysctl.conf
  246. sed -i "s/#net.ipv4.ip_forward.*/net.ipv4.ip_forward=0/g" /etc/sysctl.conf
  247. sed -i "s/#net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=0/g" /etc/sysctl.conf
  248. sed -i "s/# net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies=1/g" /etc/sysctl.conf
  249. sed -i "s/# net.ipv4.conf.all.accept_redirects.*/net.ipv4.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
  250. sed -i "s/# net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
  251. sed -i "s/# net.ipv4.conf.all.send_redirects.*/net.ipv4.conf.all.send_redirects = 0/g" /etc/sysctl.conf
  252. sed -i "s/# net.ipv4.conf.all.accept_source_route.*/net.ipv4.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
  253. sed -i "s/# net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
  254. sed -i "s/# net.ipv4.conf.default.rp_filter.*/net.ipv4.conf.default.rp_filter=1/g" /etc/sysctl.conf
  255. sed -i "s/# net.ipv4.conf.all.rp_filter.*/net.ipv4.conf.all.rp_filter=1/g" /etc/sysctl.conf
  256. sed -i "s/# net.ipv4.ip_forward.*/net.ipv4.ip_forward=0/g" /etc/sysctl.conf
  257. sed -i "s/# net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=0/g" /etc/sysctl.conf
  258. if ! grep -q "ignore pings" /etc/sysctl.conf; then
  259. echo '# ignore pings' >> /etc/sysctl.conf
  260. echo 'net.ipv4.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf
  261. #echo 'net.ipv6.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf
  262. fi
  263. if ! grep -q "disable ipv6" /etc/sysctl.conf; then
  264. echo '# disable ipv6' >> /etc/sysctl.conf
  265. echo 'net.ipv6.conf.all.disable_ipv6 = 1' >> /etc/sysctl.conf
  266. fi
  267. if ! grep -q "net.ipv4.tcp_synack_retries" /etc/sysctl.conf; then
  268. echo 'net.ipv4.tcp_synack_retries = 2' >> /etc/sysctl.conf
  269. echo 'net.ipv4.tcp_syn_retries = 1' >> /etc/sysctl.conf
  270. fi
  271. if ! grep -q "keepalive" /etc/sysctl.conf; then
  272. { echo '# keepalive';
  273. echo 'net.ipv4.tcp_keepalive_probes = 9';
  274. echo 'net.ipv4.tcp_keepalive_intvl = 75';
  275. echo 'net.ipv4.tcp_keepalive_time = 7200'; } >> /etc/sysctl.conf
  276. fi
  277. if ! grep -q "net.ipv4.conf.default.send_redirects" /etc/sysctl.conf; then
  278. echo "net.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.conf
  279. else
  280. sed -i "s|# net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
  281. sed -i "s|#net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
  282. sed -i "s|net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
  283. fi
  284. if ! grep -q "net.ipv4.conf.all.secure_redirects" /etc/sysctl.conf; then
  285. echo "net.ipv4.conf.all.secure_redirects = 0" >> /etc/sysctl.conf
  286. else
  287. sed -i "s|# net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
  288. sed -i "s|#net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
  289. sed -i "s|net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
  290. fi
  291. if ! grep -q "net.ipv4.conf.default.accept_source_route" /etc/sysctl.conf; then
  292. echo "net.ipv4.conf.default.accept_source_route = 0" >> /etc/sysctl.conf
  293. else
  294. sed -i "s|# net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
  295. sed -i "s|#net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
  296. sed -i "s|net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
  297. fi
  298. if ! grep -q "net.ipv4.conf.default.secure_redirects" /etc/sysctl.conf; then
  299. echo "net.ipv4.conf.default.secure_redirects = 0" >> /etc/sysctl.conf
  300. else
  301. sed -i "s|# net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
  302. sed -i "s|#net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
  303. sed -i "s|net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
  304. fi
  305. if ! grep -q "net.ipv4.conf.default.accept_redirects" /etc/sysctl.conf; then
  306. echo "net.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.conf
  307. else
  308. sed -i "s|# net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
  309. sed -i "s|#net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
  310. sed -i "s|net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
  311. fi
  312. # Randomize kernel
  313. if ! grep -q "kernel.randomize_va_space" /etc/sysctl.conf; then
  314. echo "kernel.randomize_va_space=2" >> /etc/sysctl.conf
  315. else
  316. sed -i 's|kernel.randomize_va_space.*|kernel.randomize_va_space=2|g' /etc/sysctl.conf
  317. fi
  318. # Turn off the tcp_timestamps
  319. if ! grep -q "net.ipv4.tcp_timestamps" /etc/sysctl.conf; then
  320. echo "net.ipv4.tcp_timestamps=0" >> /etc/sysctl.conf
  321. else
  322. sed -i 's|net.ipv4.tcp_timestamps.*|net.ipv4.tcp_timestamps=0|g' /etc/sysctl.conf
  323. fi
  324. /sbin/sysctl -p
  325. mark_completed "${FUNCNAME[0]}"
  326. }
  327. function mesh_firewall {
  328. # shellcheck disable=SC2154
  329. FIREWALL_FILENAME="${rootdir}/etc/systemd/system/meshfirewall.service"
  330. MESH_FIREWALL_SCRIPT=${rootdir}/usr/bin/mesh-firewall
  331. if ! grep -q 'telemetry.mozilla' "${rootdir}/etc/hosts"; then
  332. echo '127.0.0.1 telemetry.mozilla.org' >> "${rootdir}/etc/hosts"
  333. echo '127.0.0.1 incoming.telemetry.mozilla.org' >> "${rootdir}/etc/hosts"
  334. fi
  335. if ! grep -q 'facebook' "${rootdir}/etc/hosts"; then
  336. { echo '127.0.0.1 www.facebook.com';
  337. echo '127.0.0.1 facebook.com';
  338. echo '127.0.0.1 static.ak.fbcdn.net';
  339. echo '127.0.0.1 www.static.ak.fbcdn.net';
  340. echo '127.0.0.1 login.facebook.com';
  341. echo '127.0.0.1 www.login.facebook.com';
  342. echo '127.0.0.1 fbcdn.net';
  343. echo '127.0.0.1 www.fbcdn.net';
  344. echo '127.0.0.1 fbcdn.com';
  345. echo '127.0.0.1 www.fbcdn.com';
  346. echo '127.0.0.1 static.ak.connect.facebook.com';
  347. echo '127.0.0.1 www.static.ak.connect.facebook.com'; } >> "${rootdir}/etc/hosts"
  348. fi
  349. if ! grep -q 'google' "${rootdir}/etc/hosts"; then
  350. { echo '127.0.0.1 www.google-analytics.com';
  351. echo '127.0.0.1 google-analytics.com';
  352. echo '127.0.0.1 ssl.google-analytics.com'; } >> "${rootdir}/etc/hosts"
  353. fi
  354. { echo '#!/bin/bash';
  355. echo 'iptables -P INPUT ACCEPT';
  356. echo 'ip6tables -P INPUT ACCEPT';
  357. echo 'iptables -F';
  358. echo 'ip6tables -F';
  359. echo 'iptables -t nat -F';
  360. echo 'ip6tables -t nat -F';
  361. echo 'iptables -X';
  362. echo 'ip6tables -X';
  363. echo 'iptables -P INPUT DROP';
  364. echo 'ip6tables -P INPUT DROP';
  365. echo 'iptables -A INPUT -i lo -j ACCEPT';
  366. echo 'ip6tables -A INPUT -i lo -j ACCEPT';
  367. echo 'iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT';
  368. echo 'ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT';
  369. echo '';
  370. echo '# Make sure incoming tcp connections are SYN packets';
  371. echo 'iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP';
  372. echo 'ip6tables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP';
  373. echo '';
  374. echo '# Drop packets with incoming fragments';
  375. echo 'iptables -A INPUT -f -j DROP';
  376. echo 'ip6tables -A INPUT -f -j DROP';
  377. echo '';
  378. echo '# Drop bogons';
  379. echo 'iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP';
  380. echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP';
  381. echo 'iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP';
  382. echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP';
  383. echo 'iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP';
  384. echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP';
  385. echo '';
  386. echo '# Incoming malformed NULL packets:';
  387. echo 'iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP';
  388. echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP';
  389. echo '';
  390. echo "iptables -A INPUT -p tcp --dport $TOX_PORT -j ACCEPT";
  391. echo "ip6tables -A INPUT -p tcp --dport $TOX_PORT -j ACCEPT";
  392. echo "iptables -A INPUT -p udp --dport $ZERONET_PORT -j ACCEPT";
  393. echo "ip6tables -A INPUT -p udp --dport $ZERONET_PORT -j ACCEPT";
  394. echo "iptables -A INPUT -p tcp --dport $ZERONET_PORT -j ACCEPT";
  395. echo "ip6tables -A INPUT -p tcp --dport $ZERONET_PORT -j ACCEPT";
  396. echo "iptables -A INPUT -p udp --dport $TRACKER_PORT -j ACCEPT";
  397. echo "ip6tables -A INPUT -p udp --dport $TRACKER_PORT -j ACCEPT";
  398. echo "iptables -A INPUT -p tcp --dport $TRACKER_PORT -j ACCEPT";
  399. echo "ip6tables -A INPUT -p tcp --dport $TRACKER_PORT -j ACCEPT";
  400. echo "iptables -A INPUT -p udp --dport 1900 -j ACCEPT";
  401. echo "ip6tables -A INPUT -p udp --dport 1900 -j ACCEPT";
  402. echo "iptables -A INPUT -s $FIREFOX_TELEMETRY_IP -j DROP";
  403. echo "iptables -A OUTPUT -s $FIREFOX_TELEMETRY_IP -j DROP"; } > "$MESH_FIREWALL_SCRIPT"
  404. chmod +x "$MESH_FIREWALL_SCRIPT"
  405. { echo '[Unit]';
  406. echo 'Description=Mesh Firewall';
  407. echo '';
  408. echo '[Service]';
  409. echo 'Type=oneshot';
  410. echo 'ExecStart=/usr/bin/mesh-firewall';
  411. echo 'RemainAfterExit=no';
  412. echo '';
  413. echo 'TimeoutSec=30';
  414. echo '';
  415. echo '[Install]';
  416. echo 'WantedBy=multi-user.target'; } > "$FIREWALL_FILENAME"
  417. chmod +x "$FIREWALL_FILENAME"
  418. chroot "$rootdir" systemctl enable meshfirewall
  419. }
  420. function firewall_add {
  421. firewall_name=$(string="$1" ; echo "${string// /-}")
  422. firewall_port=$2
  423. firewall_protocol="$3"
  424. if ! grep -q "${firewall_name}=${firewall_port}" "$FIREWALL_CONFIG"; then
  425. echo "${firewall_name}=${firewall_port}" >> "$FIREWALL_CONFIG"
  426. if [ ! "${firewall_protocol}" ]; then
  427. if ! iptables -C INPUT -p udp --dport "${firewall_port}" -j ACCEPT; then
  428. iptables -A INPUT -p udp --dport "${firewall_port}" -j ACCEPT
  429. fi
  430. if ! iptables -C INPUT -p tcp --dport "${firewall_port}" -j ACCEPT; then
  431. iptables -A INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
  432. fi
  433. else
  434. if [[ "${firewall_protocol}" == *"udp"* ]]; then
  435. if ! iptables -C INPUT -p udp --dport "${firewall_port}" -j ACCEPT; then
  436. iptables -A INPUT -p udp --dport "${firewall_port}" -j ACCEPT
  437. fi
  438. fi
  439. if [[ "${firewall_protocol}" == *"tcp"* ]]; then
  440. if ! iptables -C INPUT -p tcp --dport "${firewall_port}" -j ACCEPT; then
  441. iptables -A INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
  442. fi
  443. fi
  444. fi
  445. save_firewall_settings
  446. fi
  447. }
  448. function firewall_add_range {
  449. firewall_name=$(string="$1" ; echo "${string// /-}")
  450. firewall_port_start=$2
  451. firewall_port_end=$3
  452. firewall_protocol="$4"
  453. if ! grep -q "${firewall_name}=${firewall_port_start}:${firewall_port_end}" "$FIREWALL_CONFIG"; then
  454. echo "${firewall_name}=${firewall_port_start}:${firewall_port_end}" >> "$FIREWALL_CONFIG"
  455. if [ ! "${firewall_protocol}" ]; then
  456. if ! iptables -C INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
  457. iptables -A INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
  458. fi
  459. if ! iptables -C INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
  460. iptables -A INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
  461. fi
  462. else
  463. if [[ "${firewall_protocol}" == *"udp"* ]]; then
  464. if ! iptables -C INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
  465. iptables -A INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
  466. fi
  467. fi
  468. if [[ "${firewall_protocol}" == *"tcp"* ]]; then
  469. if ! iptables -C INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
  470. iptables -A INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
  471. fi
  472. fi
  473. fi
  474. save_firewall_settings
  475. fi
  476. }
  477. function firewall_handle_port_scans {
  478. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  479. return
  480. fi
  481. # only works for high frequency port scanning
  482. # flooding of RST packets, smurf attack Rejection
  483. iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
  484. # Protecting portscans
  485. # Attacking IP will be locked for 24 hours (3600 x 24 = 86400 Seconds)
  486. iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
  487. iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP
  488. # Remove attacking IP after 24 hours
  489. iptables -A INPUT -m recent --name portscan --remove
  490. iptables -A FORWARD -m recent --name portscan --remove
  491. # These rules add scanners to the portscan list, and log the attempt.
  492. iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
  493. iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
  494. iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
  495. iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
  496. save_firewall_settings
  497. mark_completed "${FUNCNAME[0]}"
  498. }
  499. function firewall_remove {
  500. firewall_port=$1
  501. firewall_protocol="$2"
  502. if [ ! -f "$FIREWALL_CONFIG" ]; then
  503. return
  504. fi
  505. if grep -q "=${firewall_port}" "$FIREWALL_CONFIG"; then
  506. if [ ! "${firewall_protocol}" ]; then
  507. iptables -D INPUT -p udp --dport "${firewall_port}" -j ACCEPT
  508. iptables -D INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
  509. else
  510. if [[ "${firewall_protocol}" == *"udp"* ]]; then
  511. iptables -D INPUT -p udp --dport "${firewall_port}" -j ACCEPT
  512. fi
  513. if [[ "${firewall_protocol}" == *"tcp"* ]]; then
  514. iptables -D INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
  515. fi
  516. fi
  517. sed -i "/=${firewall_port}/d" "$FIREWALL_CONFIG"
  518. save_firewall_settings
  519. fi
  520. }
  521. function domain_to_hex_string {
  522. domain="$1"
  523. ctr=1
  524. segment=$(echo "$domain" | awk -F '.' -v value="$ctr" '{print $value}')
  525. while [ ${#segment} -gt 0 ]
  526. do
  527. characters=$(echo -n "$segment" | wc -c)
  528. hexnum=$(echo "obase=16; $characters" | bc)
  529. echo -n "|"
  530. if [ "$(echo -n "$hexnum" | wc -c)" -lt 2 ]; then
  531. echo -n "0"
  532. fi
  533. echo -n "$hexnum|$segment"
  534. ctr=$((ctr + 1))
  535. segment=$(echo "$domain" | awk -F '.' -v value="$ctr" '{print $value}')
  536. done
  537. echo ""
  538. }
  539. function firewall_block_domain {
  540. blocked_domain="$1"
  541. if [[ "$blocked_domain" == *'@'* ]]; then
  542. # Don't try to block email/microblog addresses
  543. echo "${blocked_domain}" >> "$FIREWALL_DOMAINS"
  544. return
  545. fi
  546. if ! grep -q "$blocked_domain" "$FIREWALL_DOMAINS"; then
  547. hexstr=$(domain_to_hex_string "$blocked_domain")
  548. if ! iptables -C INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP; then
  549. iptables -A INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  550. iptables -A INPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  551. iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  552. iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  553. iptables -I FORWARD -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  554. iptables -I FORWARD -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  555. echo "${blocked_domain}" >> "$FIREWALL_DOMAINS"
  556. save_firewall_settings
  557. fi
  558. # run the blocking rules now
  559. if [ -f /usr/bin/gnusocial-firewall ]; then
  560. /usr/bin/gnusocial-firewall
  561. fi
  562. if [ -f /usr/bin/postactiv-firewall ]; then
  563. /usr/bin/postactiv-firewall
  564. fi
  565. if [ -f /usr/bin/pleroma-blocking ]; then
  566. /usr/bin/pleroma-blocking
  567. fi
  568. fi
  569. }
  570. function firewall_block_ip {
  571. blocked_ip="$1"
  572. if [[ "$blocked_ip" == *'@'* ]]; then
  573. # Don't try to block email/microblog addresses
  574. return
  575. fi
  576. if ! grep -q "$blocked_ip" "$FIREWALL_DOMAINS"; then
  577. if ! iptables -C INPUT -s "$blocked_ip" -j DROP; then
  578. iptables -A INPUT -s "$blocked_ip" -j DROP
  579. iptables -A OUTPUT -s "$blocked_ip" -j DROP
  580. echo "${blocked_ip}" >> "$FIREWALL_DOMAINS"
  581. save_firewall_settings
  582. fi
  583. fi
  584. }
  585. function firewall_unblock_ip {
  586. blocked_ip="$1"
  587. if [[ "$blocked_ip" == *'@'* ]]; then
  588. # Don't try to block email/microblog addresses
  589. return
  590. fi
  591. if grep -q "$blocked_ip" "$FIREWALL_DOMAINS"; then
  592. iptables -D INPUT -s "$blocked_ip" -j DROP
  593. iptables -D OUTPUT -s "$blocked_ip" -j DROP
  594. sed -i "/$blocked_ip/d" "$FIREWALL_DOMAINS"
  595. echo "${blocked_ip}" >> "$FIREWALL_DOMAINS"
  596. save_firewall_settings
  597. fi
  598. }
  599. function firewall_refresh_blocklist {
  600. if [ ! -f "/root/${PROJECT_NAME}-firewall-domains.cfg" ]; then
  601. return
  602. fi
  603. while read -r blocked_domain; do
  604. firewall_block_domain "$blocked_domain"
  605. done <"/root/${PROJECT_NAME}-firewall-domains.cfg"
  606. }
  607. function firewall_unblock_domain {
  608. unblocked_domain="$1"
  609. if grep -q "${unblocked_domain}" "$FIREWALL_DOMAINS"; then
  610. if [[ "${unblocked_domain}" != *'@'* ]]; then
  611. hexstr=$(domain_to_hex_string "$unblocked_domain")
  612. iptables -D INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  613. iptables -D INPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  614. iptables -D OUTPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  615. iptables -D OUTPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  616. iptables -D FORWARD -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  617. iptables -D FORWARD -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
  618. save_firewall_settings
  619. fi
  620. sed -i "/${unblocked_domain}/d" "$FIREWALL_DOMAINS"
  621. fi
  622. if grep -q " $unblocked_domain" /etc/hosts; then
  623. sed -i "/ $unblocked_domain/d" /etc/hosts
  624. fi
  625. }
  626. function firewall_drop_spoofed_packets {
  627. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  628. return
  629. fi
  630. iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
  631. iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
  632. iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
  633. iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
  634. iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
  635. iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
  636. iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
  637. function_check save_firewall_settings
  638. save_firewall_settings
  639. mark_completed "${FUNCNAME[0]}"
  640. }
  641. function firewall_rate_limits {
  642. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  643. return
  644. fi
  645. # Limit connections per source IP
  646. iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset
  647. # Limit RST packets
  648. iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT
  649. iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
  650. # Limit new TCP connections per second per source IP
  651. iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT
  652. iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
  653. # SSH brute-force protection
  654. iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set
  655. iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
  656. function_check save_firewall_settings
  657. save_firewall_settings
  658. mark_completed "${FUNCNAME[0]}"
  659. }
  660. # NOTE: deliberately no exit 0