Skip to content

Instantly share code, notes, and snippets.

@ptomulik
Last active December 16, 2022 11:44
Show Gist options
  • Save ptomulik/e2e742e3b73e0a8e1b07 to your computer and use it in GitHub Desktop.
Save ptomulik/e2e742e3b73e0a8e1b07 to your computer and use it in GitHub Desktop.
Rotation script for freeradius accounting detail files. Shall be run as a cron script.
#! /bin/sh
########################################################################################
# Compresses old radacct detail files and removes very old compressed radacct files.
########################################################################################
# Author: P. Tomulik
########################################################################################
# Path to the programs used (for environments without $PATH set)
FIND=/usr/bin/find
RM=/bin/rm
GZIP=/bin/gzip
# The directory where radacct detail files are created by freeradius.
RADACCTDIR="/var/log/freeradius/radacct"
# The following regular expression matches only the detail-* files created by radius.
# In particular, it doesn't match files with an extension (compressed files, or other products).
COMPRESSREG="^${RADACCTDIR}/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/detail-[0-9]+\$"
# Required age of the file in DAYS. Example: RADACCTAGE=29 -> only files modified 30 days ago or
# older are compressed by the script. Others are ignored.
COMPRESSAGE=29
for FILE in $($FIND "${RADACCTDIR}" -type f -regex "${COMPRESSREG}" -mtime "+${COMPRESSAGE}"); do
echo $GZIP "${FILE}";
done
# The following regular expression matches only the detail-*.gz files created by us.
# In particular, it doesn't match files without an extension.
DELETEREG="^${RADACCTDIR}/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/detail-[0-9]+\.gz\$"
# Required age of the file in DAYS. Example: DELETEAGE=59 -> only files created 60 days ago or
# older are processed by the script. Others are ignored.
DELETEAGE=59
# NOTE: Once it's tested we can simply do:
# $FIND "${RADACCTDIR}" -type f -regex "${DELETEREG}" -mtime "+${DELETEAGE}" -delete
# instead of the whole for loop below
for FILE in $($FIND "${RADACCTDIR}" -type f -regex "${DELETEREG}" -mtime "+${DELETEAGE}"); do
echo $RM -f "${FILE}";
done
#! /bin/sh
###############################################################################
# Compresses old radacct detail files and removes very old compressed radacct
# files. Instead of using mtime we use the creation date encoded in file name
# by radius daemon. Old files are not used by daemon, so we should be safe
# to manipulate them without harm.
###############################################################################
# Author: P. Tomulik
###############################################################################
###############################################################################
# is_detail_file_older(): tests whether a file age determined from its name is
# greater than the specified age. Example of an acceptable file name:
# detail-20150113
# This file is assumed to be created on 2015-01-13. The file name may contain
# optional non-numeric suffix (extension, e.g. detail-20150113.gz).
###############################################################################
# Usage example:
# if is_detail_file_older $FILE $DAYS 2> /dev/null; then
# # older;
# fi
#
# Arguments:
#
# $FILE: file name
# $DAYS: minimum age in days for which the function returns true
###############################################################################
is_detail_file_older() {
FILE=$1 # file name with encoded
DAYS=$2 # required age in days
TODAYDAT=$(date '+%Y%m%d'); # todays date
TODAYSEC=$(date --date="$TODAYDAT" "+%s"); # number of seconds since epoch
FILEDAT=$(basename ${FILE} | sed -e 's:^detail-\([0-9]\+\)[^0-9]*$:\1:');
FILESEC=$(date --date="$FILEDAT" "+%s")
SECDIFF=$(($TODAYSEC-$FILESEC));
SECSREQ=$(($DAYS*86400));
test $SECDIFF -gt $SECSREQ
}
# The directory where radacct detail files are created by freeradius.
RADACCTDIR="/var/log/freeradius/radacct"
# The following regular expression matches only the detail-* files created by
# radius. In particular, it doesn't match files with an extension (compressed
# files, or other products).
COMPRESSREG="${RADACCTDIR}/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/detail-[0-9]+"
# Required age of the file in DAYS. Example: COMPRESSAGE=30 -> only files that
# have 31 days or more are compressed by the script. Others are skipped.
COMPRESSAGE=30
for FILE in $(find "${RADACCTDIR}" -type f -regex "^${COMPRESSREG}\$"); do
# Date encoded in a file name
if is_detail_file_older ${FILE} ${COMPRESSAGE} 2> /dev/null; then
echo gzip ${FILE};
fi
done
# The following regular expression matches only the detail-*.gz files within
# radacct tree.
DELETEREG="${COMPRESSREG}\.gz"
# Required age of the file in DAYS. Example: DELETEAGE=120 -> only files that
# have 121 days or more are removed by the script. Others are skipped.
DELETEAGE=120
for FILE in $(find "${RADACCTDIR}" -type f -regex "^$DELETEREG\$"); do
if is_detail_file_older ${FILE} ${DELETEAGE} 2> /dev/null; then
echo rm -f ${FILE};
fi
done
@ptomulik
Copy link
Author

The script only prints the invasive commands instead of executing them. To make it work, replace the lines

echo gzip "${FILE}"

and

echo rm "${FILE}"

with

gzip "${FILE}"

and

rm "${FILE}"

respectivelly.

@adzhurinskij
Copy link

Thanks!

But you can add an improvement for auth-detail and reply-detail log files:

FILEDAT=$(basename ${FILE} | sed -e 's:^\(auth\-detail\|detail\|reply\-detail\)-\([0-9]\+\)[^0-9]*$:\2:');
COMPRESSREG="${RADACCTDIR}/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/\(detail\|auth-detail\|reply-detail\)\-[0-9]+"

@saied45
Copy link

saied45 commented Jun 14, 2021

I am new to linux and freeradius in general. Where should I drop this file to get rid of the logs that are generated?

@ptomulik
Copy link
Author

I am new to linux and freeradius in general. Where should I drop this file to get rid of the logs that are generated?

/etc/logrotate.d is present in many Linux distributions (Debian, Ubuntu have it). Just put the file there and it should work. You may test it with logrotate --force /etc/logrotate.d/your-file.

@saied45
Copy link

saied45 commented Jun 14, 2021

Thank you for your help. I think I needed to make the file an executable and will monitor to see if it is working correctly.
Thanks again

@saied45
Copy link

saied45 commented Jun 14, 2021

one more question. I noticed that your script says the location for the log files are /var/log/radacct. However the log files for my stuff is in one more directory in radacct. So for example it would be /var/log/radacct/1.1.1.1 . I assume I need to modify the script to include the directory inside the radacct directory?

@ptomulik
Copy link
Author

one more question. I noticed that your script says the location for the log files are /var/log/radacct. However the log files for my stuff is in one more directory in radacct. So for example it would be /var/log/radacct/1.1.1.1 . I assume I need to modify the script to include the directory inside the radacct directory?

Can't tell for sure now, but it looks like these scripts should actually work for the N.N.N.N subdirectories. Just take a look at how COMPRESSREG is defined and used later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment