1 жовт. 2022 р.

Встановлення Mikrotik CHR 7.5 в Proxmox з використанням ZFS

1. Створити віртуальну машину з кількістю ОЗУ 192 Мб. У випадку якщо потрібно щоб в CHR використовувалось 128 Мб. Для збільшення кількості ОЗУ необхідно до необхідної кількості додати ще 64 Мб. Система забирає їх під відео підсистему. Додати жорсткий диск об'ємом не менше 128 Мб (в Winbox - system - resources буде відображатись 96 Мб Для того щоб було, наприклад 128 Мб реальні - необхідно додати + 40 Мб (чому так не знаю) = 168 Мб. В інтерфейсі Proxmox це буде 0.164 Гб)

2. Скачати за допомогою wget на хост .img Mikrotik CHR з сайту наприклад версію 7.5

3. Розпакувати zip архів з Mikrotik CHR командою unzip chr-7.5.img.zip

4. Записати за допомогою команди dd розпакований .img в віртуальний диск створений на етапі 1

наприклад команда може виглядати так: dd if=chr-7.5.img of=/dev/zvol/rpool/data/vm-100-disk-0

8 лип. 2020 р.

Налаштування Zaborona Help в Vyos

1. Завантажуємо ключі та сертифікати в каталог /config/auth

curl -o /config/auth/zaborona-help.crt https://zaborona.help/zaborona-help.crt
curl -o /config/auth/zaborona-help.key https://zaborona.help/zaborona-help.key
curl -o /config/auth/zaborona-help-ca.crt https://zaborona.help/ca.crt

2. Створюємо новий openvpn інтерфейс в режимі клієнта (якщо в системі вже створено інтерфейс "vtun0", введіть інший інтерфейс, наприкалад "vtun1")

set interfaces openvpn vtun0 mode client
set interfaces openvpn vtun0 hash sha1
set interfaces openvpn vtun0 encryption aes128
set interfaces openvpn vtun0 remote-port 1194
set interfaces openvpn vtun0 remote-host vpn.zaborona.help
set interfaces openvpn vtun0 openvpn-option "--nobind"
set int openvpn vtun0 openvpn-option "--tun-mtu 1500"
set int openvpn vtun0 openvpn-option "--mssfix 1450"
set int openvpn vtun0 openvpn-option "--sndbuf 524288"
set int openvpn vtun0 openvpn-option "--rcvbuf 524288"
set int openvpn vtun0 openvpn-option "--verb 3"
set interfaces openvpn vtun0 tls cert-file /config/auth/zaborona-help.crt
set interfaces openvpn vtun0 tls key-file /config/auth/zaborona-help.key
set interfaces openvpn vtun0 tls ca-cert-file /config/auth/zaborona-help-ca.crt

3. Створюємо правило NAT (якщо в системі вже створено правило NAT за номером "1", введіть інший номер, наприклад "10")

set nat source rule 1 description --==ZABORONA==--
set nat source rule 1 outbound-interface vtun0
set nat source rule 1 translation address masquerade

4. Активуємо конфігурацію та зберігаємо її

commit
save

13 трав. 2020 р.

Установка модуля мониторинга Host OS в iDrac в Proxmox

Для того чтобы iDrac отображал информацию о хосте необходимо доустановить в операционной системе два .deb пакета. Так как Dell в инсталляторе модуля не поддерживает ОС Debian, на базе которой построен Proxmox, пакеты можно установить вручную взяв их предварительно из инсталляционного образа iDRAC Service Module for Linux. Нужны пакеты:

dcism-3.5.1-1949.ubuntu18.deb и dcism-osc-5.0.0-41.ubuntu18.deb

Нужно положить их в один каталог после чего выполнить команды в последовательности описанной ниже:

apt-get install libcurl4
dpkg -i dcism-osc-5.0.0-41.ubuntu18.deb
dpkg -i dcism-3.5.1-1949.ubuntu18.deb
systemctl start dcismeng


Нет доступа к диску после монтирования VeraCrypt в Windows запущенной на Mac

