суббота, 9 декабря 2017 г.

Визуализация отчетов биллинга Google Cloud Platform

GCP позволяет получать ежедневные отчеты по биллингу в любой бакет проекта.
Это описано в документации: https://cloud.google.com/billing/docs/how-to/export-data-file
Полученный файл имеет формат CSV, который можно смотреть например в LibreOffice Calc.
Для визуализации и фильтрации таких отчетов я сделал небольшой проект, с помощью которого можно просматривать отчеты в удобочитаемом виде, при этом они генерируются автоматически по крону.

Настройка эта очень простая, сам проект находится тут: https://github.com/Amet13/gcloud-billing-visualize

Выглядит это примерно так:

воскресенье, 26 ноября 2017 г.

Где найти образы виртуальных машин (raw/qcow2)?

Вот тут актуальная информация, где можно найти образы ОС для развертывания виртуальных машин: https://docs.openstack.org/image-guide/obtain-images.html
Они могут пригодиться для KVM, OpenStack и прочего. В основном образы в формате img и qcow2.
Ссылка вряд ли будет меняться, а содержимое доки будет пополняться, поэтому не дублирую сюда.

Там же в документации описано, как такие образы можно собирать, конвертировать форматы и прочее. Полезная штука, тем кто будет заниматься развертыванием виртуалок на KVM например.

пятница, 10 ноября 2017 г.

ClamAV: lstat() failed: Permission denied

При попытке отправить письмо в связке с Exim+ClamAV появилась такая ошибка:
malware acl condition: clamd: ClamAV returned: /var/spool/exim4/scan/id.eml: lstat() failed: Permission denied. ERROR​

Фиксится это правкой конфигов:
/etc/clamav/freshclam.conf
/etc/clamav/clamd.conf

директивой:
AllowSupplementaryGroups yes

четверг, 2 ноября 2017 г.

Визуализируем карту мира с highcharts

Просматривая на просторах интернета список стран, в которые нужна или не нужна виза я повсюду натыкался на информацию в виде списка стран, пример: https://www.passportindex.org/comparebyPassport.php?p1=ru&fl=&s=yes. Мне казалось что просматривать такое удобно в виде карты.
Так как на сайте passportindex информация обновляется довольно оперативно, то я решил стягивать оттуда актуальную информацию по визам и странам и визуализировать это в виде карты мира.

вторник, 3 октября 2017 г.

Error: Could not initialize class sun.security.ec.SunEC

При запуске selenium на одной из нод со старой версией ОС (Fedora 22) столкнулся с тем, что selenium работает некорректно:
ERROR: Could not initialize class sun.security.ec.SunEC
phantomjs
Error: Could not initialize class sun.security.ec.SunEC

Версия java вполне себе свежая:
# java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

Однако тут есть один момент.
В относительно новых версиях JDK, SunEC был удален и заменен на nss, поэтому nss нужно обновить, в моем случае на последнюю версию из репозитории Fedora:
# dnf list installed | grep ^nss.x86_64
nss.x86_64      3.19.2-1.0.fc22     @System
# dnf update nss
# dnf list installed | grep ^nss
nss.x86_64      3.23.0-1.0.fc22     @System

После этого ошибка исчезла с новой версией nss.

via.

четверг, 14 сентября 2017 г.

Нотификации об ошибках в Redis-кластере с помощью Sentinel и Slack

На самом деле можно куда угодно слать уведомление, хоть в систему мониторинга, хоть на почту. Я отправляю в Slack.

Вот как выглядит скрипт отправки сообщения:
# vim /srv/sentinel_notification.bash
#!/bin/bash

SLACK_URL=https://hooks.slack.com/services/12345 # your webhook url

if [ "$#" = "2" ]; then
SLACK_BODY=`cat << EOB
=====================================
Information about your Redis Cluster.
Check Redis server or sentinel.
=====================================
Event type: ${1}
Event description: ${2}

Message sent by Sentinel Notification feature.

EOB`
    curl -X POST --data-urlencode "payload={\"channel\": \"#monitoring\", \"username\": \"Redis Sentinel from dbs\", \"text\": \"\`\`\`$SLACK_BODY\`\`\`\"}" $SLACK_URL
