Application: "Freeradius v3", "Nginx", "Bash".
Задача: визуализировать статистику о количестве пользователей сегмента "Eduroam", без выдачи сведений о персоналиях.
Мы некоторое время размышляли, что хотелось бы видеть в статистическом срезе и пришли к тому, что свода перечня "realm"-ов и количества их пользователей, успешно аутентифицировавшихся за некоторые периоды времени, вполне достаточно. Этого легко добиться регулярным сканированием журналов событий аутентификации "Freeradius" и генерированием простейшей HTML-страницы с таблицей.
Результат выглядит примерно так (на этапе запуска сервиса, когда пользователей совсем не много):
Пример статистического среза количества пользователей сегмента "Eduroam".
Исходим от того, что конфигурация сервера аутентификации "Freeradius" соответствует приведённой в располагающейся рядом инструкции. Журналы событий формируются модулем "linelog", со строго определённым набором параметров.
Установка и настройка web-сервера.
Для отображения HTML-страницы со статистикой воспользуемся легковесным "Nginx":
# aptitude install nginx-light
Небольшая преднастройка сервиса:
# vi /etc/nginx/nginx.conf
user www-data www-data;
worker_processes auto;
....
http {
....
# Велим Nginx не выдавать сведения о номере своей версии
server_tokens off;
....
worker_processes auto;
....
http {
....
# Велим Nginx не выдавать сведения о номере своей версии
server_tokens off;
....
Настройки сайта самые простые, достаточные для отображения единственной статической HTML-страницы:
# vi /etc/nginx/sites-available/eduroam.example.net.conf
server {
listen 80 default_server;
server_name eduroam.example.net;
access_log /var/log/nginx/eduroam.example.net.access.log;
error_log /var/log/nginx/eduroam.example.net.error.log;
# Явно указываем корень файловой структуры сайта
root /var/www/eduroam.example.net/www;
# Задаём перечень файлов, которые web-сервер должен выдать в отсутствии явного указания со стороны клиента
index index.html;
# Обслуживаем только внутрисетевых клиентов
satisfy all;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
}
listen 80 default_server;
server_name eduroam.example.net;
access_log /var/log/nginx/eduroam.example.net.access.log;
error_log /var/log/nginx/eduroam.example.net.error.log;
# Явно указываем корень файловой структуры сайта
root /var/www/eduroam.example.net/www;
# Задаём перечень файлов, которые web-сервер должен выдать в отсутствии явного указания со стороны клиента
index index.html;
# Обслуживаем только внутрисетевых клиентов
satisfy all;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
}
Удаляем "сайт по умолчанию", применяем нашу конфигурацию, проверяем её корректность и перезапускаем web-сервер:
# rm /etc/nginx/sites-enabled/default
# ln -s /etc/nginx/sites-available/eduroam.example.net.conf /etc/nginx/sites-enabled/eduroam.example.net.conf
# nginx -t && /etc/init.d/nginx restart
# ln -s /etc/nginx/sites-available/eduroam.example.net.conf /etc/nginx/sites-enabled/eduroam.example.net.conf
# nginx -t && /etc/init.d/nginx restart
Пишем скрипт анализа данных и визуализации статистики.
Задача простая, потому и решение "в лоб" - читаем журнал событий аутентификации, выбираем оттуда интересующие нас данные, группируем их и выводим результаты текстом в HTML-страницу.
Заготовим месторасположение для скрипта и результирующей web-страницы:
# mkdir -p /var/www/cgi-bin/linelog
# mkdir -p /var/www/eduroam.example.net/www
# mkdir -p /var/www/eduroam.example.net/www
Скрипт получился незамысловатый и даже в комментариях не нуждается, на мой вгляд - говорящих имён переменных вполне достаточно:
# vi /var/www/cgi-bin/linelog/view-make.sh && chmod ug+x /var/www/cgi-bin/linelog/view-make.sh
#!/bin/bash
unset BODY 2>/dev/null
BODY=${BODY}"<!DOCTYPE HTML>\n\
<html>\n\
<head>\n\
<meta charset=\"utf-8\">\n\
<font face=\"sans-serif\">\n\
<meta http-equiv=\"refresh\" content=\"600\">\n\
<title>Eduroam Gateway Usage Statistics (Example)</title>\n\
<style>\n\
a {text-decoration: none;}\n\
a:visited {color: blue;}\n\
table {text-align: left; border-collapse: collapse; margin: 0pt; padding: 0pt;}\n\
tr {border: none; margin: 0pt; padding: 0pt;}\n\
th {background-color: #F5F5F5; border: #C0C0C0 1px solid; text-align: center; font-size: 90%; margin: 0pt; padding-left: 4pt; padding-top: 2pt; padding-right: 4pt; padding-bottom: 2pt;}\n\
td {border: #C0C0C0 1px solid; text-align: left; vertical-align: top; margin: 0pt; padding-left: 4pt; padding-top: 2pt; padding-right: 4pt; padding-bottom: 2pt;}\n\
</style>\n\
</head>\n\
<body>\n\
<h2 style=\"color: #333333;\">Eduroam Gateway Usage Statistics (Example)</h2>\n\
<a href=\"https://eduroam.example.net\" style=\"font-size: 120%;\">eduroam.example.net</a> <span style=\"color: #808080;\">(this server)</span>
\n"
BODY=${BODY}"<table>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td style=\"border: none; padding-right: 15pt;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Today:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_TODAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +%Y-%m-%d)" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_TODAY=( $(echo "${ACCEPTED_TODAY}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_TODAY_ITEM in ${REALMS_TODAY[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_TODAY_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_TODAY}" | grep -c -i "@${REALMS_TODAY_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_TODAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_TODAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_TODAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
REJECTED_TODAY=( $(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep 'Send-Reject' {} \; | grep -e "^$(date +%Y-%m-%d)" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case) )
for I in ${!REJECTED_TODAY[@]} ; do
if echo "${ACCEPTED_TODAY}" | grep -qFx "${REJECTED_TODAY[$I]}" ; then
unset REJECTED_TODAY[$I]
fi
done
BODY=${BODY}"<tr><td>* (rejected)</td><td style=\"text-align: right; background-color: #ffcccc;\">$(echo "${REJECTED_TODAY[@]}" | wc -w)</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"<td style=\"border: none; padding-right: 15pt;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Last three days:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_THREEDAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_THREEDAY=( $(echo "${ACCEPTED_THREEDAY}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_THREEDAY_ITEM in ${REALMS_THREEDAY[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_THREEDAY_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_THREEDAY}" | grep -c -i "@${REALMS_THREEDAY_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_THREEDAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_THREEDAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_THREEDAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"<td style=\"border: none;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Last week:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_LASTWEEK=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-6 days')\|$(date +'%Y-%m-%d' --date '-5 days')\|$(date +'%Y-%m-%d' --date '-4 days')\|$(date +'%Y-%m-%d' --date '-3 days')\|$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_LASTWEEK=( $(echo "${ACCEPTED_LASTWEEK}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_LASTWEEK_ITEM in ${REALMS_LASTWEEK[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_LASTWEEK_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_LASTWEEK}" | grep -c -i "@${REALMS_LASTWEEK_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_LASTWEEK}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_LASTWEEK=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-6 days')\|$(date +'%Y-%m-%d' --date '-5 days')\|$(date +'%Y-%m-%d' --date '-4 days')\|$(date +'%Y-%m-%d' --date '-3 days')\|$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_LASTWEEK}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
BODY=${BODY}"</table>\n"
BODY=${BODY}"<br /><span style=\"font-size: 90%; color: #808080;\">Collection time: "$(date +'%Y-%m-%d %H:%M')" (updated hourly)</span>\n"
BODY=${BODY}"\n</body>\n</html>"
echo -e "${BODY}" 2>/dev/null > /var/www/eduroam.example.net/www/index.html
chown www-data:www-data /var/www/eduroam.example.net/www/index.html
exit ${?}
unset BODY 2>/dev/null
BODY=${BODY}"<!DOCTYPE HTML>\n\
<html>\n\
<head>\n\
<meta charset=\"utf-8\">\n\
<font face=\"sans-serif\">\n\
<meta http-equiv=\"refresh\" content=\"600\">\n\
<title>Eduroam Gateway Usage Statistics (Example)</title>\n\
<style>\n\
a {text-decoration: none;}\n\
a:visited {color: blue;}\n\
table {text-align: left; border-collapse: collapse; margin: 0pt; padding: 0pt;}\n\
tr {border: none; margin: 0pt; padding: 0pt;}\n\
th {background-color: #F5F5F5; border: #C0C0C0 1px solid; text-align: center; font-size: 90%; margin: 0pt; padding-left: 4pt; padding-top: 2pt; padding-right: 4pt; padding-bottom: 2pt;}\n\
td {border: #C0C0C0 1px solid; text-align: left; vertical-align: top; margin: 0pt; padding-left: 4pt; padding-top: 2pt; padding-right: 4pt; padding-bottom: 2pt;}\n\
</style>\n\
</head>\n\
<body>\n\
<h2 style=\"color: #333333;\">Eduroam Gateway Usage Statistics (Example)</h2>\n\
<a href=\"https://eduroam.example.net\" style=\"font-size: 120%;\">eduroam.example.net</a> <span style=\"color: #808080;\">(this server)</span>
\n"
BODY=${BODY}"<table>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td style=\"border: none; padding-right: 15pt;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Today:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_TODAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +%Y-%m-%d)" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_TODAY=( $(echo "${ACCEPTED_TODAY}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_TODAY_ITEM in ${REALMS_TODAY[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_TODAY_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_TODAY}" | grep -c -i "@${REALMS_TODAY_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_TODAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_TODAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_TODAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
REJECTED_TODAY=( $(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep 'Send-Reject' {} \; | grep -e "^$(date +%Y-%m-%d)" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case) )
for I in ${!REJECTED_TODAY[@]} ; do
if echo "${ACCEPTED_TODAY}" | grep -qFx "${REJECTED_TODAY[$I]}" ; then
unset REJECTED_TODAY[$I]
fi
done
BODY=${BODY}"<tr><td>* (rejected)</td><td style=\"text-align: right; background-color: #ffcccc;\">$(echo "${REJECTED_TODAY[@]}" | wc -w)</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"<td style=\"border: none; padding-right: 15pt;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Last three days:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_THREEDAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_THREEDAY=( $(echo "${ACCEPTED_THREEDAY}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_THREEDAY_ITEM in ${REALMS_THREEDAY[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_THREEDAY_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_THREEDAY}" | grep -c -i "@${REALMS_THREEDAY_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_THREEDAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_THREEDAY=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_THREEDAY}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"<td style=\"border: none;\">\n"
BODY=${BODY}"<h3 style=\"color: #333333;\">Last week:</h3>\n"
BODY=${BODY}"<table style='font-size: 12pt'>\n"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<th>Realm</th><th>Amount</th>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_LASTWEEK=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-6 days')\|$(date +'%Y-%m-%d' --date '-5 days')\|$(date +'%Y-%m-%d' --date '-4 days')\|$(date +'%Y-%m-%d' --date '-3 days')\|$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
REALMS_LASTWEEK=( $(echo "${ACCEPTED_LASTWEEK}" | awk -F '@' '{print $2}' | sort | uniq --ignore-case) )
for REALMS_LASTWEEK_ITEM in ${REALMS_LASTWEEK[@]} ; do
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td>$(echo "${REALMS_LASTWEEK_ITEM}" | tr '[:upper:]' '[:lower:]')</td>"
BODY=${BODY}"<td style=\"text-align: right;\">$(echo "${ACCEPTED_LASTWEEK}" | grep -c -i "@${REALMS_LASTWEEK_ITEM}")</td>"
BODY=${BODY}"</tr>\n"
done
BODY=${BODY}"<tr><td style=\"border: none;\"></td><td style=\"text-align: right;\">$(echo "${ACCEPTED_LASTWEEK}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"<tr>\n"
BODY=${BODY}"<td colspan=\"3\" style=\"border: none;\">\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
ACCEPTED_EXT_LASTWEEK=$(find /var/log/freeradius/linelog -type f -name 'linelog*.log' -exec grep -v -E 'Operator-Name = .?example.net' {} \; | grep 'Send-Accept' | grep -e "^$(date +'%Y-%m-%d' --date '-6 days')\|$(date +'%Y-%m-%d' --date '-5 days')\|$(date +'%Y-%m-%d' --date '-4 days')\|$(date +'%Y-%m-%d' --date '-3 days')\|$(date +'%Y-%m-%d' --date '-2 days')\|$(date +'%Y-%m-%d' --date '-1 days')\|$(date +'%Y-%m-%d')" | awk -F ', ' '{print $2}' | awk 'match($0, /User-Name = .+/) {print substr($0, RSTART, RLENGTH);}' | awk -F '=' '{print $2}' | tr -d '[:blank:]' | sort | uniq --ignore-case)
BODY=${BODY}"<tr><td>example.net (outside)</td><td style=\"text-align: right;\">$(echo "${ACCEPTED_EXT_LASTWEEK}" | grep -c -i "@")</td></tr>"
BODY=${BODY}"</table>\n"
BODY=${BODY}"</td>\n"
BODY=${BODY}"</tr>\n"
BODY=${BODY}"</table>\n"
BODY=${BODY}"<br /><span style=\"font-size: 90%; color: #808080;\">Collection time: "$(date +'%Y-%m-%d %H:%M')" (updated hourly)</span>\n"
BODY=${BODY}"\n</body>\n</html>"
echo -e "${BODY}" 2>/dev/null > /var/www/eduroam.example.net/www/index.html
chown www-data:www-data /var/www/eduroam.example.net/www/index.html
exit ${?}
Хоть мы и не затрагиваем здесь приватных данных, но для порядка закрываем доступ к скриптам и файлам web-сайта посторонним:
# chown -R www-data:www-data /var/www/eduroam.example.net/www /var/www/cgi-bin/linelog
# chmod -R o-rwx /var/www/eduroam.example.net/www /var/www/cgi-bin/linelog
# chmod -R o-rwx /var/www/eduroam.example.net/www /var/www/cgi-bin/linelog
Я наладил запуск скрипта ежечасно:
# vi /etc/crontab
....
# Regularly start collecting statistics on the Eduroam Gateway
0 */1 * * * root /var/www/cgi-bin/linelog/view-make.sh &
# Regularly start collecting statistics on the Eduroam Gateway
0 */1 * * * root /var/www/cgi-bin/linelog/view-make.sh &