Если у вас возникла проблема с доступом в смонтированный контейнер VeraCrypt под управлением Windows установленной через Bootcamp или создание нового контейнера с файловой системой NTFS:

Перейдите в каталог C:\Windows\System32\ drivers" и переименуйте appleHFS.sys, например в appleHFS.sys.bak После чего перезагрузите компьютер.

12 трав. 2020 р.

Настройка изолированного сервера Proxmox после установки


--------------------------------------------------------------
Базовые настройки
--------------------------------------------------------------

При наличии достаточного количества ОЗУ, для уменьшения нагрузки на ЦП отключаем службу KSM

systemctl disable ksmtuned

Отключаем и удаляем раздел Swap, а также раздел Data

swapoff -a
lvremove /dev/pve/swap
lvremove /dev/pve/data

Создаем раздел Swap размером 2 Гб и подключаем его

lvcreate -n swap -L 2G pve
mkswap -L swap /dev/pve/swap
swapon -a

Увеличиваем файловую систему до максимального размера

lvresize -l +100%FREE /dev/pve/root
resize2fs /dev/mapper/pve-root

--------------------------------------------------------------
Ограничение использования Swap
--------------------------------------------------------------

Задаем порог помещения в Swap

sysctl -w vm.swappiness=0
sysctl -p

Переподключаем раздел Swap

swapoff -a
swapon -a

Автоматизируем параметры использования Swap раздела при перезагрузке

nano /etc/sysctl.conf
vm.swappiness = 0

Создаем файл rc.local с запретом неконтролированного помещения данных в Swap

nano /etc/rc.local

Помещаем содержимое скрипта в созданный файл rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# fix for proxmox kernel swappiness problem
for i in $(/usr/bin/find /sys /var/lib 2>/dev/null | /bin/grep slice | grep swappiness) ; do [ -f ${i} ] && /bin/echo 0 > ${i} ; done
exit 0

Делаем файл rc.local исполняемым

chmod +x /etc/rc.local

Создаем файл автозапуска файла rc.local

nano /etc/systemd/system/rc-local.service

Помещаем содержимое скрипта в созданный файл rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
After=pve-cluster.service

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Делаем файл rc.local.service запускаемым при старте системы и и запускаем его вручную

systemctl enable rc-local
systemctl start rc-local.service

--------------------------------------------------------------
Обновление и установка дополнительного ПО
--------------------------------------------------------------

Создаем файл не стабильного репозитория

touch /etc/apt/sources.list.d/pve-no-subscription.list

Заполняем файл репозитория ссылкой

echo 'deb http://download.proxmox.com/debian/pve buster pve-no-subscription' >> /etc/apt/sources.list.d/pve-no-subscription.list

Для версии Proxmox 7 заполняем файл репозитрория ссылкой

echo 'deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription' >> /etc/apt/sources.list.d/pve-no-subscription.list

Комментируем использование коммерческого репозитория

sed -i 's/^/#/' /etc/apt/sources.list.d/pve-enterprise.list

Для версии Proxmox 8 заполняем файл репозитрория ссылкой

echo 'deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription' >> /etc/apt/sources.list.d/pve-no-subscription.list

echo 'deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription' >> /etc/apt/sources.list.d/pve-no-subscription.list

Комментируем использование коммерческого репозитория ceph (только для версии PVE 8)

sed -i 's/^/#/' /etc/apt/sources.list.d/ceph.list

Обновляем систему

apt-get update
apt-get upgrade
apt-get dist-upgrade

Устанавливаем дополнительное ПО. ifupdown2 нужен для переконфигурирования сетевых интерфейсов без перезапуска сервера.

apt install screen mc nmon iotop ioping iptraf iftop speedometer htop nload ncdu ntfs-3g fio ifupdown2 openvswitch-switch

Очищаем ненужное

apt-get autoremove
apt-get autoclean

--------------------------------------------------------------
Локализация консоли
--------------------------------------------------------------

dpkg-reconfigure locales