fi

Делаем скрипт исполняемым:
# chmod +x /srv/sentinel_notification.bash

В конфиг sentinel прописываем наш скрипт:
# vim /etc/redis-sentinel.conf
....
sentinel notification-script mymaster /srv/sentinel_notification.bash
...

Рестартим сервис:
# systemctl restart redis-sentinel

Вот пример того, как выглядит сообщение в Slack:

Список всех event type можно посмотреть в документации: https://redis.io/topics/sentinel#pubsub-messages

пятница, 4 августа 2017 г.

Особенность при использовании Ansible Python API с Celery

В приложении, которое использует Python API ансибла и запускается с помощью Celery была обнаружена особенность, при которой ансибловский плейбук не отрабатывает и возвращает пустой результат:
# cat ansible.log
2017-08-02 16:02:08,764 --- INFO --- utils run():87 --- Playbook load
2017-08-02 16:02:08,868 --- INFO --- utils run():94 --- Playbook run
2017-08-02 16:02:08,870 --- DEBUG --- utils run():96 --- Options: Options(connection='ssh', module_path='', forks=100, become=True, become_method='sudo', become_user='root', check=False, remote_user='root')
2017-08-02 16:02:09,328 --- DEBUG --- utils run():108 --- 0

Если же этот плейбук запускать руками напрямую, а не через Ansible, то все нормально.

Ошибка заключается в том, что Celery почему-то не может взаимодействовать с ResultCallback функцией Ansible Python API.
Решение такое, перед запуском Celery-воркера нужно задать переменную:
PYTHONOPTIMIZE=1
или запустить Celery c параметром:
-O OPTIMIZATION
После этих манипуляций все работает отлично.

via.

четверг, 3 августа 2017 г.

Генерация конфигурации OpenLDAP + SSSD

Необходимо работающий на сервере LDAP соединить с SSSD, который позволяет подключаться к LDAP, как локально, так и удаленно.
Представим что LDAP-server уже настроен и отзывается на команду:
# ldapsearch -D cn=Manager,dc=domain,dc=com -H ldaps://localhost:636 -b ou=it,dc=domain,dc=com -w

вторник, 25 июля 2017 г.

Некоторые общие проблемы с cron

Наиболее популярным планировщиком заданий в Linux является демон cron.
Демон сервиса под названием crond читает файлы конфигураций (/etc/crontab, /etc/cron.*, /var/spool/cron) и выполняет запланированные задания.

Существуют особенности работы с cron и некоторые сталкиваются с трудностями при его использовании.

пятница, 7 июля 2017 г.

Сборка кроссплатформенного python-инсталлятора с помощью conda constructor

Задача: необходимо собрать минимальное окружение c python 2.7 и gsutil на борту. Окружение должно устанавливаться на Linux, Mac OS X, Windows.
Конечный результат: в каталог файловой системы устанавливаются python и gsutil, который можно использовать без установки системных зависимостей.

Делаю это на основе чистого контейнера с CentOS 7:
# docker run -ti centos bash
# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core)

суббота, 1 июля 2017 г.

Импорт дампа базы MariaDB в Docker при сборке образа

Предположим нам нужно собрать образ на основе Fedora с MariaDB на борту (не самый правильный способ, так как есть куча готовых mysql-образов).
Примерно вот так выглядит мой Dockerfile:
# cat Dockerfile 
FROM fedora

RUN dnf install -y mariadb mariadb-server 
ADD dump/devdb.sql /tmp
ADD dump/initdb.sh /tmp

RUN /tmp/initdb.bash
RUN chown mysql:mysql -R /var/lib/mysql/

CMD ["/usr/bin/mysqld_safe --datadir=/var/lib/mysql"]

В этом докерфайле я описал базовый образ Fedora, установил MariaDB, скопировал дамп базы и скрипт инициализации в образ, выставил права на каталог с данными и описал строку запуска MariaDB.

