Advertisement
rockdrilla

/etc/init.d/iptables-persistent rc.4

Nov 20th, 2013
450
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.80 KB | None | 0 0
  1. #!/bin/sh
  2. #   Written by Simon Richter <sjr@debian.org>
  3. #   Modified by Jonathan Wiltshire <jmw@debian.org>
  4. #       with help from Christoph Anton Mitterer
  5. #   Modified by Konstantin Demin <rockdrilla@gmail.com>
  6. #       with God willing
  7.  
  8. ### BEGIN INIT INFO
  9. # Provides:          iptables-persistent
  10. # Required-Start:    mountkernfs $local_fs
  11. # Required-Stop:     $local_fs
  12. # Default-Start:     2 3 4 5
  13. # Default-Stop:      0 1 6
  14. # X-Start-Before:    $network
  15. # X-Stop-After:      $network
  16. # Short-Description: Set up iptables rules
  17. # Description:       Loads/saves current iptables rules from/to /etc/iptables
  18. #                    to provide a persistent rule set during boot time
  19. ### END INIT INFO
  20.  
  21. NAME=iptables-persistent
  22. RULES=/etc/iptables/rules
  23. RULES_set=${RULES}.ipset
  24. RULES_v4=${RULES}.ipv4
  25. RULES_v6=${RULES}.ipv6
  26.  
  27.  
  28. export PATH=/sbin:/bin
  29. . /lib/lsb/init-functions
  30.  
  31. # partial /bin/which realization
  32. # only checks if binary exists
  33. binary_exist() {
  34.     IFS_BAK=${IFS} IFS=':' notfound=1
  35.  
  36.     # if PATH ends with ':' then search in current directory too (IFS hack)
  37.     case "${PATH}" in
  38.     *[!:]:) PATH="${PATH}:" ;;
  39.     esac
  40.  
  41.     case "$1" in
  42.     */*)
  43.         binary_exist_h "$1" && notfound=0
  44.     ;;
  45.     *)
  46.         for location in ${PATH}; do
  47.             test -z "${location}" && location=.
  48.             binary_exist_h "${location}/$1" && notfound=0 && break
  49.         done
  50.     ;;
  51.     esac
  52.     IFS=${IFS_BAK}
  53.     return ${notfound}
  54. }
  55. binary_exist_h() { test -f "$1" && test -x "$1"; }
  56.  
  57. load_module() {
  58.     module=
  59.     case "$1" in
  60.     ipset)  module=ip_set          ;;
  61.     ipv4)   module=iptable_filter  ;;
  62.     ipv6)   module=ip6table_filter ;;
  63.     *)      return 2 ;;
  64.     esac
  65.  
  66.     modprobe -q ${module}
  67.     return 0
  68. }
  69.  
  70. # keep in sync with test_avail()
  71. init_avail() {
  72.     for subsys in ipset ipv4 ipv6; do
  73.         case "${subsys}" in
  74.         ipset)
  75.             dirs='/sys/module/ip_set '
  76.             files=
  77.             binaries='ipset '
  78.         ;;
  79.         ipv4)
  80.             dirs=
  81.             files='/proc/net/ip_tables_names '
  82.             binaries='iptables iptables-restore iptables-save '
  83.         ;;
  84.         ipv6)
  85.             dirs=
  86.             files='/proc/net/ip6_tables_names '
  87.             binaries='ip6tables ip6tables-restore ip6tables-save '
  88.         ;;
  89.         *) continue ;; # this may not happen at all.
  90.         esac
  91.  
  92.         load_module ${subsys}
  93.  
  94.         for flavour in K U; do
  95.             err=0
  96.             case "${flavour}" in
  97.             K)  for i in ${dirs}; do test -d $i || err=1; done
  98.                 for i in ${files}; do test -e $i || err=1; done
  99.             ;;
  100.             U)  for i in ${binaries}; do binary_exist $i || err=1; done
  101.             ;;
  102.             *)  continue ;; # this may not happen at all.
  103.             esac
  104.  
  105.             eval "avail_${subsys}_${flavour}() { return ${err};}"
  106.         done
  107.     done
  108.  
  109.     return 0
  110. }
  111.  
  112. test_avail() {
  113.     subsys=$1 flavour=
  114.     case "$2" in
  115.     kernel)  flavour=K ;; # kernel-space
  116.     *)       flavour=U ;; # user-space
  117.     esac
  118.  
  119.     case "${subsys}" in
  120.     ipset|ipv4|ipv6) ;;
  121.     *) return 2 ;;
  122.     esac
  123.  
  124.     eval "avail_${subsys}_${flavour}"
  125. }
  126.  
  127. m_ok='[ok]'
  128. m_err='{ERROR}'
  129. m_skip='[skip]'
  130. m_skip_kernel='[skip: no kernel modules]'
  131. m_skip_user='[skip: no userspace bin]'
  132. m_skip_rules='[skip: no rules]'
  133.  
  134. load_rules() {
  135.     log_begin_msg "${NAME} loading rules:"
  136.  
  137.     subsystems='ipset ipv4 ipv6'
  138.     test $# -ne 0 && subsystems=$@
  139.  
  140.     c_total=0 c_success=0
  141.     for i in ${subsystems}; do
  142.         c_total=$((c_total+1))
  143.  
  144.         title= cmd= file=
  145.         case "$i" in
  146.         ipset)  title=IPset  cmd=load_rules_ipset  file=${RULES_set} ;;
  147.         ipv4)   title=IPv4   cmd=load_rules_ipv4   file=${RULES_v4}  ;;
  148.         ipv6)   title=IPv6   cmd=load_rules_ipv6   file=${RULES_v6}  ;;
  149.         *)
  150.             log_progress_msg " $i[unrecognized]"
  151.             continue
  152.         ;;
  153.         esac
  154.  
  155.         log_progress_msg "${title}"
  156.  
  157.         if ! test_avail $i kernel; then
  158.             log_progress_msg "${m_skip_kernel}"
  159.             continue
  160.         fi
  161.  
  162.         if ! test_avail $i user; then
  163.             log_progress_msg "${m_skip_user}"
  164.             continue
  165.         fi
  166.  
  167.         if ! test -f ${file}; then
  168.             log_progress_msg "${m_skip_rules}"
  169.             continue
  170.         fi
  171.  
  172.         ${cmd} < ${file}
  173.  
  174.         if test $? -ne 0; then
  175.             log_progress_msg "${m_err}"
  176.         else
  177. #           log_progress_msg "${m_ok}"
  178.             c_success=$((c_success+1))
  179.         fi
  180.     done; unset subsystems i title cmd file
  181.  
  182.     rc=0 # success
  183.     test ${c_success} -lt ${c_total} && rc=255 # warning
  184.     test ${c_success} -eq 0          && rc=1 # failure
  185.     unset c_total c_success
  186.  
  187.     log_end_msg ${rc}; unset rc
  188.     return 0
  189. }
  190. load_rules_ipset() { ipset restore; }
  191. load_rules_ipv4()  { iptables-restore; }
  192. load_rules_ipv6()  { ip6tables-restore; }
  193.  
  194. save_rules() {
  195.     log_begin_msg "${NAME} saving rules:"
  196.  
  197.     subsystems='ipset ipv4 ipv6'
  198.     test $# -ne 0 && subsystems=$@
  199.  
  200.     c_total=0 c_success=0
  201.     for i in ${subsystems}; do
  202.         c_total=$((c_total+1))
  203.  
  204.         title= cmd= file=
  205.         case "$i" in
  206.         ipset)  title=IPset  cmd=save_rules_ipset  file=${RULES_set} ;;
  207.         ipv4)   title=IPv4   cmd=save_rules_ipv4   file=${RULES_v4}  ;;
  208.         ipv6)   title=IPv6   cmd=save_rules_ipv6   file=${RULES_v6}  ;;
  209.         *)
  210.             log_progress_msg " $i[unrecognized]"
  211.             continue
  212.         ;;
  213.         esac
  214.  
  215.         log_progress_msg "${title}"
  216.  
  217.         if ! test_avail $i kernel; then
  218.             log_progress_msg "${m_skip_kernel}"
  219.             continue
  220.         fi
  221.  
  222.         if ! test_avail $i user; then
  223.             log_progress_msg "${m_skip_user}"
  224.             continue
  225.         fi
  226.  
  227.         if ! test -f ${file}; then
  228.             log_progress_msg "${m_skip_rules}"
  229.             continue
  230.         fi
  231.  
  232.         ${cmd} > ${file}
  233.  
  234.         if test $? -ne 0; then
  235.             log_progress_msg "${m_err}"
  236.         else
  237. #           log_progress_msg "${m_ok}"
  238.             c_success=$((c_success+1))
  239.         fi
  240.     done; unset subsystems i title cmd file
  241.  
  242.     rc=0 # success
  243.     test ${c_success} -lt ${c_total} && rc=255 # warning
  244.     test ${c_success} -eq 0          && rc=1 # failure
  245.     unset c_total c_success
  246.  
  247.     log_end_msg ${rc}; unset rc
  248.     return 0
  249. }
  250. save_rules_ipset() { ipset save; }
  251. save_rules_ipv4()  { iptables-save; }
  252. save_rules_ipv6()  { ip6tables-save; }
  253.  
  254. flush_rules() {
  255.     log_begin_msg "${NAME} flushing rules:"
  256.  
  257.     # reversed order IS correct
  258.     subsystems='ipv6 ipv4 ipset'
  259.     test $# -ne 0 && subsystems=$@
  260.  
  261.     c_total=0 c_success=0
  262.     for i in ${subsystems}; do
  263.         c_total=$((c_total+1))
  264.  
  265.         case "$i" in
  266.         ipset)  title=IPSet  cmd=flush_rules_ipset ;;
  267.         ipv4)   title=IPv4   cmd=flush_rules_ipv4  ;;
  268.         ipv6)   title=IPv6   cmd=flush_rules_ipv6  ;;
  269.         *)
  270.             log_progress_msg " $i[unrecognized]"
  271.             continue
  272.         ;;
  273.         esac
  274.  
  275.         log_progress_msg "${title}"
  276.  
  277.         if ! test_avail $i kernel; then
  278.             log_progress_msg "${m_skip_kernel}"
  279.             continue
  280.         fi
  281.  
  282.         if ! test_avail $i user; then
  283.             log_progress_msg "${m_skip_user}"
  284.             continue
  285.         fi
  286.  
  287.         ${cmd}
  288.  
  289.         if test $? -ne 0; then
  290.             log_progress_msg "${m_err}"
  291.         else
  292. #           log_progress_msg "${m_ok}"
  293.             c_success=$((c_success+1))
  294.         fi
  295.     done; unset subsystems i title cmd
  296.  
  297.     rc=0 # success
  298.     test ${c_success} -lt ${c_total} && rc=255 # warning
  299.     test ${c_success} -eq 0          && rc=1 # failure
  300.     unset c_total c_success
  301.  
  302.     log_end_msg ${rc}; unset rc
  303.     return 0
  304. }
  305. flush_rules_ipset() {
  306.     ipset flush
  307.     ipset destroy
  308. }
  309. flush_rules_ipv4() {
  310.     for chain in INPUT FORWARD OUTPUT; do
  311.         iptables -P ${chain} ACCEPT
  312.     done; unset chain
  313.     for table in $(cat /proc/net/ip_tables_names); do
  314.         iptables -t ${table} -F
  315.         iptables -t ${table} -X
  316.         iptables -t ${table} -Z
  317.     done; unset table
  318. }
  319. flush_rules_ipv6() {
  320.     for chain in INPUT FORWARD OUTPUT; do
  321.         ip6tables -P ${chain} ACCEPT
  322.     done; unset chain
  323.     for table in $(cat /proc/net/ip6_tables_names); do
  324.         ip6tables -t ${table} -F
  325.         ip6tables -t ${table} -X
  326.         ip6tables -t ${table} -Z
  327.     done; unset table
  328. }
  329.  
  330. work_init() {
  331.     init_avail
  332.  
  333.     # stderr redirection to /tmp/tmp.XXXXXXXXXX
  334.     U=$(umask); umask 0077 # more restrictive umask
  335.     T=$(mktemp)
  336.     umask $U; unset U # restore origin umask
  337.     exec 2>>$T
  338. }
  339. work_done() {
  340.     exec 2>/dev/null
  341.  
  342.     if test -s $T; then
  343.         N=10 i=0 S=
  344.  
  345.         log_begin_msg "${NAME} log contains some info; here is first $N (or less) lines of them:"
  346.         log_end_msg 255
  347.  
  348.         exec 3< $T
  349.         while test $i -lt $N; do
  350.             read -r S <&3 || break
  351.             printf '%s\n' "$S"
  352.             i=$((i+1))
  353.         done; unset i N
  354.         exec 3<&-
  355.     fi
  356.  
  357.     rm -f $T; unset T
  358. }
  359.  
  360. R=0
  361.  
  362. act=$1; test $# -gt 0 && shift
  363. case "${act}" in
  364. start|reload)
  365.     work_init
  366.     load_rules "$@"
  367.     work_done
  368. ;;
  369. save)
  370.     work_init
  371.     save_rules "$@"
  372.     work_done
  373. ;;
  374. flush)
  375.     work_init
  376.     flush_rules "$@"
  377.     work_done
  378. ;;
  379. restart|force-reload)
  380.     work_init
  381.     flush_rules "$@"
  382.     load_rules "$@"
  383.     work_done
  384. ;;
  385. stop)
  386.     # Why? because if stop is used, the firewall gets flushed for a variable
  387.     # amount of time during package upgrades, leaving the machine vulnerable
  388.     # It's also not always desirable to flush during purge
  389.     echo 'Automatic flushing disabled, use "flush" instead of "stop"' >&2
  390. ;;
  391. *)
  392.     echo "Usage: $0 {start|restart|reload|force-reload|save|flush} [ipset|ipv4|ipv6]" >&2
  393.     R=1
  394. ;;
  395. esac
  396.  
  397. exit $R
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement