Advertisement
rockdrilla

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

Nov 20th, 2013
418
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 8.90 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 -v ${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.         for flavour in K U; do
  93.             err=0
  94.             case "${flavour}" in
  95.             K)  for i in ${dirs}; do test -d $i || err=1; done
  96.                 for i in ${files}; do test -e $i || err=1; done
  97.             ;;
  98.             U)  for i in ${binaries}; do binary_exist $i || err=1; done
  99.             ;;
  100.             *)  continue ;; # this may not happen at all.
  101.             esac
  102.  
  103.             eval "avail_${subsys}_${flavour}() { return ${err};}"
  104.         done
  105.     done
  106.  
  107.     return 0
  108. }
  109.  
  110. test_avail() {
  111.     subsys=$1 flavour=
  112.     case "$2" in
  113.     kernel)  flavour=K ;; # kernel-space
  114.     *)       flavour=U ;; # user-space
  115.     esac
  116.  
  117.     case "${subsys}" in
  118.     ipset|ipv4|ipv6) ;;
  119.     *) return 2 ;;
  120.     esac
  121.  
  122.     eval "avail_${subsys}_${flavour}"
  123. }
  124.  
  125. m_ok='[ok]'
  126. m_err='{ERROR}'
  127. m_skip='[skip]'
  128. m_skip_kernel='[skip: no kernel modules]'
  129. m_skip_user='[skip: no userspace bin]'
  130. m_skip_rules='[skip: no rules]'
  131.  
  132. load_rules() {
  133.     log_begin_msg "${NAME} loading rules: "
  134.  
  135.     subsystems='ipset ipv4 ipv6'
  136.     test $# -ne 0 && subsystems=$@
  137.  
  138.     for i in ${subsystems}; do
  139.         title= cmd= file=
  140.         case "$i" in
  141.         ipset)  title=IPset  cmd=load_rules_ipset  file=${RULES_set} ;;
  142.         ipv4)   title=IPv4   cmd=load_rules_ipv4   file=${RULES_v4}  ;;
  143.         ipv6)   title=IPv6   cmd=load_rules_ipv6   file=${RULES_v6}  ;;
  144.         *)
  145.             log_progress_msg " $i[unrecognized]"
  146.             continue
  147.         ;;
  148.         esac
  149.  
  150.         log_progress_msg "${title}"
  151.  
  152.         if ! test_avail $i kernel; then
  153.             log_progress_msg "${m_skip_kernel}"
  154.             continue
  155.         fi
  156.  
  157.         if ! test_avail $i user; then
  158.             log_progress_msg "${m_skip_user}"
  159.             continue
  160.         fi
  161.  
  162.         if ! test -f ${file}; then
  163.             log_progress_msg "${m_skip_rules}"
  164.             continue
  165.         fi
  166.  
  167.         ${cmd} < ${file}
  168.  
  169.         if test $? -ne 0
  170.         then log_progress_msg "${m_err}"
  171. #       else log_progress_msg "${m_ok}"
  172.         fi
  173.     done; unset subsystems i title cmd file
  174.  
  175.     log_end_msg 0
  176.     return 0
  177. }
  178. load_rules_ipset() { ipset restore; }
  179. load_rules_ipv4()  { iptables-restore; }
  180. load_rules_ipv6()  { ip6tables-restore; }
  181.  
  182. save_rules() {
  183.     log_begin_msg "${NAME} saving rules:"
  184.  
  185.     subsystems='ipset ipv4 ipv6'
  186.     test $# -ne 0 && subsystems=$@
  187.  
  188.     for i in ${subsystems}; do
  189.         title= cmd= file=
  190.         case "$i" in
  191.         ipset)  title=IPset  cmd=save_rules_ipset  file=${RULES_set} ;;
  192.         ipv4)   title=IPv4   cmd=save_rules_ipv4   file=${RULES_v4}  ;;
  193.         ipv6)   title=IPv6   cmd=save_rules_ipv6   file=${RULES_v6}  ;;
  194.         *)
  195.             log_progress_msg " $i[unrecognized]"
  196.             continue
  197.         ;;
  198.         esac
  199.  
  200.         log_progress_msg "${title}"
  201.  
  202.         if ! test_avail $i kernel; then
  203.             log_progress_msg "${m_skip_kernel}"
  204.             continue
  205.         fi
  206.  
  207.         if ! test_avail $i user; then
  208.             log_progress_msg "${m_skip_user}"
  209.             continue
  210.         fi
  211.  
  212.         if ! test -f ${file}; then
  213.             log_progress_msg "${m_skip_rules}"
  214.             continue
  215.         fi
  216.  
  217.         ${cmd} > ${file}
  218.  
  219.         if test $? -ne 0
  220.         then log_progress_msg "${m_err}"
  221. #       else log_progress_msg "${m_ok}"
  222.         fi
  223.     done; unset subsystems i title cmd file
  224.  
  225.     log_end_msg 0
  226.     return 0
  227. }
  228. save_rules_ipset() { ipset save; }
  229. save_rules_ipv4()  { iptables-save; }
  230. save_rules_ipv6()  { ip6tables-save; }
  231.  
  232. flush_rules() {
  233.     log_begin_msg "${NAME} flushing rules:"
  234.  
  235.     # reversed order IS correct
  236.     subsystems='ipv6 ipv4 ipset'
  237.     test $# -ne 0 && subsystems=$@
  238.  
  239.     for i in ${subsystems}; do
  240.         case "$i" in
  241.         ipset)  title=IPSet  cmd=flush_rules_ipset ;;
  242.         ipv4)   title=IPv4   cmd=flush_rules_ipv4  ;;
  243.         ipv6)   title=IPv6   cmd=flush_rules_ipv6  ;;
  244.         *)
  245.             log_progress_msg " $i[unrecognized]"
  246.             continue
  247.         ;;
  248.         esac
  249.  
  250.         log_progress_msg "${title}"
  251.  
  252.         if ! test_avail $i kernel; then
  253.             log_progress_msg "${m_skip_kernel}"
  254.             continue
  255.         fi
  256.  
  257.         if ! test_avail $i user; then
  258.             log_progress_msg "${m_skip_user}"
  259.             continue
  260.         fi
  261.  
  262.         ${cmd}
  263.  
  264.         if test $? -ne 0
  265.         then log_progress_msg "${m_err}"
  266. #       else log_progress_msg "${m_ok}"
  267.         fi
  268.     done; unset subsystems i title cmd
  269.  
  270.     log_end_msg 0
  271.     return 0
  272. }
  273. flush_rules_ipset() {
  274.     ipset flush
  275.     ipset destroy
  276. }
  277. flush_rules_ipv4() {
  278.     for chain in INPUT FORWARD OUTPUT; do
  279.         iptables -P ${chain} ACCEPT
  280.     done; unset chain
  281.     for table in $(cat /proc/net/ip_tables_names); do
  282.         iptables -t ${table} -F
  283.         iptables -t ${table} -X
  284.         iptables -t ${table} -Z
  285.     done; unset table
  286. }
  287. flush_rules_ipv6() {
  288.     for chain in INPUT FORWARD OUTPUT; do
  289.         ip6tables -P ${chain} ACCEPT
  290.     done; unset chain
  291.     for table in $(cat /proc/net/ip6_tables_names); do
  292.         ip6tables -t ${table} -F
  293.         ip6tables -t ${table} -X
  294.         ip6tables -t ${table} -Z
  295.     done; unset table
  296. }
  297.  
  298. work_init() {
  299.     init_avail
  300.  
  301.     # stderr redirection to /tmp/tmp.XXXXXXXXXX
  302.     U=$(umask); umask 0077 # more restrictive umask
  303.     T=$(mktemp)
  304.     umask $U; unset U # restore origin umask
  305.     exec 2>>$T
  306. }
  307. work_done() {
  308.     exec 2>/dev/null
  309.  
  310.     if test -s $T; then
  311.         N=10 i=0 S=
  312.  
  313.         log_begin_msg "${NAME} log contains some info; here is first $N (or less) lines of them:"
  314.         log_end_msg 255
  315.  
  316.         exec 3< $T
  317.         while test $i -lt $N; do
  318.             read -r S <&3 || break
  319.             printf '%s\n' "$S"
  320.             i=$((i+1))
  321.         done; unset i N
  322.         exec 3<&-
  323.     fi
  324.  
  325.     rm -f $T; unset T
  326. }
  327.  
  328. R=0
  329.  
  330. act=$1; test $# -gt 0 && shift
  331. case "${act}" in
  332. start|reload)
  333.     work_init
  334.     load_rules "$@"
  335.     work_done
  336. ;;
  337. save)
  338.     work_init
  339.     save_rules "$@"
  340.     work_done
  341. ;;
  342. flush)
  343.     work_init
  344.     flush_rules "$@"
  345.     work_done
  346. ;;
  347. restart|force-reload)
  348.     work_init
  349.     flush_rules "$@"
  350.     load_rules "$@"
  351.     work_done
  352. ;;
  353. stop)
  354.     # Why? because if stop is used, the firewall gets flushed for a variable
  355.     # amount of time during package upgrades, leaving the machine vulnerable
  356.     # It's also not always desirable to flush during purge
  357.     echo 'Automatic flushing disabled, use "flush" instead of "stop"' >&2
  358. ;;
  359. *)
  360.     echo "Usage: $0 {start|restart|reload|force-reload|save|flush} {ipset|ipv4|ipv6}" >&2
  361.     R=1
  362. ;;
  363. esac
  364.  
  365. exit $R
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement