lfirewall 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. #!/bin/dash
  2. ### BEGIN INIT INFO
  3. # Provides: firewall.sh
  4. # Required-Start: $syslog $network
  5. # Required-Stop: $syslog $network
  6. # Default-Start: 2 3 4 5
  7. # Default-Stop: 0 1 6
  8. # Short-Description: Start firewall daemon at boot time
  9. # Description: Custom Firewall scrip.
  10. ### END INIT INFO
  11. #
  12. # Light Firewall configuration.
  13. #
  14. # Original author : Nicolargo
  15. #
  16. # chkconfig: 2345 9 91
  17. # description: Activates/Deactivates the firewall at boot time
  18. #
  19. CONFIGURATION_DIR=/etc/lfirewall
  20. . ${CONFIGURATION_DIR}/setup
  21. process_and_parent=`find_systemctl_pids`
  22. restart_mode=no
  23. if [ -n "${process_and_parent}" ]
  24. then
  25. if has_parent_process ${process_and_parent} > /dev/null
  26. then
  27. shell_process=`echo ${process_and_parent} | awk '{print $1}'`
  28. parent_term=`readlink /proc/${shell_process}/fd/2`
  29. fi
  30. # Find if systemctl is in restart mode
  31. for process_id in ${process_and_parent}
  32. do
  33. if [ `ps -o comm= -p $process_id` = "systemctl" ] \
  34. && ps -o args -p $process_id | grep -v COMMAND | grep restart > /dev/null
  35. then
  36. restart_mode=yes
  37. break
  38. fi
  39. done
  40. fi
  41. set -eu
  42. help_message_lfirewall(){
  43. cat <<-EOF
  44. Light Firewall configuration script.
  45. `basename ${0}` [OPTIONS...] COMMAND
  46. COMMANDS
  47. start : starts the firewall
  48. stop : stops the firewall (removes rules set by this script)
  49. clear : clears the firewall (removes all IPTABLES rules and let all connections work)
  50. dropall : drops all network connections (USE with CAUTION)
  51. test : tests the existing rules for 30 seconds
  52. saveuser : backup of the user (custom) rules
  53. OPTIONS
  54. -v --verbose : verbose mode
  55. -h --help : display this help message
  56. -l --logging : enables logging (prefix: iptables-logging)
  57. BACKING UP USER RULES
  58. WARNING: PLEASE FOLLOW CAREFULLY THE ACTIONS BELOW
  59. 1. Before setting any rule: clear the firewall
  60. 2. Setup your rules
  61. 3. run:
  62. `basename ${0}` saveuser
  63. AUTHOR
  64. Author: Laurent Hubert
  65. Idea by: Nicolargo
  66. EOF
  67. }
  68. options=$(getopt -l "help,verbose,logging" -o "hvl" -- "$@")
  69. if [ $? != 0 ] ; then
  70. help_message_lfirewall
  71. exit 1
  72. fi
  73. eval set -- "$options"
  74. verbose=0
  75. logging=" "
  76. while :
  77. do
  78. if [ ${verbose} = "1" ] ; then
  79. echo "$@"
  80. fi
  81. case "$1" in
  82. -h|--help)
  83. help_message_lfirewall
  84. exit 0
  85. ;;
  86. -v|--verbose)
  87. verbose=$(( verbose + 1 ))
  88. if [ ${verbose} -gt 1 ]
  89. then
  90. set -x
  91. fi
  92. if [ ${verbose} -gt 2 ]
  93. then
  94. set -v
  95. fi
  96. ;;
  97. -l|--logging)
  98. logging="-j LOG --log-prefix 'iptables-logging'"
  99. IT_INPUT=${IT_INPUT_LOG}
  100. IT_OUTPUT=${IT_OUTPUT_LOG}
  101. ;;
  102. --)
  103. shift
  104. break
  105. ;;
  106. esac
  107. shift
  108. done
  109. if ! [ -x $IP_TABLES ]; then
  110. echo "$IP_TABLES is not executable or not present" >&2
  111. exit 1
  112. fi
  113. if ! [ -x $IP_TABLES_RESTORE ]; then
  114. echo "$IP_TABLES_RESTORE is not executable or not present" >&2
  115. exit 3
  116. fi
  117. if ! [ -x $IP_TABLES_RESTORE_6 ]; then
  118. echo "$IP_TABLES_RESTORE_6 is not executable or not present" >&2
  119. exit 6
  120. fi
  121. if [ -f $CONFIGURATION_FILE ] ; then
  122. set +u
  123. . $CONFIGURATION_FILE
  124. set -u
  125. fi
  126. if [ -f $CONFIGURATION_LOCAL_FILE ] ; then
  127. set +u
  128. . $CONFIGURATION_LOCAL_FILE
  129. set -u
  130. fi
  131. # Should I disable this ?
  132. # I think I should... but will the
  133. if ! /usr/bin/ip link show $NETWORK_IF > /dev/null 2>&1
  134. then
  135. echo "Network interface '$NETWORK_IF' is not present" >&2
  136. exit 2
  137. fi
  138. do_log=do_not_log_action
  139. export verbose
  140. ##########################
  141. # Drops INPUT
  142. ##########################
  143. fw_exec_basic_input_rules(){
  144. local do_action
  145. do_action=$1
  146. ### Blocks any incoming
  147. $do_action $IPTABLES_SET_POLICY $IT_INPUT DROP
  148. ### Keep existing connections
  149. $do_action $IPTABLES_ADD $IT_INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  150. # Remote testing
  151. ### Allows PING
  152. $do_action $IPTABLES_ADD $IT_INPUT -p icmp -j ACCEPT
  153. ### Allows LOOPBACK
  154. $do_action $IPTABLES_ADD $IT_INPUT -i lo -j ACCEPT
  155. }
  156. ##########################
  157. # Executes the Firewall rules
  158. ##########################
  159. fw_execute () {
  160. local do_action
  161. do_action=$1
  162. #**************************************************************************#
  163. # Input traffic:
  164. #**************************************************************************#
  165. fw_exec_basic_input_rules $do_action
  166. # Services
  167. if [ -n "$TCP_SERVICES" ] ; then
  168. for PORT in $TCP_SERVICES; do
  169. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${PORT} -j ACCEPT
  170. done
  171. fi
  172. if [ -n "$UDP_SERVICES" ] ; then
  173. for PORT in $UDP_SERVICES; do
  174. $do_action $IPTABLES_ADD $IT_INPUT -p udp --dport ${PORT} -j ACCEPT
  175. done
  176. fi
  177. # Remote management
  178. if [ "${NETWORK_MGMT:=UNBOUND_VARIABLE}" != "UNBOUND_VARIABLE" ] ; then
  179. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --src ${NETWORK_MGMT} --dport ${SSH_PORT} -j ACCEPT
  180. else
  181. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${SSH_PORT} -j ACCEPT
  182. fi
  183. # SSH
  184. if [ ! -z "${SSH_PORT:-}" ] ; then
  185. $do_action $IPTABLES_ADD $IT_OUTPUT -t filter -p tcp --dport "$SSH_PORT" -j ACCEPT
  186. $do_action $IPTABLES_ADD $IT_INPUT -t filter -p tcp --dport "$SSH_PORT" -j ACCEPT
  187. else
  188. $do_action $IPTABLES_ADD $IT_OUTPUT -t filter -p tcp --dport "22" -j ACCEPT
  189. $do_action $IPTABLES_ADD $IT_INPUT -t filter -p tcp --dport "22" -j ACCEPT
  190. fi
  191. #**************************************************************************#
  192. # NGINX
  193. #**************************************************************************#
  194. $do_action $IPTABLES_ADD $IT_INPUT -i lo -s localhost -d localhost -j ACCEPT
  195. $do_action $IPTABLES_ADD $IT_OUTPUT -o lo -s localhost -d localhost -j ACCEPT
  196. #**************************************************************************#
  197. # Output:
  198. #**************************************************************************#
  199. ### Allows LOOPBACK
  200. $do_action $IPTABLES_ADD $IT_OUTPUT -j ACCEPT -o lo
  201. ###
  202. $do_action $IPTABLES_ADD $IT_OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  203. # ICMP is permitted:
  204. ### Allows ping:
  205. $do_action $IPTABLES_ADD $IT_OUTPUT -p icmp -j ACCEPT
  206. # As well as the services we have defined:
  207. if [ -n "$REMOTE_TCP_SERVICES" ] ; then
  208. for PORT in $REMOTE_TCP_SERVICES; do
  209. $do_action $IPTABLES_ADD $IT_OUTPUT -p tcp --dport ${PORT} -j ACCEPT
  210. done
  211. fi
  212. if [ -n "$REMOTE_UDP_SERVICES" ] ; then
  213. for PORT in $REMOTE_UDP_SERVICES; do
  214. $do_action $IPTABLES_ADD $IT_OUTPUT -p udp --dport ${PORT} -j ACCEPT
  215. done
  216. fi
  217. if [ "${ACTIVATE_LOGGING:-1}" = 1 ]
  218. then
  219. # All other connections are registered in system log's backend
  220. $do_action $IPTABLES_ADD $IT_INPUT -j LOG
  221. $do_action $IPTABLES_ADD $IT_OUTPUT -j LOG
  222. $do_action $IPTABLES_ADD $IT_OUTPUT -j REJECT
  223. $do_action $IPTABLES_ADD FORWARD -j LOG
  224. fi
  225. $do_action $IPTABLES_SET_POLICY $IT_OUTPUT DROP
  226. #**************************************************************************#
  227. # DOS attack protection
  228. #**************************************************************************#
  229. # See http://rockdio.org/ayudatech/how-to-stop-small-ddos-attacks-some-basic-security-advice/
  230. #
  231. $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --set
  232. $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
  233. $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --set
  234. $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
  235. #**************************************************************************#
  236. # blacklist action
  237. #**************************************************************************#
  238. fw_blacklist $do_action
  239. fw_execute_post_up_down $do_action
  240. fw_execute_post_start_stop $do_action
  241. #**************************************************************************#
  242. # whitelist action
  243. #**************************************************************************#
  244. fw_whitelist $do_action
  245. }
  246. EXECUTE_LFIREWALL_DIR=`dirname $0`/execute_lfirewall_dir
  247. fw_execute_post_up_down(){
  248. local do_action
  249. do_action=$1
  250. set +eu
  251. ${EXECUTE_LFIREWALL_DIR} -f ${do_action} ${POST_UP_DOWN_SCRIPTS_DIR}
  252. set -eu
  253. }
  254. fw_execute_post_start_stop(){
  255. local do_action
  256. do_action=$1
  257. set +eu
  258. ${EXECUTE_LFIREWALL_DIR} ${do_action} ${POST_START_STOP_SCRIPTS_DIR}
  259. set -eu
  260. }
  261. warn_user_missing_ban_list() {
  262. local ban_list_name
  263. ban_list_name=$1
  264. printf "###############################################################\n\r" >&2
  265. printf "# IMPORTANT WARNING !!! #\n\r" >&2
  266. printf "# Banned list named '$ban_list_name' does not exist #\n\r" >&2
  267. printf "# Please create it using with at least one entry using : #\n\r" >&2
  268. printf "# # ipset create $ban_list_name hash:net hashsize 4096 #\n\r" >&2
  269. printf "# #\n\r" >&2
  270. printf "###############################################################\n\r" >&2
  271. }
  272. fw_blacklist(){
  273. local do_action
  274. do_action=$1
  275. case $do_action in
  276. do_exec)
  277. if [ -n "${BANNED_LISTS:-}" ]
  278. then
  279. for ban_list in ${BANNED_LISTS}
  280. do
  281. if ipset list ${ban_list} > /dev/null
  282. then
  283. if ! iptables -C INPUT -m set --match-set ${ban_list} src -j DROP > /dev/null 2>&1
  284. then
  285. echo "Enabling $ban_list"
  286. iptables -I INPUT -m set --match-set ${ban_list} src -j DROP
  287. fi
  288. else
  289. warn_user_missing_ban_list ${ban_list}
  290. fi
  291. done
  292. fi
  293. ;;
  294. *)
  295. ;;
  296. esac
  297. }
  298. warn_user_no_whitelist() {
  299. printf "###############################################################\n\r" >&2
  300. printf "# IMPORTANT WARNING !!! #\n\r" >&2
  301. printf "# Your whitelist is empty or non existent #\n\r" >&2
  302. printf "# Please create one using with at least one entry using : #\n\r" >&2
  303. printf "# # ipset create whitelist hash:net hashsize 4096 #\n\r" >&2
  304. printf "# #\n\r" >&2
  305. printf "# Append at least your IP address using one of the following: #\n\r" >&2
  306. printf "# # ipset add whitelist 12.34.56.78 #\n\r" >&2
  307. printf "# # ipset add whitelist 192.168.0.0/16 #\n\r" >&2
  308. printf "# #\n\r" >&2
  309. printf "###############################################################\n\r" >&2
  310. }
  311. fw_whitelist() {
  312. local do_action
  313. do_action=$1
  314. if ! ipset list whitelist > /dev/null
  315. then
  316. warn_user_no_whitelist
  317. return
  318. else
  319. if [ `ipset list whitelist 2> /dev/null | awk '/Number of entries/ {print $NF}'` -eq 0 ]
  320. then
  321. warn_user_no_whitelist
  322. return
  323. fi
  324. fi
  325. if [ -n "$TCP_SERVICES" ] ; then
  326. for PORT in $TCP_SERVICES; do
  327. $do_action $IPTABLES_INSERT $IT_INPUT -p tcp -m tcp --dport ${PORT} -m set --match-set whitelist src -j ACCEPT
  328. done
  329. fi
  330. if [ -n "$UDP_SERVICES" ] ; then
  331. for PORT in $UDP_SERVICES; do
  332. $do_action $IPTABLES_INSERT $IT_INPUT -p udp -m udp --dport ${PORT} -m set --match-set whitelist src -j ACCEPT
  333. done
  334. fi
  335. }
  336. fw_network_protection(){
  337. #**************************************************************************#
  338. # Other network protections
  339. # (some will only work with some kernel versions)
  340. #**************************************************************************#
  341. if [ "${ALLOW_IP_FORWARDING:-0}" = 0 ]
  342. then
  343. echo 0 > /proc/sys/net/ipv4/ip_forward
  344. else
  345. echo 1 > /proc/sys/net/ipv4/ip_forward
  346. fi
  347. if [ "${NETWORK_PROTECTION:-1}" = 1 ]
  348. then
  349. echo 1 > /proc/sys/net/ipv4/tcp_syncookies
  350. echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  351. echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
  352. echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
  353. echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
  354. echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
  355. echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
  356. echo "Firewall network protection enhancement set"
  357. fi
  358. }
  359. do_this(){
  360. if [ ${verbose} -ge 1 ] ; then
  361. echo $*
  362. fi
  363. $*
  364. }
  365. ##########################
  366. # Backups user rules
  367. ##########################
  368. fw_backup_user(){
  369. $IP_TABLES_SAVE > ${USER_RULES_IPTABLES}
  370. $IP_TABLES_SAVE_6 > ${USER_RULES_IPTABLES_6}
  371. }
  372. ##########################
  373. # Restores user rules
  374. ##########################
  375. fw_restore_user(){
  376. if [ -f $USER_RULES_IPTABLES ] ; then
  377. $IP_TABLES_RESTORE < ${USER_RULES_IPTABLES}
  378. fi
  379. if [ -f $USER_RULES_IPTABLES_6 ] ; then
  380. $IP_TABLES_RESTORE_6 < ${USER_RULES_IPTABLES_6}
  381. fi
  382. }
  383. ##########################
  384. # Stop the Firewall rules
  385. ##########################
  386. fw_stop () {
  387. global_status=0
  388. # Start will not really start but exec the "do_delete" action
  389. fw_execute do_delete
  390. if [ 0 -eq "$global_status" ] ; then
  391. echo "Firewall rules removed"
  392. return 0
  393. else
  394. echo "Some firewall rules were not removed !!!"
  395. return $global_status
  396. fi
  397. }
  398. ##########################
  399. # Drop any incoming
  400. # but keep existing ones
  401. ##########################
  402. fw_dropall(){
  403. do_this $IP_TABLES -F
  404. do_this $IP_TABLES -t nat -F
  405. do_this $IP_TABLES -t mangle -F
  406. fw_exec_basic_input_rules do_exec
  407. do_this $IP_TABLES -P FORWARD ACCEPT
  408. do_this $IP_TABLES -P OUTPUT ACCEPT
  409. }
  410. ##########################
  411. # Clear the Firewall rules
  412. ##########################
  413. fw_clear () {
  414. do_this $IP_TABLES -F
  415. do_this $IP_TABLES -X
  416. do_this $IP_TABLES -P INPUT ACCEPT
  417. do_this $IP_TABLES -P FORWARD ACCEPT
  418. do_this $IP_TABLES -P OUTPUT ACCEPT
  419. }
  420. ##########################
  421. # Test the Firewall rules
  422. ##########################
  423. fw_save () {
  424. if [ ${verbose} -ge 1 ] ; then
  425. echo "$IP_TABLES_SAVE > /etc/lfirewall/iptables.backup"
  426. fi
  427. $IP_TABLES_SAVE > /etc/lfirewall/iptables.backup
  428. }
  429. fw_restore () {
  430. fw_clear
  431. BACKUP_FILE=/etc/lfirewall/iptables.backup
  432. if [ -e $BACKUP_FILE ]; then
  433. if [ ${verbose} -ge 1 ] ; then
  434. echo "IP_TABLES_RESTORE > $BACKUP_FILE"
  435. fi
  436. $IP_TABLES_RESTORE < $BACKUP_FILE
  437. fi
  438. }
  439. fw_test () {
  440. fw_save
  441. sleep 30 && echo "Restoring previous Firewall rules" && fw_restore && echo "Done" &
  442. fw_stop
  443. fw_execute do_exec
  444. wait $(jobs -p)
  445. }
  446. if [ ${verbose} -gt 0 ] ; then
  447. do_log=log_action
  448. fi
  449. export do_log
  450. case "$1" in
  451. start|restart)
  452. echo -n "Starting firewall.."
  453. fw_stop
  454. fw_restore_user
  455. fw_execute do_exec
  456. echo "Firewall rules added"
  457. fw_network_protection
  458. echo "done."
  459. ;;
  460. saveuser)
  461. echo "###############################################################"
  462. echo "# Backing up user rules to /etc/lfirewall/iptables-user.v* #"
  463. echo "# #"
  464. echo "# Other iptables rules should not be removed unless you use #"
  465. echo "# the 'clear' command (which deletes every rule) #"
  466. echo "# If you used the 'clear' command, you can restore them by #"
  467. echo "# using the 'start' command to restore them #"
  468. echo "###############################################################"
  469. echo -n "Backing up rules"
  470. fw_backup_user
  471. echo "done."
  472. ;;
  473. stop)
  474. echo "###############################################################"
  475. echo "# Removing rules set by this tool #"
  476. echo "# #"
  477. echo "# Other iptables rules should not be removed unless you use #"
  478. echo "# the 'clear' command #"
  479. echo "# Use 'dropall' to stop any traffic and block everything. #"
  480. echo "###############################################################"
  481. fw_stop
  482. ;;
  483. clear)
  484. echo "###############################################################"
  485. echo "# Clearing any rule and let the firewall pass any packet #"
  486. echo "# #"
  487. echo "# You can restore them by using the 'start' command #"
  488. echo "###############################################################"
  489. echo -n "Clearing firewall rules.."
  490. fw_clear
  491. echo "done."
  492. ;;
  493. dropall)
  494. echo "Droping all connections !!!"
  495. fw_dropall
  496. echo "done."
  497. if [ -c "${parent_term:-}" ]
  498. then
  499. exec 2>${parent_term}
  500. fi
  501. if [ "${restart_mode}" = "no" ]
  502. then
  503. printf "###############################################################\n\r" >&2
  504. printf "# IMPORTANT WARNING !!! #\n\r" >&2
  505. printf "# From now any new SSH session or INPUT #\n\r" >&2
  506. printf "# WILL BE REFUSED #\n\r" >&2
  507. printf "# If you NEED to continue working remotely, #\n\r" >&2
  508. printf "# run one of the 'lfirewall clear', 'lfirewall stop' #\n\r" >&2
  509. printf "# 'lfirewall start' commands #\n\r" >&2
  510. printf "# NOW !!! #\n\r" >&2
  511. printf "###############################################################\n\r" >&2
  512. fi
  513. ;;
  514. test)
  515. echo "Test Firewall rules..."
  516. echo "Previous configuration will be restore in 30 seconds"
  517. fw_test
  518. ;;
  519. status)
  520. global_status=0
  521. # Start will not really start but exec the "check" action
  522. fw_execute do_check
  523. if [ 0 -eq "$global_status" ] ; then
  524. echo "Firewall rules match configuration"
  525. exit 0
  526. else
  527. echo "Some firewall rules are not set correctly"
  528. exit $global_status
  529. fi
  530. ;;
  531. *)
  532. echo "Usage: $0 {start|dropall|stop|restart|clear|test}"
  533. echo "###############################################################"
  534. echo "# Be aware that 'dropall' will block #"
  535. echo "# all incoming/outgoing traffic !!! #"
  536. echo "###############################################################"
  537. echo "Use start option to restore all rules."
  538. echo "Use clear option to remove all traffic."
  539. echo "Use stop option to allow all traffic."
  540. exit 1
  541. ;;
  542. esac