-
Notifications
You must be signed in to change notification settings - Fork 10
/
tcpdump247
executable file
·214 lines (192 loc) · 5.87 KB
/
tcpdump247
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/bash
# tcpdump247 (part of ossobv/vcutil) // wdoekes/2013-2016,2023 // Public Domain
#
# Script to start a rotating tcpdump. Restarts tcpdump if it dies.
#
# This is used on servers where you need to keep a batch of old traffic
# to diagnose recent events. The restart functionality is there because
# interfaces (e.g. ipsec) that go down, will kill a running tcpdump.
#
# Usage:
#
# # Install:
# cp -a tcpdump247 /etc/init.d/tcpdump247
# cp tcpdump247.default /etc/default/tcpdump247
#
# # Start:
# /etc/init.d/tcpdump247 start
#
# # Configuration is done in /etc/default/tcpdump247 like this:
# ENABLED=1
# SPOOL=/var/spool/tcpdump; mkdir -p $SPOOL
# COMMON_ARGS="-i eth0 -pnns0 -W 100 -C20"
# ARGS_LIST=(
# "$COMMON_ARGS -w $SPOOL/1.2.3.4.pcap. 'host 1.2.3.4'"
# "$COMMON_ARGS -w $SPOOL/25or80.pcap. 'port 25 or port 80'"
# )
#
# Author: Walter Doekes, 2013,2015.
# Notes: using bash instead of sh to get 'exec -a' functionality, and
# for array-of-strings syntax.
#
### BEGIN INIT INFO
# Provides: tcpdump247
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: tcpdump247
# Description: Rotating traffic dumps wrapper using tcpdump
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=tcpdump247
DESC="rotating traffic dumps wrapper"
TCPDUMP=$(command -v tcpdump)
PIDFILE=/var/run/tcpdump247.pgid # it's a pgid-file actually
. /lib/lsb/init-functions
# load local settings
test -r /etc/default/tcpdump247 && . /etc/default/tcpdump247
# sanity checks
test "$ENABLED" != "1" && exit 0 # not enabled? (or exit 6?)
if ! test -x "$TCPDUMP"; then
echo "tcpdump247: tcpdump bin not found or not executable" >&2
exit 5
fi
start_scripts() {
for ARGS in "${ARGS_LIST[@]}"; do
if ! start_script; then
# Drat. Must now kill everyone from pgid except ourself.
# Cannot call stop_scripts, because it would kill this
# invocation too.
pgid=`cat "$PIDFILE" 2>/dev/null`
if test -n "$pgid"; then
for pid in `pgrep -g $pgid`; do
if test $pid -ne $$ && test $pid -ne $PPID; then
kill -15 $pid
fi
done
rm "$PIDFILE"
fi
return 1
fi
done
}
start_script() {
# The combination of backticks and parentheses is is a double fork.
# Now it gets detached properly, and can kill it further down if
# needed, without messing up the console.
# The exec /bin/sh is used to rename argv[0] for clarity.
# The sleep 15 limits the restart speed.
echo " [x] $TCPDUMP $ARGS"
pid=`(exec -a TCPDUMP247 /bin/bash -c \
"while :; do \"$TCPDUMP\" $ARGS >/dev/null 2>&1
sleep 15; done"
) >/dev/null 2>&1 & echo $!`
# Sleep a second and check that we're really up. This helps catching
# typos in the ARGS.
sleep 1
if ! pgrep -P $pid -f "$TCPDUMP" >/dev/null; then
# Kill parent. The sleep will die by itself.
# (We do not run stop_script here, because it will kill this
# invocation too.)
kill -15 $pid 2>/dev/null
# List possible reasons for failure:
cat >&2 << EOF
Daemon tcpdump did not start, possibly due to:
- binary not found ($TCPDUMP)
- not enough permissions (are you root? does tcpdump switch to a tcpdump-user?)
- bad args ($ARGS)
- write permissions (does the -w directory exist?)
- apparmor permissions (/**.[pP][cC][aA][pP].[0-9][0-9] rw,)
- apparmor in lxc permissions for stdout/stderr (/dev/pts/* rw,)
EOF
return 1
fi
#PIDFILE="$RUNDIR/${pid}.pid"
pgid=`to_pgid $pid`
echo $pgid >"$PIDFILE"
}
stop_scripts() {
pgid=`get_pgid`
if test $? = 0; then
kill -15 -$pgid
res=$?
rm -f "$PIDFILE"
return $res
fi
return 1
}
to_pgid() {
ps -p "$1" -o pgid | sed -e '1d;s/[^0-9]//g'
}
get_pgid() {
# Check pid file.
pgid=`cat "$PIDFILE" 2>/dev/null`
if test -n "$pgid"; then
if pgrep -g "$pgid" -f TCPDUMP247 >/dev/null 2>&1; then
echo $pgid
return 0
fi
echo " (removing stale pidfile)" >&2
rm "$PIDFILE"
fi
# Fall back to pidof/pgrep.
pids=`pidof TCPDUMP247 2>/dev/null | sed -e 's/ /,/g'`
if test -n "$pids"; then
pgids=`ps -p "$pids" -o pgid | sed -e1d | sort -u`
if test -n "$pgids"; then
pgid1=
for pgid in $pgids; do
if test -z "$pgid1"; then
pgid1=$pgid
echo "(attempting to create pidfile)" >&2
echo $pgid1
echo $pgid1 > "$PIDFILE"
else
echo "(attempting to kill other TCPDUMP247 $pgid)" >&2
kill -15 -$pgid
fi
done
return 0
fi
fi
# Not running.
return 3
}
case "$1" in
start)
log_begin_msg "Starting $DESC:" "$NAME"
if ! get_pgid >/dev/null; then
start_scripts
fi
log_end_msg $?
;;
stop)
log_begin_msg "Stopping $DESC:" "$NAME"
stop_scripts
log_end_msg $?
;;
status)
pgid=`get_pgid`
status="$?"
if test $status -eq 0; then
log_success_msg "$NAME is running"
exit 0
else
log_failure_msg "$NAME is not running";
exit $status
fi
;;
force-restart|reload|restart)
log_begin_msg "Restarting $DESC:" "$NAME"
stop_scripts
sleep 1
start_scripts
log_end_msg $?
;;
*)
echo "Usage: $0 {start|stop|status|restart|force-reload|reload}" >&2
exit 1
;;
esac
# vim: set ts=8 sw=4 sts=4 et ai tw=79: