1#!/bin/sh
2# 20130331 sampo@synergetics.be
3
4FIND=find
5RM="rm -rf"
6PGP=gpg
7#zalgo=--compress-algo bzip2     # seems bzip2 does not help much for audit data
8ses_atime=1
9trail_atime=30
10backupdir=~/zxbackup
11now=`date -u '+%Y%m%d-%H%M%S'`
12
13warning="WARNING: Running this script (zxlogclean.sh) in production environment
14         may destroy valuable audit trail data, which you may be legally obliged
15         to retain. Be sure any such data has already been copied to a safe place."
16
17help="This is a ZXID log cleanup script, typically run from cron(8)
18Copyright (c) 2013 Synergetics NV. All Rights Reserved.
19Author: Sampo Kellomaki (sampo@synergetics.be)
20
21$warning
22
23The default behaviour is to
24   - backup most files not touched in $trail_atime days to directory $backupdir
25   - remove any sessions older than 1 day by access time stamp (find ses -atime +$ses_atime)
26   - remove any debugging files, such as xml.dbg
27
28zxlogclean.sh  - Runs default behaviour assuming CWD to be the instance dir
29zxlogclean.sh [OPTIONS] path1 path2  - Runs in specified instance directories
30
31Options:
32  -d   Debug mode
33  -n   Dryrun: do not actually delete or backup files, just print what would be done
34  -r   Really remove: delete files that by default would have been backed up
35  -b   Always backup: backup all files, even those that would usually be removed
36  -pgp PUBKEY   - When backing up, encrypt the backups using $PGP and public key
37       from the public keyring.
38  -sig PRIVKEY  - When backing up, sign the backups using $PGP and private key
39       from the secret keyring.
40  -sym SYMKEYFILE  - When backing up, encrypt the backups using $PGP and symmetric
41       key from the specified file. Warn: The key is protected by file permissions.
42  -symfd SYMKEYFD  - When backing up, encrypt the backups using $PGP and symmetric
43       key from the specified file descriptor.
44  -symstr SYMSTR   - When backing up, encrypt the backups using specified symmetric key.
45       WARNING: The supplied key will be visible from the command line history and ps.
46                For the best security, you should use the -pgp PUBKEY option.
47  -pubring FILE - Specifies public keyring file for -pgp. Default ~/.gnupg/pubring.gpg
48  -secring FILE - Specifies secret keyring file for -sig. Default ~/.gnupg/secring.gpg
49  -bdir D  Backups are to be made to directory D (default $backupdir)
50  -trail N Trail backup -atime value (in days) (default $trail_atime)
51  -ses N   Session deletion -atime value (in days) (default $ses_atime)
52  -nw  Shut down the warning about audit trail destruction
53  -nd  No delete. Even when running for real and making backups, etc., do not delete
54  -h   This help
55  --   End of options
56
57For -pgp and -sig options to work, you must have created keyrings, see $PGP --gen-key
58
59To decrypt (and verify signature, if any):
60gpg --secret-keyring log-decrypt-secret.gpg <~/zxbackup/trail-20130405-194808.tar.pgp | tar xvf -
61
62BUGS: The -pgp options may be still buggy (20130404 --Sampo)
63"
64
65warn() { echo "$1" 1>&2; }
66die()  { echo "$1" 1>&2; exit 1; }
67
68while [ 1 ]; do
69#warn "HERE($1)"
70case "$1" in
71-d)  debug=1;  shift; continue;;
72-n)  dryrun=1; shift; continue;;
73-r)  remove=1; shift; continue;;
74-b)  backup=1; shift; continue;;
75-f)  force=1;  shift; warn "Force not supported, see -r and -b\n$help"; continue;;
76-pgp)    shift;  pubkey=$1;   shift; continue;;
77-sig)    shift;  sig="-u $1 -s";   shift; continue;;
78-sym)    shift;  symkeyf=$1;  shift; symenc=1; passphrase="--passphrase-file $symkeyf"; continue;;
79-symfd)  shift;  symkeyfd=$1; shift; symenc=1; passphrase="--passphrase-fd $symkeyfd"; continue;;
80-symstr) shift;  symkeys=$1;  shift; symenc=1; passphrase="--passphrase $symkeys"; continue;;
81-pubring) shift; pubring="--no-default-keyring --keyring $1";   shift; continue;;
82-secring) shift; secring="--secret-keyring $1";   shift; continue;;
83-bdir)   shift;  backupdir=$1;   shift; continue;;
84-trail)  shift;  trail_atime=$1; shift; continue;;
85-ses)    shift;  ses_atime=$1;   shift; continue;;
86-nw) warning=""; shift; continue;;
87-nd) nodel=1; shift; continue;;
88-h)  echo "$help"; exit;;
89--)  shift; break;;
90-*)  die "Unknown option: $1\n$help";;
91*)   break;;
92esac
93done
94
95[ "$warning" ] && warn "$warning"
96
97[ -d $backupdir ] || die "Backup directory $backupdir does not exist. Run mkdir $backupdir"
98
99tarup() {
100    if xargs tar czf $1 < $2; then
101	[ $debug ] && warn "tar: Created backup($1)"
102	[ $nodel ] || xargs $RM < $2
103    else
104	warn "ERROR: Failed to create a backup($1). Originals not deleted."
105    fi
106}
107
108pgppub() {
109    #[ ! -r $pubkey ] && die "Public key($pubkey) not found or not readable ($?)"
110    if cat $2 | xargs tar cf - | $PGP $zalgo $pubring $secring $sig -r $pubkey -e --batch > $1 ; then
111	[ $debug ] && warn "pgppub: Created backup($1)"
112	[ $nodel ] || xargs $RM < $2
113    else
114	warn "ERROR: Failed to create a backup($1). Originals not deleted!"
115    fi
116}
117
118pgpsym() {
119    #[ ! -r $symkey ] && die "Symmetric key($pubkey) not found or not readable ($?)"
120    #warn "$PGP $zalgo $pubring $secring $sig --force-mdc $passphrase -c --batch"
121    if xargs tar cf - < $2 | $PGP $zalgo $pubring $secring $sig --force-mdc $passphrase -c --batch > $1 ; then
122	[ $debug ] && warn "pgpsym: Created backup($1)"
123	[ $nodel ] || xargs $RM < $2
124    else
125	warn "ERROR: Failed to create a backup($1). Originals not deleted!"
126    fi
127}
128
129### Per instance directory cleaning
130
131clean_inst() {
132    dir=$1
133
134    #mkdir $dir/log/issue $dir/log/rely     # in case we accidentally delete them
135    #chown si $dir/log/issue $dir/log/rely
136    #chmod g+s $dir/log/issue $dir/log/rely
137
138    [ $debug ] && warn "cleaning $dir"
139
140    # Immediate cleanup items
141
142    echo "$dir/log/xml.dbg" > $backupdir/zxlogclean-todel-$$
143
144    if [ $dryrun ] ; then cat $backupdir/zxlogclean-todel-$$
145    elif [ "$backup" -a "$pubkey" ] ; then
146	pgppub $backupdir/junk-$now.tar.pgp $backupdir/zxlogclean-todel-$$
147    elif [ "$backup" -a "$symenc" ] ; then
148	pgpsym $backupdir/junk-$now-sym.tar.pgp $backupdir/zxlogclean-todel-$$
149    elif [ $backup ] ; then
150	tarup $backupdir/junk-$now.tgz $backupdir/zxlogclean-todel-$$
151    else
152	[ $nodel ] || xargs $RM <$backupdir/zxlogclean-todel-$$
153    fi
154
155    [ $debug ] || $RM $backupdir/zxlogclean-todel-$$
156
157    # Audit trail
158
159    $FIND $dir/log -mindepth 2 \! -name .keep -atime +$trail_atime >$backupdir/zxlogclean-trail-$$
160    echo "$dir/log/err" >> $backupdir/zxlogclean-trail-$$
161    echo "$dir/log/act" >> $backupdir/zxlogclean-trail-$$
162
163    #echo "Reset $now" > $dir/log/err
164    #echo log/err* > $backupdir/zxlogclean-trail-$$
165    #echo log/act* >> $backupdir/zxlogclean-trail-$$
166
167    if [ $dryrun ] ; then cat $backupdir/zxlogclean-trail-$$
168    elif [ $pubkey ] ; then
169	pgppub $backupdir/trail-$now.tar.pgp $backupdir/zxlogclean-trail-$$
170    elif [ $symenc ] ; then
171	pgpsym $backupdir/trail-$now-sym.tar.pgp $backupdir/zxlogclean-trail-$$
172    elif [ "$remove" -a !"$backup" ] ; then
173	[ $nodel ] || xargs $RM <$backupdir/zxlogclean-trail-$$
174    else # backup is the default for most trail items
175	tarup $backupdir/trail-$now.tgz $backupdir/zxlogclean-trail-$$
176    fi
177
178    [ $debug ] || $RM $backupdir/zxlogclean-trail-$$
179
180    # Session
181
182    $FIND $dir/ses -mindepth 1 -depth -atime +$ses_atime -type d >$backupdir/zxlogclean-ses-to-rm-$$
183
184    if [ $dryrun ] ; then cat $backupdir/zxlogclean-ses-to-rm-$$
185    elif [ "$backup" -a "$pubkey" ] ; then
186	pgppub $backupdir/ses-$now.tar.pgp $backupdir/zxlogclean-ses-to-rm-$$
187    elif [ "$backup" -a "$symenc" ] ; then
188	pgpsym $backupdir/ses-$now-sym.tar.pgp $backupdir/zxlogclean-ses-to-rm-$$
189    elif [ $backup ] ; then
190	tarup $backupdir/ses-$now.tgz $backupdir/zxlogclean-ses-to-rm-$$
191    else
192	[ $nodel ] || xargs $RM <$backupdir/zxlogclean-ses-to-rm-$$
193    fi
194
195    [ $debug ] || $RM $backupdir/zxlogclean-ses-to-rm-$$
196
197    # Other cleanup items ***
198}
199
200### Main loop
201
202if [ "x$*" = "x" ] ; then clean_inst `pwd`; exit; fi
203
204for inst in $* ; do
205  if [ ! -d $inst ] ; then warn "Instance($inst) is not a directory. Skipping."; continue; fi
206  if [ ! -d $inst/log ] ; then warn "Inst($inst) is missing log. Skipping."; continue; fi
207  clean_inst $inst
208done
209
210#EOF