Выбираем ru_RU.UTF-8 UTF-8 и нажимаем Ок
В следующем окне выбираем ru_RU.UTF-8 и нажимаем Ок

dpkg-reconfigure console-setup

Выбираем UTF-8 и нажимаем Ок
Выбираем Cyrillic — non-Slavic languages и нажимаем Ок
Выбираем Fixed и нажимаем Ок
Выбираем 8х16 и нажимаем Ок

--------------------------------------------------------------
Отключаем окно предупреждения о отсутствии лицензии
--------------------------------------------------------------

Делаем резервную копию оригинального файла

cp /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.bak

Комментируем строку проверяющую лицензию

sed -i "s/getNoSubKeyHtml:/getNoSubKeyHtml_:/" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js

--------------------------------------------------------------
Скачиваем драйвера Virtio
--------------------------------------------------------------

wget -P /var/lib/vz/template/iso https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso

--------------------------------------------------------------
Настройка NAT и DHCP на хосте
--------------------------------------------------------------

1. Создаем новый Bridge, например vmbr1 и назначаем ему IP адрес, например 192.168.158.1./24
В настройки созданного бриджа добавляем:

hwaddress ether ab:cd:12:34:56:78

Это нужно для того чтобы виртуальные машины Windows при перезапуске каждый раз не обнаруживали новую сеть.

В конец файла /etc/network/interfaces добавляем следующие правила

#Разрешаем маршрутизацию между интерфейсами
post-up echo 1 > /proc/sys/net/ipv4/ip_forward

#Разрешаем Source NAT из локальной сети 192.168.158.0/24 
post-up iptables -t nat -A POSTROUTING -s '192.168.158.0/24' -o vmbr0 -j MASQUERADE

#Если необходимо, например, пробросить RDP внутрь виртуальной машины с наружного порта 49389 на внутренний 3389. Создаем правила tcp и udp. В правиле указываем интерфейс - бридж на котором назначен внешний IP.
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp -m tcp --dport 49389 -j DNAT --to-destination 192.168.158.10:3389
post-up iptables -t nat -A PREROUTING -i vmbr0 -p udp -m udp --dport 49389 -j DNAT --to-destination 192.168.158.10:3389

#Удаляем правила при остановке
post-down iptables -t nat -D POSTROUTING -s '192.168.158.0/24' -o vmbr0 (enp1s0, eth0 или другие варианты) -j MASQUERADE
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp -m tcp --dport 49389 -j DNAT --to-destination 192.168.158.10:3389
post-down iptables -t nat -D PREROUTING -i vmbr0 -p udp -m udp --dport 49389 -j DNAT --to-destination 192.168.158.10:3389

Устанавливаем dhcp и dns сервер dnsmasq

apt install dnsmasq

Редактируем конфигурационный файл dnsmasq

nano /etc/dnsmasq.conf

Добавляем в конец файла

interface=vmbrl
listen-address=192.168.158.1
dhcp-range=interface:vmbr1,192.168.158.101,192.168.158.199,255.255.255.0,12h
dhcp-option=interface:vmbr1,3,192.168.158.1
dhcp-option=interface:vmbr1,6,192.168.158.1
dhcp-option=interface:vmbr1,15,pve.lan

Перезапускаем dnsmasq /etc/init.d/dnsmasq restart

--------------------------------------------------------------
Инициализация новых дисков в системе
--------------------------------------------------------------

Очистка информации, иницализация в GPT и создание одного раздела типа LVM

sgdisk /dev/sdX -Z -U -R -N 1 -t 1:8e00

Очистка информации, иницализация в GPT и создание одного раздела типа Linux Filesystem

sgdisk /dev/sdX -Z -U -R -N 1 -t 1:8300

--------------------------------------------------------------
Создание тома LVM Thin
--------------------------------------------------------------

Мне не нравится как Proxmox создает lvm thin через веб интерфейс, поэтому делаю это вручную. lvm thin нужен для работы снепшотов.

Создание физического тома (PV)

