fw4 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #!/bin/sh
  2. set -o pipefail
  3. MAIN=/usr/share/firewall4/main.uc
  4. LOCK=/var/run/fw4.lock
  5. STATE=/var/run/fw4.state
  6. VERBOSE=
  7. [ -e /dev/stdin ] && STDIN=/dev/stdin || STDIN=/proc/self/fd/0
  8. [ -t 2 ] && export TTY=1
  9. die() {
  10. [ -n "$QUIET" ] || echo "$@" >&2
  11. exit 1
  12. }
  13. start() {
  14. {
  15. flock -x 1000
  16. case "$1" in
  17. start)
  18. [ -f $STATE ] && die "The fw4 firewall appears to be already loaded."
  19. ;;
  20. reload)
  21. [ ! -f $STATE ] && die "The fw4 firewall does not appear to be loaded."
  22. # Delete state to force reloading ubus state
  23. rm -f $STATE
  24. ;;
  25. esac
  26. ACTION=start \
  27. utpl -S $MAIN | nft $VERBOSE -f $STDIN
  28. ACTION=includes \
  29. utpl -S $MAIN
  30. } 1000>$LOCK
  31. }
  32. print() {
  33. ACTION=print \
  34. utpl -S $MAIN
  35. }
  36. stop() {
  37. {
  38. flock -x 1000
  39. if nft list tables inet | grep -sq "table inet fw4"; then
  40. nft delete table inet fw4
  41. rm -f $STATE
  42. else
  43. return 1
  44. fi
  45. } 1000>$LOCK
  46. }
  47. flush() {
  48. {
  49. flock -x 1000
  50. local dummy family table
  51. nft list tables | while read dummy family table; do
  52. nft delete table "$family" "$table"
  53. done
  54. rm -f $STATE
  55. } 1000>$LOCK
  56. }
  57. reload_sets() {
  58. ACTION=reload-sets \
  59. flock -x $LOCK utpl -S $MAIN | nft $VERBOSE -f $STDIN
  60. }
  61. lookup() {
  62. ACTION=$1 OBJECT=$2 DEVICE=$3 \
  63. flock -x $LOCK utpl -S $MAIN
  64. }
  65. while [ -n "$1" ]; do
  66. case "$1" in
  67. -q)
  68. export QUIET=1
  69. shift
  70. ;;
  71. -v)
  72. export VERBOSE=-e
  73. shift
  74. ;;
  75. *)
  76. break
  77. ;;
  78. esac
  79. done
  80. case "$1" in
  81. start|reload)
  82. start "$1"
  83. ;;
  84. stop)
  85. stop || die "The fw4 firewall does not appear to be loaded, try fw4 flush to delete all rules."
  86. ;;
  87. flush)
  88. flush
  89. ;;
  90. restart)
  91. QUIET=1 print | nft ${VERBOSE} -c -f $STDIN || die "The rendered ruleset contains errors, not doing firewall restart."
  92. stop || rm -f $STATE
  93. start
  94. ;;
  95. check)
  96. if [ -n "$QUIET" ]; then
  97. exec 1>/dev/null
  98. exec 2>/dev/null
  99. fi
  100. print | nft ${VERBOSE} -c -f $STDIN && echo "Ruleset passes nftables check."
  101. ;;
  102. print)
  103. print
  104. ;;
  105. reload-sets)
  106. reload_sets
  107. ;;
  108. network|device|zone)
  109. lookup "$@"
  110. ;;
  111. *)
  112. cat <<EOT
  113. Usage:
  114. $0 [-v] [-q] start|stop|flush|restart|reload
  115. Start, stop, flush, restart or reload the firewall respectively.
  116. $0 [-v] [-q] reload-sets
  117. Reload the contents of all declared sets but do not touch the
  118. ruleset.
  119. $0 [-q] print
  120. Print the rendered ruleset.
  121. $0 [-q] check
  122. Test the rendered ruleset using nftables' check mode without
  123. applying it to the running system.
  124. $0 [-q] network {net}
  125. Print the name of the firewall zone covering the given network.
  126. Exits with code 1 if the network is not found or if no zone is
  127. covering it.
  128. $0 [-q] device {dev}
  129. Print the name of the firewall zone covering the given device.
  130. Exits with code 1 if the device is not found or if no zone is
  131. covering it.
  132. $0 [-q] zone {zone} [dev]
  133. Print all covered devices of the given zone, optionally restricted
  134. to only the given device name.
  135. Exits with code 1 if zone is not found or if a device is specified
  136. and not covered by the given zone.
  137. EOT
  138. ;;
  139. esac