Во время сборки образа, после копирования файлов в контейнер запускается скрипт initdb.bash вот с таким содержимым:
# cat dump/initdb.bash 
#!/bin/bash

set -e
set -x

mysql_install_db
mysqld_safe --datadir='/var/lib/mysql' --user=root &
until mysqladmin ping >/dev/null 2>&1; do
   sleep 0.2
done

mysql_upgrade && \
mysql -e 'drop database test;' && \
mysql -e 'create database devdb;' && \
mysql devdb < /tmp/devdb.sql && \
echo "Successfully imported" && exit 0

Скрипт инициализирует базы MySQL, запускает MariaDB-server и проверяет запустился ли он (mysqladmin ping), после того, как сервер работает запускается то что нам нужно, а именно удаление базы test, создание чистой базы devdb и импорт дампа в эту базу.

пятница, 23 июня 2017 г.

Интеграция сервисов в Slack (Redmine, Zabbix, Teamcity)

Slack - это корпоративный мессенджер с возможностью интеграции многих сервисов.
В отличие от skype (не skype for business) или telegram очень удобен для работы команды, как в плане общения, так и в плане интеграции.

После перехода со Skype на Slack я в первую очередь решил настроить его интеграцию с некоторыми сервисами, используемыми в IT-инфраструктуре. Некоторые вещи реализуются несколькими кликами в Slack и самом сервисе, а в некоторых приходится искать сторонние решения или придумывать их самому.
В заметке я опишу как я настраивал интеграцию Slack с системой управления проектами Redmine, мониторингом Zabbix и CI-инструментом Teamcity.

среда, 21 июня 2017 г.

Проблема с pip uninstall в Docker

При использовании Storage Driver OverlayFS в Docker возникает проблема с удалением пакета через pip.

Пример:
# docker info | grep "Storage Driver"
Storage Driver: overlay

# vim Dockerfile
FROM fedora:22
RUN pip uninstall six

# docker build -t testimage .
...
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 126, in main
...
OSError: [Errno 39] Directory not empty: '/tmp/pip-oMuCWu-uninstall/usr/bin'
...

Этот баг пофикшен в ядре 4.5.0.-rc6, поэтому нужно обновлять ядро, либо переключаться на другой storage backend, например devicemapper.

воскресенье, 18 июня 2017 г.

Верстка презентации в LaTeX с помощью Beamer

С LaTeX я познакомился на 3 курсе университета в 2014 году увидев курс на Coursera. До этого я слышал что LaTeX это очень сложная штука и используется в основном в научных кругах для верстки статей для журналов.
Оказалось что LaTeX не настолько сложен и потратив несколько дней на его изучение, можно легко верстать как обычные документы, так и презентации.
Тренировался я на разных отчетах, курсачах, методичках, визитках переползая с LibreOffice на LaTeX.
Впоследствии бакалаврский и магистерский дипломы, а также множество презентаций я верстал именно в LaTeX.

воскресенье, 7 мая 2017 г.

Разворачивание окружения для работы LaTeX в Docker

Как известно, пакеты содержащие зависимости LaTeX могут достигать больших размеров и для тех кто не хочет захламлять систему лишними пакетами (например если нужно единожды собрать какой-нибудь проект) можно воспользоваться Docker'ом.

Dockerfile такого вида устанавливает необходимые пакеты для работы XeLaTeX и beamer:
FROM ubuntu
MAINTAINER User <[email protected]>

ENV DIR /master-thesis
RUN mkdir $DIR

RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty multiverse" | tee -a /etc/apt/sources.list.d/multiverse.list && \
   echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections

RUN apt update && \
   apt install -y wget git make apt-transport-https unzip && \
   apt install -y texlive-base texlive-latex-extra texlive-xetex texlive-lang-cyrillic latexmk texlive-fonts-extra texlive-math-extra latex-beamer

RUN apt install -y --reinstall ttf-mscorefonts-installer