pvcreate /dev/sdX1

Создание группы томов (VG)

vgcreate volume_group_name /dev/sdX1

Создание раздела Meta (высчитывается как 1% от емкости дисковой группы)

lvcreate -L XG volume_group_name

Создание раздела свободного пространства для расширения раздела Meta в случае завершения в нем места. Минимум 1 Гб

lvcreate -L XG volume_group_name

Создание раздела Data (оставшееся свободное пространство)

lvcreate -l +100%FREE volume_group_name

Удаление раздела свободного места для расширения раздела Meta

lvremove volume_group_name/lvol1

Пример для диска объемом 6 Тб

pvcreate /dev/sdb1
vgcreate data /dev/sdb1
lvcreate -L 15G data
lvcerate -L 5G data
lvcreate -l +100%FREE data
lvremove data/lvol1

Конвертация раздела LVM в разреженный том (Thin Pool) без дублирующего раздела для Meta - pmspare (Данный раздел позволяет восстановить данные в случае повреждения раздела Meta)

lvconvert --type thin-pool --poolmetadataspare n --poolmetadata volume_group_name/lvol0 volume_group_name/lvol2

Переименование раздела lvm thin

lvrename /dev/volume_group_name/lvol2 /dev/volume_group_name/volume_new_name

Увеличение раздела Meta при отсутствии в нем свободного места

lvextend --poolmetadatasize +1G volume_group_name/volume_name

29 жовт. 2017 р.

Перемещение виртуального диска LVM от одной виртуальной машины к другой в Proxmox



Для того чтобы переместить виртуальный диск LVM от одной виртуальной машины к другой можно использовать команду lvrename

Узнать какой диск нужно переименовать можно командой lvscan

root@host:~# lvscan

ACTIVE '/dev/pve/swap' [7,00 GiB] inherit
ACTIVE '/dev/pve/root' [96,00 GiB] inherit
ACTIVE '/dev/pve/data' [812,26 GiB] inherit
ACTIVE '/dev/pve/vm-102-disk-1' [100,00 GiB] inherit
ACTIVE '/dev/pve/vm-101-disk-1' [40,00 GiB] inherit
ACTIVE '/dev/ssd/vm-101-disk-1' [120,00 GiB] inherit



После чего можно переименовывать (диск предварительно должен быть отключен от ВМ)

root@host:~# lvrename /dev/pve/vm-101-disk-1 /dev/pve/vm-102-disk-2


Результатом будет:

Renamed "vm-101-disk-1" to "vm-102-disk-2" in volume group "pve"

Далее в конфиге старой ВМ удаляем, а конфиге новой ВМ добавляем диск.

11 черв. 2016 р.

Торможение TeamViewer и Chrome Desktop на серверах с видеокартой Matrox G200eW

Если наблюдается торможение TeamViewer и Chrome Desktop на серверах - проблема в слабой карте Matrox G200eW. Требуется в настройках адаптера отключить аппаратное ускорение.

Пример в Windows Server 2008 R2

1. Правой кнопкой мыши - Разрешение экрана
2. Дополнительные параметры
3. Диагностика
4. Выставить "Аппаратное ускорение" - Нет

24 січ. 2016 р.

Проблема с открытием "больших и тяжелых"сайтов через PPTP VPN настроенного в VyOS

В интернете полно информации как настроить PPTP VPN в VyOS (бывшая Vyatta). Однако, лично у меня, возникла проблема с открытием, через уже установленное VPN соединение, "больших и тяжелых" сайтов, таких как, например, http://speedtest.net.

Для исправления необходимо выполнить в режиме конфигурирования следующую команду:

echo iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu > /config/scripts/vyatta-postconfig-bootup.script

и перезапустить роутер.

4 бер. 2015 р.

Скрипт уточняющий кто жрет Swap

Чтобы узнать кто потребляет Swap делаем:

nano checkswap.sh

Вставляем следующий код:

