xref: /freebsd/contrib/blocklist/libexec/blacklistd-helper (revision 5f4c09dd85bff675e0ca63c55ea3c517e0fddfcc)
1*5f4c09ddSEd Maste#!/bin/sh
2*5f4c09ddSEd Maste#echo "run $@" 1>&2
3*5f4c09ddSEd Maste#set -x
4*5f4c09ddSEd Maste# $1 command
5*5f4c09ddSEd Maste# $2 rulename
6*5f4c09ddSEd Maste# $3 protocol
7*5f4c09ddSEd Maste# $4 address
8*5f4c09ddSEd Maste# $5 mask
9*5f4c09ddSEd Maste# $6 port
10*5f4c09ddSEd Maste# $7 id
11*5f4c09ddSEd Maste
12*5f4c09ddSEd Mastepf=
13*5f4c09ddSEd Masteif [ -f "/etc/ipfw-blacklist.rc" ]; then
14*5f4c09ddSEd Maste	pf="ipfw"
15*5f4c09ddSEd Maste	. /etc/ipfw-blacklist.rc
16*5f4c09ddSEd Maste	ipfw_offset=${ipfw_offset:-2000}
17*5f4c09ddSEd Mastefi
18*5f4c09ddSEd Maste
19*5f4c09ddSEd Masteif [ -z "$pf" ]; then
20*5f4c09ddSEd Maste	for f in npf pf ipf; do
21*5f4c09ddSEd Maste		if [ -f "/etc/$f.conf" ]; then
22*5f4c09ddSEd Maste			pf="$f"
23*5f4c09ddSEd Maste			break
24*5f4c09ddSEd Maste		fi
25*5f4c09ddSEd Maste	done
26*5f4c09ddSEd Mastefi
27*5f4c09ddSEd Maste
28*5f4c09ddSEd Masteif [ -z "$pf" ]; then
29*5f4c09ddSEd Maste	echo "$0: Unsupported packet filter" 1>&2
30*5f4c09ddSEd Maste	exit 1
31*5f4c09ddSEd Mastefi
32*5f4c09ddSEd Maste
33*5f4c09ddSEd Masteif [ -n "$3" ]; then
34*5f4c09ddSEd Maste	proto="proto $3"
35*5f4c09ddSEd Mastefi
36*5f4c09ddSEd Maste
37*5f4c09ddSEd Masteif [ -n "$6" ]; then
38*5f4c09ddSEd Maste	port="port $6"
39*5f4c09ddSEd Mastefi
40*5f4c09ddSEd Maste
41*5f4c09ddSEd Masteaddr="$4"
42*5f4c09ddSEd Mastemask="$5"
43*5f4c09ddSEd Mastecase "$4" in
44*5f4c09ddSEd Maste::ffff:*.*.*.*)
45*5f4c09ddSEd Maste	if [ "$5" = 128 ]; then
46*5f4c09ddSEd Maste		mask=32
47*5f4c09ddSEd Maste		addr=${4#::ffff:}
48*5f4c09ddSEd Maste	fi;;
49*5f4c09ddSEd Masteesac
50*5f4c09ddSEd Maste
51*5f4c09ddSEd Mastecase "$1" in
52*5f4c09ddSEd Masteadd)
53*5f4c09ddSEd Maste	case "$pf" in
54*5f4c09ddSEd Maste	ipf)
55*5f4c09ddSEd Maste		/sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1
56*5f4c09ddSEd Maste		echo block in quick $proto from $addr/$mask to \
57*5f4c09ddSEd Maste		    any port=$6 head port$6 | \
58*5f4c09ddSEd Maste		    /sbin/ipf -I -f - -s >/dev/null 2>&1 && echo OK
59*5f4c09ddSEd Maste		;;
60*5f4c09ddSEd Maste	ipfw)
61*5f4c09ddSEd Maste		# use $ipfw_offset+$port for rule number
62*5f4c09ddSEd Maste		rule=$(($ipfw_offset + $6))
63*5f4c09ddSEd Maste		tname="port$6"
64*5f4c09ddSEd Maste		/sbin/ipfw table $tname create type addr 2>/dev/null
65*5f4c09ddSEd Maste		/sbin/ipfw -q table $tname add "$addr/$mask"
66*5f4c09ddSEd Maste		# if rule number $rule does not already exist, create it
67*5f4c09ddSEd Maste		/sbin/ipfw show $rule >/dev/null 2>&1 || \
68*5f4c09ddSEd Maste			/sbin/ipfw add $rule drop $3 from \
69*5f4c09ddSEd Maste			table"("$tname")" to any dst-port $6 >/dev/null && \
70*5f4c09ddSEd Maste			echo OK
71*5f4c09ddSEd Maste		;;
72*5f4c09ddSEd Maste	npf)
73*5f4c09ddSEd Maste		/sbin/npfctl rule "$2" add block in final $proto from \
74*5f4c09ddSEd Maste		    "$addr/$mask" to any $port
75*5f4c09ddSEd Maste		;;
76*5f4c09ddSEd Maste	pf)
77*5f4c09ddSEd Maste		# if the filtering rule does not exist, create it
78*5f4c09ddSEd Maste		/sbin/pfctl -a "$2/$6" -sr 2>/dev/null | \
79*5f4c09ddSEd Maste		    grep -q "<port$6>" || \
80*5f4c09ddSEd Maste		    echo "block in quick $proto from <port$6> to any $port" | \
81*5f4c09ddSEd Maste		    /sbin/pfctl -a "$2/$6" -f -
82*5f4c09ddSEd Maste		# insert $ip/$mask into per-protocol/port anchored table
83*5f4c09ddSEd Maste		/sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \
84*5f4c09ddSEd Maste		    /sbin/pfctl -qk "$addr" && echo OK
85*5f4c09ddSEd Maste		;;
86*5f4c09ddSEd Maste	esac
87*5f4c09ddSEd Maste	;;
88*5f4c09ddSEd Masterem)
89*5f4c09ddSEd Maste	case "$pf" in
90*5f4c09ddSEd Maste	ipf)
91*5f4c09ddSEd Maste		/sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1
92*5f4c09ddSEd Maste		echo block in quick $proto from $addr/$mask to \
93*5f4c09ddSEd Maste		    any port=$6 head port$6 | \
94*5f4c09ddSEd Maste		    /sbin/ipf -I -r -f - -s >/dev/null 2>&1 && echo OK
95*5f4c09ddSEd Maste		;;
96*5f4c09ddSEd Maste	ipfw)
97*5f4c09ddSEd Maste		/sbin/ipfw table "port$6" delete "$addr/$mask" 2>/dev/null && \
98*5f4c09ddSEd Maste		    echo OK
99*5f4c09ddSEd Maste		;;
100*5f4c09ddSEd Maste	npf)
101*5f4c09ddSEd Maste		/sbin/npfctl rule "$2" rem-id "$7"
102*5f4c09ddSEd Maste		;;
103*5f4c09ddSEd Maste	pf)
104*5f4c09ddSEd Maste		/sbin/pfctl -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
105*5f4c09ddSEd Maste		    echo OK
106*5f4c09ddSEd Maste		;;
107*5f4c09ddSEd Maste	esac
108*5f4c09ddSEd Maste	;;
109*5f4c09ddSEd Masteflush)
110*5f4c09ddSEd Maste	case "$pf" in
111*5f4c09ddSEd Maste	ipf)
112*5f4c09ddSEd Maste		/sbin/ipf -Z -I -Fi -s > /dev/null && echo OK
113*5f4c09ddSEd Maste		;;
114*5f4c09ddSEd Maste	ipfw)
115*5f4c09ddSEd Maste		/sbin/ipfw table "port$6" flush 2>/dev/null && echo OK
116*5f4c09ddSEd Maste		;;
117*5f4c09ddSEd Maste	npf)
118*5f4c09ddSEd Maste		/sbin/npfctl rule "$2" flush
119*5f4c09ddSEd Maste		;;
120*5f4c09ddSEd Maste	pf)
121*5f4c09ddSEd Maste		# dynamically determine which anchors exist
122*5f4c09ddSEd Maste		for anchor in $(/sbin/pfctl -a "$2" -s Anchors); do
123*5f4c09ddSEd Maste			/sbin/pfctl -a $anchor -t "port${anchor##*/}" -T flush
124*5f4c09ddSEd Maste			/sbin/pfctl -a $anchor -F rules
125*5f4c09ddSEd Maste		done
126*5f4c09ddSEd Maste		echo OK
127*5f4c09ddSEd Maste		;;
128*5f4c09ddSEd Maste	esac
129*5f4c09ddSEd Maste	;;
130*5f4c09ddSEd Maste*)
131*5f4c09ddSEd Maste	echo "$0: Unknown command '$1'" 1>&2
132*5f4c09ddSEd Maste	exit 1
133*5f4c09ddSEd Maste	;;
134*5f4c09ddSEd Masteesac
135