RUN wget -O /usr/share/fonts/xits-math.otf https://github.com/khaledhosny/xits-math/raw/master/xits-math.otf && \
   wget http://www.paratype.ru/uni/public/PTSansOFL.zip && \
   wget http://www.paratype.ru/uni/public/PTMono.zip && \
   unzip PTSansOFL.zip -d /usr/share/fonts/ && unzip PTMono.zip -d /usr/share/fonts/ && \
   rm -f PTSansOFL.zip PTMono.zip && \
   fc-cache -f -v

VOLUME $DIR
WORKDIR $DIR

Также тут устанавливаются некоторые шрифты, такие как Times New Roman, XITS Math, PT Sans, PT Mono.
Я например использую такой подход для сборки своего диплома в LaTeX, очень удобно.

пятница, 7 апреля 2017 г.

Автоматическая сборка LaTeX-проекта с GitHub и TravisCI

По умолчанию TravisCI не умеет нативно собирать LaTeX-проекты, однако он позволяет запускать Docker-контейнеры.
Моя задача состоит в том, что у меня есть некий проект, в котором после каждого коммита нужно собирать новый PDF-файл с помощью XeTeX и релизить этот PDF-файл на GitHub.
Можно собирать проект на рабочей машине, но если не хочется устанавливать LaTeX-окружение, то можно воспользоваться Docker.

Расскажу как это реализовано в репозитории: https://github.com/Amet13/master-thesis

вторник, 4 апреля 2017 г.

Уведомление в Telegram после завершения консольной команды

Понадобилось мне тут импортировать большой mysql-дамп и чтобы не сидеть все время в ожидании окончания импорта, я решил отойти по делам, а когда импорт закончится мне придет уведомление в Telegram, так как смартфон всегда при мне.

Делается это очень просто. Для этого нужно только создать бота. На рабочей машине должен быть python3.

среда, 29 марта 2017 г.

Уведомления из Zabbix в Telegram

1. Создаем бота.
Идем к @BotFather
/start
/newbot
Получаем токен вида:
311825528:AAE3r8V7iaIiXzJY_s0-9brG6JMWbT126qB
Добавляем бота в список контактов в телеграме.

2. Узнаем свой TelegramID.
Идем к @MyTelegramID_bot
/start
Получаем ID вида:
281724313

пятница, 17 марта 2017 г.

Заметки по Docker

1. По умолчанию в образах докера CentOS отключена установка документации (man) для экономии места.
Это осуществляется записью в конфиге /etc/yum.conf:
tsflags=nodocs
Поэтому если хотим маны в образах CentOS, этот параметр нужно закомментировать или удалить.

2. В репозиториях CentOS/RHEL, Docker собран с поддержкой параметра --add-registry, что позволяет использовать вот такое в /etc/sysconfig/docker:
ADD_REGISTRY='--add-registry docker-registry:5000'
INSECURE_REGISTRY='--insecure-registry docker-registry:5000'
При таком раскладе, Docker может обращаться к приватному регистри без явного указания адреса, например вместо:
$ docker pull docker-registry:5000/someimage
можно прописать просто:
$ docker pull someimage

Если же Docker установлен из официального репозитория, то там параметра --add-registry нет и нужно всегда указывать явный адрес приватного регистри.

3. Интересная штука написанная на go: https://github.com/bcicen/ctop
Top для Docker-контейнеров.

4. Добавить алиас к образу:
# docker images
REPOSITORY             TAG      IMAGE ID  CREATED           SIZE
registry:5000/image latest  7cb574e42e5b  25 minutes ago    5.435 GB

# docker tag 7cb574e42e5b image2
# docker images
REPOSITORY             TAG      IMAGE ID  CREATED           SIZE
registry:5000/image latest  7cb574e42e5b  25 minutes ago    5.435 GB
image2              latest  7cb574e42e5b  25 minutes ago    5.435 GB

5. Перенос образа контейнера с одной ноды на другую:
# docker save -o <save image to path> <image name>
# docker load -i <path to image tar file>