#!/bin/bash
# Get current swap usage for all running processes
SUM=0
OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`
do
    PID=`echo $DIR | cut -d / -f 3`
    PROGNAME=`ps -p $PID -o comm --no-headers`
    for SWAP in `grep Swap $DIR/smaps 2>/dev/null | awk '{ print $2 }'`
    do
        let SUM=$SUM+$SWAP
    done
    if (( $SUM > 0 )); then
        echo "PID=$PID swapped $SUM KB ($PROGNAME)"
    fi
    let OVERALL=$OVERALL+$SUM
    SUM=0
done
echo "Overall swap used: $OVERALL KB"

Альтернативный вариант:


#!/bin/bash
    # find-out-what-is-using-your-swap.sh

SCRIPT_NAME=`basename $0`;
SORT="kb";                 # {pid|kB|name} as first parameter, [default: kb]
[ "$1" != "" ] && { SORT="$1"; }
[ ! -x `which mktemp` ] && { echo "ERROR: mktemp is not available!"; exit; }
MKTEMP=`which mktemp`;
TMP=`${MKTEMP} -d`;
[ ! -d "${TMP}" ] && { echo "ERROR: unable to create temp dir!"; exit; }
>${TMP}/${SCRIPT_NAME}.pid;
>${TMP}/${SCRIPT_NAME}.kb;
>${TMP}/${SCRIPT_NAME}.name;
SUM=0;
OVERALL=0;
    echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`;
do
    PID=`echo $DIR | cut -d / -f 3`
    PROGNAME=`ps -p $PID -o comm --no-headers`
    for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'`
    do
        let SUM=$SUM+$SWAP
    done
    if (( $SUM > 0 ));
    then
        echo -n ".";
        echo -e "${PID}\t${SUM}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.pid;
        echo -e "${SUM}\t${PID}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.kb;
        echo -e "${PROGNAME}\t${SUM}\t${PID}" >> ${TMP}/${SCRIPT_NAME}.name;
    fi
    let OVERALL=$OVERALL+$SUM
    SUM=0
done
echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
echo;
echo "Overall swap used: ${OVERALL} kB";
echo "========================================";
case "${SORT}" in
    name )
        echo -e "name\tkB\tpid";
        echo "========================================";
        cat ${TMP}/${SCRIPT_NAME}.name|sort -r;
        ;;
    kb )
        echo -e "kB\tpid\tname";
        echo "========================================";
        cat ${TMP}/${SCRIPT_NAME}.kb|sort -rh;
        ;;
    pid | * )
        echo -e "pid\tkB\tname";
        echo "========================================";
        cat ${TMP}/${SCRIPT_NAME}.pid|sort -rh;
        ;;
esac
rm -fR "${TMP}/";


Выполняем: chmod +x checkswap.sh && ./checkswap.sh


3 бер. 2015 р.

Исправление при предупреждении "File System on Control Domain Full" в XenServer 6.2

Суть предупреждения заключается в том, что дисковое пространство в корневой ФС XenServer подходит к концу. Для очистки мы можем удалить старые журнальные файлы и файлы загруженных обновлений. Для этого логинимся в консоли и выполняем команду:

[root@xen ~] cd /var/patch && rm -rf `ls | grep -v 'applied'` && cd /var/log && rm -rf *.gz

Примечание: В каталоге /var/patch/applied находятся уже примененные обновления для вашего XenServer. Удалять сам каталог applied или его содержимое НЕЛЬЗЯ!



12 вер. 2014 р.

Размер голосового почтового ящика в Elastix

По умолчанию, объем голосового почтового ящика пользователя в Elastix ограничен 100 сообщениями. Если необходимо увеличить этот объем то в настройках Extension в разделе Voicemail & Directory, пункте VM Options необходимо добавить параметр maxmsg=X и сохранить настройки. Где X это количество сообщений для изменяемого Extension.

10 серп. 2014 р.

Замена текстового редактора в консоли Linux

Допустим стандартный текстовый редактор vi, надо сменить на nano, в консоли выполняем:

EDITOR="nano"
export EDITOR

