-
Notifications
You must be signed in to change notification settings - Fork 0
/
netflow
executable file
·193 lines (170 loc) · 6.25 KB
/
netflow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/sh
# Copyright (C) 2016 Deciso B.V.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# PROVIDE: ngnetflow
# REQUIRE: NETWORKING
# KEYWORD: nojail
# load standard rc
. /etc/rc.subr
# load netflow config
if [ -f /usr/local/etc/netflow.conf ]; then
. /usr/local/etc/netflow.conf
fi
name=netflow
rcvar=netflow_enable
start_cmd="${name}_start"
stop_cmd="${name}_stop"
status_cmd="${name}_status"
extra_commands="status"
[ -z "$netflow_enable" ] && netflow_enable="NO"
[ -z "$netflow_egress_only" ] && netflow_egress_only=""
# netflow_node_error (interface, message)
# - shutdown the netflow node on error to avoid connection problems
# with unassigned hooks
netflow_node_error()
{
interface=$1
message=$2
echo "error $interface: $message"
/usr/sbin/ngctl shutdown netflow_$interface: >/dev/null 2>&1
}
# netflow_setup_interface (interface)
# - use netgraph + ng_netflow in combination with samplicate to record netflow
# data and send it to multiple locations
netflow_setup_interface()
{
# set netflow version (export keyword)
if [ "$netflow_version" == "9" ]; then
nfversion="9"
else
nfversion=""
fi
interface=$1
# determine (snmp) ifIndex
ifIndex=0
found=0
for item in $(/sbin/ifconfig -l); do
let ifIndex = ifIndex + 1 > /dev/null 2>&1
if [ "$item" = "$interface" ]; then
found=1
break
fi
done
if [ "$found" == "0" ]; then
echo "error : interface $interface not found"
return
fi
# disable ingress (traffic to this host) for selected interfaces
# avoids counting traffic going through this firewall double when using nat
if [ -n "$(echo " $netflow_egress_only " | grep " $interface ")" ]; then
conf="10"
echo "setup $interface [egress only]"
else
conf="11"
echo "setup $interface"
fi;
# remove earlier setup (if any)
/usr/sbin/ngctl shutdown netflow_$interface: >/dev/null 2>&1
# configure netflow for this interface
# ng_ether:lower <-> ng_netflow:ifaceX <-> ng_netflow:export <-> ng_netflow:outX <-> ng_ether:upper
# create ng_netflow node and connect ifaceX hook with ng_ether lower hook
if ! /usr/sbin/ngctl mkpeer $interface: netflow lower iface$ifIndex; then
netflow_node_error $interface "cannot create netflow node for $interface"
return
fi
# set a name for the netflow node
if ! /usr/sbin/ngctl name $interface:lower netflow_$interface; then
netflow_node_error $interface "cannot set name for $interface:lower"
return
fi
# connect ng_netflow outX hook with ng_ether upper hook to reinject the packets
if ! /usr/sbin/ngctl connect $interface: netflow_$interface: upper out$ifIndex; then
netflow_node_error $interface "cannot connect $interface:upper with out$ifIndex"
return
fi
# set timeouts
if ! /usr/sbin/ngctl msg netflow_$interface: settimeouts { inactive=$netflow_inactive_timeout active=$netflow_active_timeout }; then
netflow_node_error $interface "cannot set timouts"
return
fi
# configure ingress
if ! /usr/sbin/ngctl msg netflow_$interface: setconfig {iface=$ifIndex conf=$conf}; then
netflow_node_error $interface "cannot configure ingress"
return
fi
# create a ng_ksocket node to export the NetFlow datagrams from ng_netflow
if ! /usr/sbin/ngctl mkpeer netflow_$interface: ksocket export$nfversion inet/dgram/udp; then
netflow_node_error $interface "cannot create ksocket node for netflow_$interface"
return
fi
# set a name for the ksocket node
if ! /usr/sbin/ngctl name netflow_$interface:export$nfversion ksocket_netflow_$interface; then
netflow_node_error $interface "cannot set name for netflow_$interface:export$nfversion"
return
fi
# connect the ng_ksocket with the NetFlow destination
if ! /usr/sbin/ngctl msg netflow_$interface:export$nfversion connect inet/$netflow_destinations; then
netflow_node_error $interface "cannot connect socket_netflow_$interface with inet/$netflow_destinations"
return
fi
}
netflow_start()
{
is_running=$(ngctl list | grep netflow_ | wc -l)
if [ $is_running -ne 0 ]; then
echo "already running"
return
fi
if ! kldstat -qm ng_ether; then
kldload ng_ether
fi
# configure interfaces
for interface in $netflow_interfaces; do
netflow_setup_interface "$interface"
done
}
# stop netflow collect and distribution
netflow_stop()
{
# kill all samplicate process
if [ -f /var/run/netflow_samplicate.pid ]; then
kill -9 $(cat /var/run/netflow_samplicate.pid)
fi
# cleanup netflow processes
for netflow_node in $(/usr/sbin/ngctl list | grep "Type: netflow" | awk '{print $2;}'); do
/usr/sbin/ngctl shutdown $netflow_node:
done
}
# netflow status
netflow_status()
{
flows=$(/usr/sbin/ngctl list | grep netflow_ | wc -l | /usr/bin/awk '{print $1}')
if [ $flows -eq 0 ]; then
echo "netflow is not active"
else
echo "netflow is active (flows : $flows)"
fi
}
load_rc_config $name
run_rc_command $1