Всем привет,
Что делать, если аналоги платные или не адаптированы под наши условия? Конечно, писать самому.
Поскольку мои знания ограничиваются одним языком программирования – bash, реализация будет выполнена именно на нем.
Что нам потребуется:
Как будет работать:
ssh adm@IP -> сбор нужной информации -> запись в лог на сервер -> exit.
Как выглядит на практике:
При запуске программы отображается информация о пользователях и доступных пакетах для обновления. Имеется возможность ручного управления через меню.P.s реальные имена и IP заменены в целях анонимности. Далее показан пример выполнения первого пункта:
Краткая информация о системе, список пакетов доступных для обновления.
Примеры лог файлов, которые создает программа можно скачать тут
Реализация:
/root/uuman – корневая папка программы.
../uuman/log – папка с лог файлами (она же сетевая шара).
../../log/.menu_log – скрытая папка с краткой информацией о удаленной машине.
Как пользоваться:
Если Вы использовали свои пути, поправьте следующие переменные в uuman.sh:
Скрипт setup установит необходимые пакеты для работы программы на клиентских станциях. Чтобы использовать скрипт, в файле uuman.sh закомментируйте строку:
Автоматический режим:
Мы получаем клиент-серверную систему позволяющую в автоматическом или ручном режиме получать, хранить и обрабатывать информацию об актуальности установленных программ, пакетов безопасности и при необходимости производить обновление на клиентских станциях под управлением Ubuntu Linux.
UPD:
Авторизация теперь по ssh-key.
Генерируем ключ
С помощью файла setup, размещаем его на клиентских станциях.
Что делать, если аналоги платные или не адаптированы под наши условия? Конечно, писать самому.
Условие:
- ~ 50 удаленных клиентских станций, работающих на Ubuntu Desktop (10.04-12.10).
Задача:
- Получение информации о доступности обновления пакетов, на удаленных клиентских станциях.
- Логирование версий пакетов доступных для обновления.
- Удаленное обновление одной/всех клиентских станций.
Варианты решения:
- Landscape – Отлично, но платно.
- Spacewalk – Только RHEL и ему подобные.
- Собственная разработка – этот вариант как раз для нас.
Поскольку мои знания ограничиваются одним языком программирования – bash, реализация будет выполнена именно на нем.
Что нам потребуется:
- ssh-server на клиентских станциях.
- Общий пользователь для администрирования.
- Linux сервер (программа expect должна быть установлена).
- Сетевая шара (я использовал nfs).
Как будет работать:
ssh adm@IP -> сбор нужной информации -> запись в лог на сервер -> exit.
Как выглядит на практике:
При запуске программы отображается информация о пользователях и доступных пакетах для обновления. Имеется возможность ручного управления через меню.
Краткая информация о системе, список пакетов доступных для обновления.
Примеры лог файлов, которые создает программа можно скачать тут
Реализация:
/root/uuman – корневая папка программы.
../uuman/log – папка с лог файлами (она же сетевая шара).
../../log/.menu_log – скрытая папка с краткой информацией о удаленной машине.
setup – файл первоначальной настройки удаленных машин.
#!/usr/bin/expect -f
set IP $argv
#Ождиаем каждую команду
set timeout -1
#Отправляем ключ на удаленную станцию
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub adm@$IP
expect -re "(yes/no)"
#Отправляем YES
send "yes\r"
#Ждем строки ввода пароля
expect -re "Password:"
#Вводим пароль
send "YOU_PASSWORD\r"
#Подтверждение добовления ключа
expect -re "expecting."
#Заходим по ssh
spawn ssh adm@$IP
expect -re "\\$ $"
#Обязательноо запросить sudo пароль
send "sudo -K\r"
expect -re "\\$ $"
#Становимся root
send "sudo su\r"
expect -re "password for"
send "YOU_SUDO_PASSWORD\r"
expect -re "# $"
#Устанавливеам необходимые пакеты(если используете samba шару замените пакет nfs-common на cifs-utils)
send "apt-get install -y apt-show-versions nfs-common\r"
expect -re "# $"
send "exit\r"
expect -re "\\$ $"
exit 0
update – файл для сбора информации о доступных пакетах.
#!/usr/bin/expect -f
set IP [lrange $argv 0 0]
set USERN [lrange $argv 1 1]
set DATES [exec date "+%Y.%m.%d/%H:%M:%S"]
#Подключаемся по ssh (adm сменить на своего пользователя)
spawn ssh adm@$IP
#Ждем конец строки $
expect -re "\\$ $"
#Требуем обязательно запросить пароль от sudo
send "sudo -K\r"
expect -re "\\$ $"
#Становимся root
send "sudo su\r"
expect -re "password for"
send "YOU_SUDO_PASSWORD\r"
#Ждем конец строки #
expect -re "# $"
#Создаем временную папку, для монтирования шары
send "mkdir -m 777 /tmp/share > /dev/null 2>&1\r"
expect -re "# $"
#Монтируем nfs шару (для samba строка будет выглядить иначе)
send "mount.nfs 192.168.0.1:/root/uuman/log /tmp/share\r"
expect -re "# $"
#Дата в лог файл
send "date > /tmp/share/$IP.log\r"
expect -re "# $"
#Версия ядра, битность системы в лог файл
send "uname -a >> /tmp/share/$IP.log\r"
expect -re "# $"
#Имя пользовтаеля в лог
send "echo Username:$USERN >> /tmp/share/$IP.log\r"
expect -re "# $"
#IP в лог
send "echo IP:$IP >> /tmp/share/$IP.log\r"
expect -re "# $"
#Имя хоста в лог
send "(echo -n Hostname:;hostname) >> /tmp/share/$IP.log\r"
expect -re "# $"
#Версия Ubuntu в лог
send "(cat /etc/issue.net) >> /tmp/share/$IP.log\r"
expect -re "# $"
#Считаем количетсво достпуных пакетов для обновления и записываем в лог файл
send "(echo -n Count of packages for update:;apt-show-versions -u | wc -l) >> /tmp/share/$IP.log\r"
expect -re "# $"
#Пустая строка
send "echo >> /tmp/share/$IP.log\r"
expect -re "# $"
#Расширеный список пакетов для обновления в лог
send "apt-show-versions -u | column -t >> /tmp/share/$IP.log\r"
expect -re "# $"
#Строка для конфигурации денамического меню (ИМЯ пользователя | IP | ubuntu_version | кол-во пакетов | дата запроса)
send "(echo -n $USERN;echo -n ' |' $IP '| ';cat /etc/issue.net | sed 's/ /_/g';echo -n AvailableUpdates\:;apt-show-versions -u | wc -l ;echo -n $DATES) > /tmp/share/.menu_log/$IP.log\r"
expect -re "# $"
#Отмонтируем шару
send "umount -f /tmp/share\r"
expect -re "# $"
#Очищаем историю root
send "history -c\r"
expect -re "# $"
#выходим из root
send "exit\r"
expect -re "\\$ $"
exit 0
package – файл для обновления клиентских машин.
#!/usr/bin/expect -f
set IP [lrange $argv 0 0]
set USERN [lrange $argv 1 1]
set DATES [exec date "+%Y.%m.%d/%H:%M:%S"]
#Ждем окончания каждой команды
set timeout -1
spawn ssh adm@$IP
expect -re "\\$ $"
send "sudo -K\r"
expect -re "\\$ $"
send "sudo su\r"
expect -re "password for"
send "YOU_SUDO_PASSWORD\r"
expect -re "# $"
#Обновляем систему
send "apt-get -y upgrade\r"
expect -re "# $"
#Собираем информацию в лог
send "mkdir -m 777 /tmp/share > /dev/null 2>&1\r"
expect -re "# $"
send "mount.nfs 192.168.0.1:/root/uuman/log /tmp/share\r"
expect -re "# $"
send "date > /tmp/share/$IP.log\r"
expect -re "# $"
send "uname -a >> /tmp/share/$IP.log\r"
expect -re "# $"
send "echo IP:$IP >> /tmp/share/$IP.log\r"
expect -re "# $"
send "(echo -n Hostname:;hostname) >> /tmp/share/$IP.log\r"
expect -re "# $"
send "(cat /etc/issue.net) >> /tmp/share/$IP.log\r"
expect -re "# $"
send "(echo -n Count of packages for update:;apt-show-versions -u | wc -l) >> /tmp/share/$IP.log\r"
expect -re "# $"
send "echo >> /tmp/share/$IP.log\r"
expect -re "# $"
send "apt-show-versions -u | column -t >> /tmp/share/$IP.log\r"
expect -re "# $"
send "(echo -n $USERN;echo -n ' |' $IP '| ';cat /etc/issue.net | sed 's/ /_/g';echo -n AvailableUpdates\:;apt-show-versions -u | wc -l ;echo -n $DATES) > /tmp/share/.menu_log/$IP.log\r"
expect -re "# $"
send "umount /tmp/share\r"
expect -re "# $"
send "apt-get -y upgrade\r"
expect -re "# $"
send "history -c\r"
expect -re "# $"
send "exit\r"
expect -re "\\$ $"
exit 0
uuman.sh – файл запуска (основной файл).
#!/bin/bash
#Дата для логов
DATE=`date "+%Y.%m.%d/%H:%M:%S"`
#Папка лог файлов
LOCAL="/root/uuman/log"
#Рабочая папка скрипта
WORKD="/root/uuman"
#[\]Идикатор работы
spinner()
{
local pid=$1
local delay=0.25
while [ $(ps -eo pid | grep $pid) ]; do
for i in \| / - \\; do
printf ' [%c]\b\b\b\b' $i
sleep $delay
done
done
printf '\b\b\b\b'
}
#Функция для обновления информации о хостах
UPDATEA()
{
#2012_11_23
DATEFN=`date "+%Y_%m_%d"`
#Задаем права на папку с логами. Данная строка используется для nfs
chown -R nfsnobody:nfsnobody $LOCAL
i=0
#Обрабатываем каждую строку файла
cat $WORKD/ip.txt | while read line; do
USERN=`echo $line`
#Получаем IP из строки
IP=`echo $line | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'`
#Доступность хоста
if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then
i=`expr $i + 1`
#Для каждого хоста отдельный screen
screen -A -m -d -S "upd$i" expect $WORKD/update $IP $USERN
#Строка для начальной настройки хостов
#screen -A -m -d -S "upd$i" expect $WORKD/setup $IP
else
#Если хост не доступен пишем в логи соответсующий вывод
#Данные в лог ошибок
echo "$DATE" >> $LOCAL/err.txt
echo "$USERN - not connected" >> $LOCAL/err.txt
echo >> $LOCAL/err.txt
#Данные в общий лог
echo "$DATE | $USERN - not connected" >> $LOCAL/upd.txt
echo >> $LOCAL/upd.txt
#Данные в лог текущей даты
echo "$DATE | $USERN - not connected" >> $LOCAL/UPD-$DATEFN.txt
echo >> $LOCAL/UPD-$DATEFN.txt
#Если хост когда-либо был в сети, не ставить статус not connected в меню
NT=`cat $LOCAL/.menu_log/$IP.log | grep "AvailableUpdates"`
if [ -z "$NT" ]; then
echo -n "$USERN | Unknown | NotConnected | $DATE" > $LOCAL/.menu_log/$IP.log
fi
fi
done
#Информация по хостам в общий лог
ls $LOCAL | grep .log | while read TXT; do
paste $LOCAL/$TXT >> $LOCAL/upd.txt
echo >> $LOCAL/upd.txt
#В лог на текущую дату
paste $LOCAL/$TXT >> $LOCAL/UPD-$DATEFN.txt
echo >> $LOCAL/UPD-$DATEFN.txt
done
}
#Функция для обновления всех хостов
PACKAGEA()
{
#2012_11_23
DATEFN=`date "+%Y_%m_%d"`
#Задаем права на папку с логами. Данная строка используется для nfs
chown -R nfsnobody:nfsnobody $LOCAL
i=0
#Обрабатываем каждую строку файла
cat $WORKD/ip.txt | while read line; do
USERN=`echo $line`
#Получаем IP из строки
IP=`echo $line | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'`
#Доступность хоста
if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then
i=`expr $i + 1`
#Для каждого хоста отдельный screen
screen -A -m -d -S "upd$i" expect $WORKD/package $IP $USERN
else
#Если хост не доступен пишем в логи соответсующий вывод
#Данные в лог ошибок
echo "$DATE" >> $LOCAL/err.txt
echo "$USERN - not connected" >> $LOCAL/err.txt
echo >> $LOCAL/err.txt
#Данные в общий лог
echo "$DATE | $USERN - not connected" >> $LOCAL/upd.txt
echo >> $LOCAL/upd.txt
#Данные в лог текущей даты
echo "$DATE | $USERN - not connected" >> $LOCAL/UPD-$DATEFN.txt
echo >> $LOCAL/UPD-$DATEFN.txt
#Если хост когда-либо был в сети, не ставить статус not connected в меню
NT=`cat $LOCAL/.menu_log/$IP.log | grep "AvailableUpdates"`
if [ -z "$NT" ]; then
echo -n "$USERN | Unknown | NotConnected | $DATE" > $LOCAL/.menu_log/$IP.log
fi
fi
done
#Информация по хостам в общий лог
ls $LOCAL | grep .log | while read TXT; do
paste $LOCAL/$TXT >> $LOCAL/upd.txt
echo >> $LOCAL/upd.txt
#В лог на текущую дату
paste $LOCAL/$TXT >> $LOCAL/UPD-$DATEFN.txt
echo >> $LOCAL/UPD-$DATEFN.txt
done
}
#Функция генерация общего мини-отчета по хостам (Меню)
MAIN()
{
rm -rf $LOCAL/MENU.txt
ls $LOCAL/.menu_log | grep .log | while read MENU; do
#Все для красивого вывода (возврат строки и замена символов)
TEXT=`paste -s -d '|' $LOCAL/.menu_log/$MENU | sed 's/|/ | /g;s/-/|/g'`
echo $TEXT >> $LOCAL/MENU.txt
done
#Очистка экрана и табличный вывод файла
clear && cat $LOCAL/MENU.txt | column -t
}
#Меню скрипта
MENU()
{
echo
echo "1.Get update-information for Ubuntu-host (by custom IP-address)"
echo "2.Get update-information for all Ubuntu-hosts (uses file with IP-addresses)"
echo "3.Update packages for Ubuntu-host (by custom IP-address)"
echo "4.Update packages for all hosts (uses file with IP-addresses)"
echo "5.View error-connection log"
echo "6.Refresh"
echo "7.Exit"
read SELECT
case $SELECT in
1)
#Информация о конкретном IP
echo -n "Enter IP:"
read IP
#Задаем права на папку с логами. Данная строка используется для nfs
chown -R nfsnobody:nfsnobody $LOCAL
#Доступен ли хост
if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then
#Находим пользовтеля по IP и получаем его имя
USERN=`cat $WORKD/ip.txt | grep "$IP" | sed 's/ .*//'`
$WORKD/update $IP $USERN > /dev/null 2>&1 & spinner $!
cat $LOCAL/$IP.log
else
#Уведомляем и записываем в лог ошибок
echo "Computer is not online"
echo "$DATE" >> $LOCAL/err.txt
echo "$IP - not connected" >> $LOCAL/err.txt
echo >> $LOCAL/err.txt
fi
MENU
;;
2)
#Обновить информацию о всех хостах
UPDATEA > /dev/null 2>&1 & spinner $!
#Не все хосты успевают быстро обработать информацию, можно выставить задержку перед показом меню
#sleep 5s
MAIN
MENU
;;
3)
#Обновить конкретный IP
echo "Enter IP:"
read IP
#Задаем права на папку с логами. Данная строка используется для nfs
chown -R nfsnobody:nfsnobody $LOCAL
if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then
#Находим пользовтеля по IP и получаем его имя
USERN=`cat $WORKD/ip.txt | grep "$IP" | sed 's/ .*//'`
$WORKD/package $IP $USERN > /dev/null 2>&1 & spinner $!
cat $LOCAL/$IP.log
else
echo "Computer is not online"
echo "$DATE" >> $LOCAL/err.txt
echo "$IP - not connected" >> $LOCAL/err.txt
echo >> $LOCAL/err.txt
fi
MENU
;;
4)
#Обновить все хосты
PACKAGEA > /dev/null 2>&1 & spinner $!
#Не все хосты успевают быстро обработать информацию, можно выставить задержку перед показом меню
#sleep 5s
MAIN
MENU
;;
5)
#Показать лог ошибок
cat $LOCAL/err.txt
MENU
;;
6)
#Обновить
MAIN
MENU
;;
7)
exit 0
;;
*)
MENU
esac
}
#Запуск скрипта с параметрами
#Получаем параметр
ARG=$1
case $ARG in
#Обновить информацию о всех хостах
check)
UPDATEA
exit 0
;;
#Обновить все хосты
update)
PACKAGEA
exit 0
;;
*)
MAIN
MENU
;;
esac
ip.txt – база содержащая User – IP.
User1 — 192.168.0.1
User2 — 192.168.0.2
User3 — 192.168.0.3
User4 — 192.168.0.4
User2 — 192.168.0.2
User3 — 192.168.0.3
User4 — 192.168.0.4
Как пользоваться:
Если Вы использовали свои пути, поправьте следующие переменные в uuman.sh:
#Папка лог файлов
LOCAL="/root/uuman/log"
#Рабочая папка скрипта
WORKD="/root/uuman"
Скрипт setup установит необходимые пакеты для работы программы на клиентских станциях. Чтобы использовать скрипт, в файле uuman.sh закомментируйте строку:
screen -A -m -d -S "upd$i" expect $WORKD/update $IP $USERN
И раскомментируйте:#screen -A -m -d -S "upd$i" expect $WORKD/setup $IP
Автоматический режим:
$WORKD/uuman.sh check
— чек клиентских станций из файла ip.txt на доступность обновлений.$WORKD/uuman.sh update
— обновление клиентских станций, доступных из файла ip.txt.Итог:
Мы получаем клиент-серверную систему позволяющую в автоматическом или ручном режиме получать, хранить и обрабатывать информацию об актуальности установленных программ, пакетов безопасности и при необходимости производить обновление на клиентских станциях под управлением Ubuntu Linux.
UPD:
Авторизация теперь по ssh-key.
Генерируем ключ
ssh-keygen -t rsa
С помощью файла setup, размещаем его на клиентских станциях.