или

echo export EDITOR="nano" >> ~/.bashrc

9 серп. 2014 р.

Отключение ненужных услуг мобильных операторов Украины при использовании SIM карт в GSM шлюзе

1. Оповещение о том, что вам звонили но не смогли дозвониться:

Киевстар: *100*03*3#
МТС: *120*32#

2. Оповещение о том, что абонент которому вы звонили снова в сети:

Киевстар: *100*12*3#
МТС: *120*22#

3. Отключение автоответчика:

Киевстар: *100*04*3#
МТС: Звонок на номер 7745

4. Отмена всех переадресаций:

Киевстар: ##002#
МТС: ##002#





2 серп. 2014 р.

Доступ не администратору для прослушивания записей звонков в Elastix

По умолчанию в Elastix только администратор может видеть все записи звонков. Для исправления данной ситуации, необходимо:

1. Создать новую группу, например Monitor
2. Выставить права monitoring (записи) и report (CDR) для этой группы
3. Создать нового пользователя без внутреннего номера, например monitor и включить его в эту группу
4. Привести файл /var/www/html/libs/paloSantoACL.class.php к следующему виду:

function isUserAdministratorGroup($username) 

$is=false; 
$idUser = $this->getIdUser($username); 
if($idUser){ 
$arrGroup = $this->getMembership($idUser); 
//$is = array_key_exists('administrator',$arrGroup); 
$is = array_search('1', $arrGroup); 

if(isset($arrGroup['Monitor'])) 
$is=true; 


return $is; 
}

Строками

if(isset($arrGroup['Monitor'])) 
$is=true; 

Мы разрешили группе Monitor полный доступ к записям.


Перезапуск FOP в Elastix из консоли

Если разговор давно завершился, а Flash Operator Panel (FOP) продолжает показывать, что разговор еще идет, то:

1. Логинимся по SSH на Elastix Server
2. В консоли выполняем команду:


[root@srv ~]# amportal stop_fop && amportal start_fop

9 лип. 2014 р.

Скрипт для удаления устаревших голосовых записей в Elastix

Данный скрипт позволяет удалить устаревшие записи из каталога, а также очисть БД от CDR

#!/bin/bash                                                    user="root"                                                    pass="Pa$$w0rd"                                                db="asteriskcdrdb"                                              #Remove sounds from db for last 60 days                         sql="DELETE FROM cdr WHERE cdr.calldate <= DATE_ADD(NOW(), INTERVAL -15 DAY)"
sqlo="OPTIMIZE TABLE cdr"
mysql -u"$user" -p"$pass"  <
use $db;
$sql;                       
$sqlo;
EOF
#Remove sound from db for last 60 days
find /var/spool/asterisk/monitor/* -mtime +15 -exec rm {} \;  

19 трав. 2014 р.

Использование клавиши F8 в виртуальных машинах Windows, работающих в XenServer

Если необходимо попасть в загрузочное меню Windows, вызываемое нажатием клавиши F8 виртуальных машинах Windows, в настройках виртуальной машины в XenCenter необходимо выставить последовательность загрузки ВМ, начиная с "Network", потому как не хватает времени на переключение в консоль после перезагрузки или запуска ВМ.


5 серп. 2013 р.

Прошивки для контроллеров и OMSA для Dell PowerEdge 1950 II



Собрал в архивчик последние, состоянием на август 2013, прошивки контроллеров и BIOS из под Linux + Windows, а также ПО Dell OpenManage Server Administrator 7.3 (XenServer 6.2 + Windows Server 2008 R2) для сервера Dell PowerEdge 1950 II.

31 лип. 2013 р.

Установка Midnight Commander в XenServer

Так как в комплекте с XenServer mc не идет, придется установить его на лету командой из консоли:

yum install --enablerepo=base mc

26 лип. 2013 р.

С днем системного администратора

Дорогие наши сисадмины
Повод есть поднять за вас пивка
Есть тому весомые причины -
Нет в году подобного денька!


















С праздником, коллеги.