6. Скопировать файл с хост-ноды в контейнер и наоборот:
# docker cp foo.txt mycontainer:/foo.txt
# docker cp mycontainer:/foo.txt foo.txt

7. Если используется DeviceMapper и вылезает ошибка "No space left on device", это значит, что образ размером более 10G. Фиксить можно так:
# systemctl stop docker
# rm -rf /var/lib/docker
# vim /etc/systemd/system/multi-user.target.wants/docker.service
...
--storage-opt dm.basesize=25G

# systemctl daemon-reload
# systemctl start docker

вторник, 7 марта 2017 г.

Проблема с разрешением имен в Ubuntu/Mint при использовании VPN

Существует в Ubuntu и дистрибутивах на его основе баг, при котором при использовании OpenVPN с NetworkManager локальный резолвер (dnsmasq) не может разрешить имена.
Проявляется это не во всех случаях.

Решением этой проблемы является выпилить dnsmasq из конфига NetworkManager (или закомментить строчку):
# grep dns /etc/NetworkManager/NetworkManager.conf
#dns=dnsmasq

# /etc/init.d/network-manager restart

Начиная с Ubuntu 17.04 эта проблема не должна проявляться, так как dnsmasq заменили на systemd-resolved.

среда, 1 марта 2017 г.

Мониторинг уязвимостей в используемом ПО из открытых источников

Идея была написать скрипт, который 1-2 раза в сутки ходит в какую-нибудь базу уязвимостей и смотрит появились ли за сегодня уязвимости в списке требуемого ПО.
Один из таких открытых источников является www.cvedetails.com в котором даже есть некое подобие API.

Решил я писать на питоне, просто потому что интересно было что-то на нем написать.
Получилось в принципе нормально, скрипт свою работу делает. Репозиторий тут: https://github.com/Amet13/vulncontrol там же и инструкция как это все запустить.

В случае обнаружения уведомлений скрипт умеет отправлять уведомление в телеграм.
По желанию можно его засунуть в мониторинг, например Nagios/Icinga2 или Zabbix.
Или просто добавить его в крон.

Есть возможность указания своей даты, если нужно например посмотреть какие уязвимости были в определенный день. Также можно фильтровать уязвимости по CVSS.

Статический анализатор кода flake8 немного помог мне оформить правильно код, т.к. на питоне пишу можно сказать впервые.
Также интересно было попробовать как с GitHub работает TravisCI, довольно удобная интересная штука для открытых проектов и не только.

пятница, 3 февраля 2017 г.

Permission denied в Docker-volume

При монтировании тома в Docker-контейнере столкнулся с проблемой, что в контейнере нет доступа к смонтированному каталогу.
# docker run --name=nginx -d -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /var/lib/docker/volumes/nginx:/var/log/nginx -p 80:80 local/c7-nginx
# docker exec -it nginx bash
# ls /var/log/nginx/access.log 
ls: cannot access /var/log/nginx/access.log: Permission denied

Проблема оказалась в контроле доступов SELinux, который не позволял для контейнеров расшаривать файлы.
Тут можно почитать об этом: https://habrahabr.ru/company/kingservers/blog/209644/

Решение, отключить SELinux:
# echo SELINUX=disabled > /etc/selinux/config
# SELINUXTYPE=targeted >> /etc/selinux/config
# setenforce 0

Либо дать соответствующие права для каталога:
# chcon -Rt svirt_sandbox_file_t /var/lib/docker/volumes/nginx/

Проверка:
# docker stop nginx ; docker start nginx
# docker exec -it nginx bash
# ls /var/log/nginx/access.log
/var/log/nginx/access.log

понедельник, 23 января 2017 г.

Удаление файла с некорректным именем

Если файл имеет название типа S�vety-i-rekom.pdf и при этом через rm его не удалить, то это можно сделать с помощью find и inode файла.
# ls -li | grep rekom
41831918 -rw-r--r--  1 username usergroup    54074 Jan 30  2016 S\356vety-i-rekom.pdf
# find . -inum 41831918 -delete