lfirewall 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #!/bin/bash
  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. set -euo pipefail
  20. help_message_lfirewall(){
  21. cat <<-EOF
  22. Light Firewall configuration script.
  23. $(basename ${0}) [OPTIONS...] COMMAND
  24. COMMANDS
  25. start : starts the firewall
  26. clear : stops the firewall (removes all IPTABLES rules and let all connections work)
  27. stop : stops all network connections (USE with CAUTION)
  28. test : tests the existing rules for 30 seconds
  29. OPTIONS
  30. -v --verbose : verbose mode
  31. -h --help : display this help message
  32. -l --logging : enables logging (prefix: iptables-logging)
  33. AUTHOR
  34. Original author: Nicolargo
  35. Modified by: Laurent Hubert
  36. EOF
  37. }
  38. options=$(getopt -l "help,verbose,logging" -o "hvl" -- "$@")
  39. if [[ $? != 0 ]] ; then
  40. help_message_lfirewall
  41. exit 1
  42. fi
  43. eval set -- "$options"
  44. IT_INPUT=INPUT
  45. IT_INPUT_LOG=LOGINPUT
  46. IT_OUTPUT=OUTPUT
  47. IT_OUTPUT_LOG=LOGOUTPUT
  48. verbose=0
  49. logging=" "
  50. while :
  51. do
  52. if [[ ${verbose} = "1" ]] ; then
  53. echo "$@"
  54. fi
  55. case "$1" in
  56. -h|--help)
  57. help_message_lfirewall
  58. exit 0
  59. ;;
  60. -v|--verbose)
  61. verbose=$(( verbose + 1 ))
  62. if [[ ${verbose} -gt 1 ]]
  63. then
  64. set -x
  65. fi
  66. if [[ ${verbose} -gt 2 ]]
  67. then
  68. set -v
  69. fi
  70. ;;
  71. -l|--logging)
  72. logging="-j LOG --log-prefix 'iptables-logging'"
  73. IT_INPUT=${IT_INPUT_LOG}
  74. IT_OUTPUT=${IT_OUTPUT_LOG}
  75. ;;
  76. --)
  77. shift
  78. break
  79. ;;
  80. esac
  81. shift
  82. done
  83. PATH=/bin:/sbin:/usr/bin:/usr/sbin
  84. #Defautl network interface
  85. NETWORK_IF=eth0
  86. # Services that the system will offer to the network
  87. TCP_SERVICES="22" # SSH only
  88. UDP_SERVICES=""
  89. # Services the system will use from the network
  90. REMOTE_TCP_SERVICES="80 443" # web browsing
  91. REMOTE_UDP_SERVICES="53" # DNS
  92. # Network that will be used for remote mgmt
  93. # (if undefined, no rules will be setup)
  94. # NETWORK_MGMT=192.168.0.0/24
  95. # Port used for the SSH service, define this is you have setup a
  96. # management network but remove it from TCP_SERVICES
  97. SSH_PORT="22"
  98. # Default IP_TABLES command path
  99. IP_TABLES="/sbin/iptables"
  100. CONFIGURATION_FILE=/etc/lfirewall/lfirewall.conf
  101. if [ -f $CONFIGURATION_FILE ] ; then
  102. set +u
  103. . $CONFIGURATION_FILE
  104. set -u
  105. fi
  106. if ! [ -x $IP_TABLES ]; then
  107. echo "$IP_TABLES is not executable or not present" >&2
  108. exit 1
  109. fi
  110. if ! /usr/sbin/ifup --no-act $NETWORK_IF
  111. then
  112. echo "Network interface '$NETWORK_IF' is not present or configured" >&2
  113. exit 2
  114. fi
  115. do_action=do_exec
  116. IPTABLES_CHECK=__iptables_check_action
  117. IPTABLES_ADD=__iptable_add_action
  118. IPTABLES_SET_POLICY=__iptable_set_policy_action
  119. do_exec () {
  120. case $1 in
  121. __iptable_add_action)
  122. shift
  123. iptables_option=-A
  124. ;;
  125. __iptable_set_policy_action)
  126. shift
  127. iptables_option=-P
  128. ;;
  129. *)
  130. echo "Nothing to be done for $1"
  131. ;;
  132. esac
  133. if [[ ${verbose} -ge 1 ]] ; then
  134. echo $IP_TABLES $iptables_option $*
  135. fi
  136. $IP_TABLES $iptables_option $*
  137. }
  138. do_check () {
  139. the_action=$1
  140. shift
  141. case $the_action in
  142. __iptable_add_action)
  143. iptables_option=-A
  144. ;;
  145. __iptable_set_policy_action)
  146. return 0
  147. ;;
  148. *)
  149. echo "Nothing to be done for $1"
  150. ;;
  151. esac
  152. default_option=-C
  153. if [[ ${verbose} -ge 1 ]] ; then
  154. echo $do_log "$the_action:" $IP_TABLES -C $*
  155. echo $IP_TABLES -C $*
  156. fi
  157. $do_log "$the_action:" $IP_TABLES -C $*
  158. $IP_TABLES -C $*
  159. global_status=$((global_status+$?))
  160. }
  161. log_action () {
  162. echo $*
  163. }
  164. do_not_log_action () {
  165. return 0
  166. }
  167. do_log=do_not_log_action
  168. ##########################
  169. # Start the Firewall rules
  170. ##########################
  171. fw_start () {
  172. #**************************************************************************#
  173. # Input traffic:
  174. #**************************************************************************#
  175. ### Keep existing connections
  176. $do_action $IPTABLES_ADD $IT_INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  177. # Services
  178. if [ -n "$TCP_SERVICES" ] ; then
  179. for PORT in $TCP_SERVICES; do
  180. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${PORT} -j ACCEPT
  181. done
  182. fi
  183. if [ -n "$UDP_SERVICES" ] ; then
  184. for PORT in $UDP_SERVICES; do
  185. $do_action $IPTABLES_ADD $IT_INPUT -p udp --dport ${PORT} -j ACCEPT
  186. done
  187. fi
  188. # Remote management
  189. if [ "${NETWORK_MGMT:=UNBOUND_VARIABLE}" != "UNBOUND_VARIABLE" ] ; then
  190. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --src ${NETWORK_MGMT} --dport ${SSH_PORT} -j ACCEPT
  191. else
  192. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${SSH_PORT} -j ACCEPT
  193. fi
  194. #**************************************************************************#
  195. # NGINX
  196. #**************************************************************************#
  197. $do_action $IPTABLES_ADD $IT_INPUT -i lo -s localhost -d localhost -j ACCEPT
  198. $do_action $IPTABLES_ADD $IT_OUTPUT -o lo -s localhost -d localhost -j ACCEPT
  199. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport http -j ACCEPT
  200. $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport https -j ACCEPT
  201. # Remote testing
  202. ### Allows PING
  203. $do_action $IPTABLES_ADD $IT_INPUT -p icmp -j ACCEPT
  204. ### Allows LOOPBACK
  205. $do_action $IPTABLES_ADD $IT_INPUT -i lo -j ACCEPT
  206. $IP_TABLES -P $IT_INPUT DROP
  207. $do_action $IPTABLES_ADD $IT_INPUT -j LOG
  208. #**************************************************************************#
  209. # Output:
  210. #**************************************************************************#
  211. ### Allows LOOPBACK
  212. $do_action $IPTABLES_ADD $IT_OUTPUT -j ACCEPT -o lo
  213. ###
  214. $do_action $IPTABLES_ADD $IT_OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  215. # ICMP is permitted:
  216. ### Allows ping:
  217. $do_action $IPTABLES_ADD $IT_OUTPUT -p icmp -j ACCEPT
  218. # As well as the services we have defined:
  219. if [ -n "$REMOTE_TCP_SERVICES" ] ; then
  220. for PORT in $REMOTE_TCP_SERVICES; do
  221. $do_action $IPTABLES_ADD $IT_OUTPUT -p tcp --dport ${PORT} -j ACCEPT
  222. done
  223. fi
  224. if [ -n "$REMOTE_UDP_SERVICES" ] ; then
  225. for PORT in $REMOTE_UDP_SERVICES; do
  226. $do_action $IPTABLES_ADD $IT_OUTPUT -p udp --dport ${PORT} -j ACCEPT
  227. done
  228. fi
  229. # All other connections are registered in syslog
  230. $do_action $IPTABLES_ADD $IT_OUTPUT -j LOG
  231. $do_action $IPTABLES_ADD $IT_OUTPUT -j REJECT
  232. $do_action $IPTABLES_SET_POLICY $IT_OUTPUT DROP
  233. $do_action $IPTABLES_ADD FORWARD -j LOG
  234. #**************************************************************************#
  235. # DOS attack protection
  236. #**************************************************************************#
  237. # See http://rockdio.org/ayudatech/how-to-stop-small-ddos-attacks-some-basic-security-advice/
  238. #
  239. $IP_TABLES -I $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --set
  240. $IP_TABLES -I $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
  241. $IP_TABLES -I $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --set
  242. $IP_TABLES -I $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
  243. #**************************************************************************#
  244. # Other network protections
  245. # (some will only work with some kernel versions)
  246. #**************************************************************************#
  247. echo 1 > /proc/sys/net/ipv4/tcp_syncookies
  248. if [[ "${ALLOW_IP_FORWARDING}" = 0 ]]
  249. then
  250. echo 0 > /proc/sys/net/ipv4/ip_forward
  251. else
  252. echo 1 > /proc/sys/net/ipv4/ip_forward
  253. fi
  254. echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  255. echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
  256. echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
  257. echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
  258. echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
  259. echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
  260. iptables -t filter -A $IT_OUTPUT -p tcp --dport 22 -j ACCEPT
  261. iptables -t filter -A $IT_INPUT -p tcp --dport 22 -j ACCEPT
  262. }
  263. do_this(){
  264. if [[ ${verbose} -ge 1 ]] ; then
  265. echo $*
  266. fi
  267. $*
  268. }
  269. ##########################
  270. # Stop the Firewall rules
  271. ##########################
  272. fw_stop () {
  273. do_this $IP_TABLES -F
  274. do_this $IP_TABLES -t nat -F
  275. do_this $IP_TABLES -t mangle -F
  276. do_this $IP_TABLES -P $IT_INPUT DROP
  277. do_this $IP_TABLES -P FORWARD DROP
  278. do_this $IP_TABLES -P $IT_OUTPUT ACCEPT
  279. }
  280. ##########################
  281. # Clear the Firewall rules
  282. ##########################
  283. fw_clear () {
  284. do_this $IP_TABLES -F
  285. do_this $IP_TABLES -t nat -F
  286. do_this $IP_TABLES -t mangle -F
  287. do_this $IP_TABLES -P $IT_INPUT ACCEPT
  288. do_this $IP_TABLES -P FORWARD ACCEPT
  289. do_this $IP_TABLES -P $IT_OUTPUT ACCEPT
  290. do_this $IP_TABLES -X
  291. }
  292. ##########################
  293. # Test the Firewall rules
  294. ##########################
  295. fw_save () {
  296. if [[ ${verbose} -ge 1 ]] ; then
  297. echo "$IP_TABLES-save > /etc/iptables.backup"
  298. fi
  299. $IP_TABLES-save > /etc/iptables.backup
  300. }
  301. fw_restore () {
  302. if [ -e /etc/iptables.backup ]; then
  303. if [[ ${verbose} -ge 1 ]] ; then
  304. echo "$IP_TABLES-save > /etc/iptables.backup"
  305. fi
  306. $IP_TABLES-restore < /etc/iptables.backup
  307. fi
  308. }
  309. fw_test () {
  310. fw_save
  311. sleep 30 && echo "Restore previous Firewall rules..." && fw_restore &
  312. fw_stop
  313. fw_start
  314. }
  315. case "$1" in
  316. start|restart)
  317. echo -n "Starting firewall.."
  318. fw_stop
  319. fw_start
  320. echo "done."
  321. ;;
  322. stop)
  323. echo "###############################################################"
  324. echo "I do not stop for now."
  325. echo "Use 'clear' to remove all firewall blocking rules."
  326. echo "Use 'dropall' to stop any traffic and block everything."
  327. echo "###############################################################"
  328. ;;
  329. clear)
  330. echo -n "Clearing firewall rules.."
  331. fw_clear
  332. echo "done."
  333. ;;
  334. dropall)
  335. echo -n "Droping all connections !!!"
  336. fw_stop
  337. echo "done."
  338. ;;
  339. test)
  340. echo -n "Test Firewall rules..."
  341. fw_test
  342. echo -n "Previous configuration will be restore in 30 seconds"
  343. ;;
  344. status)
  345. do_action=do_check
  346. global_status=0
  347. if [ "$2" = "-v" ] ; then
  348. do_log=log_action
  349. fi
  350. # Start will not really start but exec the "check" action
  351. fw_start
  352. if [ 0 -eq "$global_status" ] ; then
  353. echo "Firewall rules match configuration"
  354. exit 0
  355. else
  356. echo "Some firewall rules are not set correctly"
  357. exit $global_status
  358. fi
  359. ;;
  360. *)
  361. echo "Usage: $0 {start|dropall|stop|restart|clear|test}"
  362. echo "###############################################################"
  363. echo "# Be aware that 'stop' drop all incoming/outgoing traffic !!! #"
  364. echo "###############################################################"
  365. echo "Use clear option to allow all traffic."
  366. exit 1
  367. ;;
  368. esac
  369. exit 0