Автоматическое резервное копирование баз PostgreSQL

Есть удаленный доступ к серверы с базами данных PostgreSQL, надо делать их локальные дампы. Потом другой хост забирает данные по rsync и сам уже следит за удалением устаревших. Для MySQL работает хорошо. С Postgres’ом есть свои нюансы.
Чтобы не светить логины и пароли к базе при вызове команды pg_dump, они прописываются в специальном файлике ~/.pgpass:
#hostname:port:database:username:password
localhost:5432:database1:username1:strongpassword
localhost:5432:database2:username2:strongpassword

Права на файл:
$ chmod 600 ~/.pgpass

Вызов команд из crontab:
50 0 * * * /usr/bin/pg_dump --no-password -U username1 -h localhost database1 > /home/username/backup/database1.`date +\%Y-\%m-\%dT\%H:\%M:\%S`.pgsql
55 0 * * * /usr/bin/pg_dump --no-password -U username2 -h localhost database2 > /home/username/backup/database2.`date +\%Y-\%m-\%dT\%H:\%M:\%S`.pgsql

Если не указать хост, pg_dump выдаст ошибку и дамп создан не будет.

Бекап-сервер потом все забирает такой командой:
30 1 * * * /usr/bin/rsync -avz --remove-source-files -e "/usr/bin/ssh" username@server.domain.tld:backup/ /var/backup/server.db > /dev/null 2>&1

Разумеется, на удаленном сервере должны быть установлены OpenSSH и rsync, настроена авторизация по ключу.

Полезная статья по резервному копированию и восстановлению PostgreSQL: “How To Backup PostgreSQL Databases on an Ubuntu VPS”

Как настроить Active Directory на Samba 4 на Ubuntu

Начиная с 4 версии, Samba уже вполне подходит для развертывания структуры Active Directory в небольших компаниях.
Хороший цикл статей на английском по настройке инфраструктуры AD при помощи Samba 4:
Part 1: Install Active Directory Infrastructure with SAMBA4 on Ubuntu
Part 2: Manage Samba4 AD Infrastructure from Linux Command Line
Part 3: Manage Samba4 Active Directory Infrastructure from Windows10 via RSAT
Part 4: Manage Samba4 AD Domain Controller DNS and Group Policy from Windows
Part 5: Join an Additional Ubuntu DC to Samba4 AD DC
Part 6: Setup SysVol Replication Across Two Samba4 AD DC with Rsync
Part 7: Create a Shared Directory on Samba AD DC and Map to Windows/Linux Clients
Part 8: Integrate Ubuntu 16.04 to AD as a Domain Member with Samba and Winbind
Part 9: Integrate CentOS 7 Desktop to Samba4 AD as a Domain Member
Part 10: How to Install iRedMail on CentOS 7 for Samba4 AD Integration
Part 11: Integrate iRedMail Services to Samba4 AD DC
Part 12: How to Integrate iRedMail Roundcube with Samba4 AD DC
Part 13: How to Configure Thunderbird with iRedMail for Samba4 AD
Part 14: Integrate Ubuntu 16.04 to Samba4 AD DC with SSSD and Realm
Part 15: Integrate CentOS 7 from Command Line to Samba AD DC as a Domain Member
Part 16: Integrate VMware ESXI Host to Samba4 AD Domain Controller

Microsoft Excel. Узелки на память

1. Чтобы MS Excel корректно использовал сепараторы в CSV, надо в первой строке CSV указать сепаратор директивой “sep=,”

Как восстановить работу директорий пользователей в Confluence

Имеем свеженастроенную пару JIRA 8.2 + Confluence 6.15. В Confluence пользователи должны браться из директории пользователей JIRA, но из-за неправильной настройки никто залогиниться не может. Имеем криворукого админа (меня то есть), который неловким движением руки отключил внутреннюю директорию Confluence, где, разумеется, и были все пользователи с админскими правами. Картинка “Приехали”.

Чинится проблема редактированием доступа к директориям пользователей напрямую в базе Posgtres:

rat@atlassian:~$ sudo -u postgres psql
[sudo] password for rat: 
psql (9.5.17)
Type "help" for help.
postgres=# \list
                                   List of databases
    Name    |   Owner    | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+------------+----------+-------------+-------------+-----------------------
 confluence | confluence | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 jira       | jira       | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres   | postgres   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

postgres=# \connect confluence
You are now connected to database "confluence" as user "postgres".
confluence=# select id, directory_name, active from cwd_directory;
   id    |        directory_name         | active 
---------+-------------------------------+--------
  294913 | Confluence Internal Directory | F
 1736705 | JIRA Server                   | T
(2 rows)

confluence=# update cwd_directory set active='T' where id=294913;
UPDATE 1

confluence=# select id, directory_name, active from cwd_directory;
   id    |        directory_name         | active 
---------+-------------------------------+--------
 1736705 | JIRA Server                   | T
  294913 | Confluence Internal Directory | T
(2 rows)

confluence=# \quit

Осталось перезапустить Confluence и правильно настроить директории пользователей.

Доступ к удаленному FTPS-серверу в пакетном режиме

Для коммуникации с ftps-сервером хорошо подходит утилита lftp, которая поддерживает SSL в отличие от стандартной утилиты ftp. Есть поддержка считывания данных из ~/.netrc, так что в скриптах логин и пароль светить не придется.
Вызов работы из скрипта выглядит примерно так (Ubuntu Linux -> Microsoft FTP Server):

/usr/bin/lftp -e "set ftp:passive-mode off;
                  set ftp:ssl-protect-data true;
                  set ftp:ssl-force true;
                  set ssl:verify-certificate no;
                  lcd /data/processing/out;
                  cd /;
                  mput *;
                  bye" ftps.domain.tld

Установка NextCloud на Ubuntu 16.04 (Apache2, MariaDB)

Для небольшой компании установил NextCloud в качестве точки обмена со сторонней бухгалтерией и бизнес-партнерами. До этого они обменивались документами по электронной почте, что, учитывая требования GDPR, создавало сложности.
Установка почти полностью делалась по статье “Install NextCloud On Ubuntu 16.04 LTS With Apache2, MariaDB, PHP 7.1 And Let’s Encrypt SSL/TLS”, за мелкими исключениями.
В моем случае сервер находится на нестандартном порту (порт прокидывается за NAT, 8443->443), поэтому использовать сертификат Let’s Encrypt не получится, для запроса сертификата веб-сайт должен быть доступен извне по портам 80/tcp и 443/tcp. Использовался самоподписанный сертификат SSL/TLS.
В сети много инструкций по настройке NextCloud в связке с Nginx, но я несколько недолюбливаю этот отличный веб-сервер за его головоломные файлы конфигурации.
Сам сервер развернут в виде LXC-контейнера для повышения уровня изоляции данных. В качестве базы данных – MariaDB.

$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install apache2

Сразу отключим листинг директорий:
$ sudo sed -i "s/Options Indexes FollowSymLinks/Options FollowSymLinks/" /etc/apache2/apache2.conf
$ sudo systemctl stop apache2.service
$ sudo systemctl start apache2.service
$ sudo systemctl enable apache2.service

База данных:
$ sudo apt-get install mariadb-server mariadb-client
$ sudo mysql_secure_installation

When prompted, answer the questions below by following the guide.

Enter current password for root (enter for none): Just press the Enter
Set root password? [Y/n]: Y
New password: Enter password
Re-enter new password: Repeat password
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y

Рестартуем сервер MariaDB:
$ sudo systemctl restart mysql.service

PHP 7.1 не входит в поставку Ubuntu 16.04, ставим из стороннего репозитория:
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
$ sudo apt-get install php7.1 libapache2-mod-php7.1 php7.1-common libapache2-mod-php7.1 php7.1-mbstring php7.1-xmlrpc php7.1-soap php-apcu php-smbclient php7.1-ldap php-redis php7.1-gd php7.1-xml php7.1-intl php7.1-json php-imagick php7.1-mysql php7.1-cli php7.1-mcrypt php7.1-ldap php7.1-zip php7.1-curl

Немного правим дефолтные параметры PHP-FPM:
$ sudo vim /etc/php/7.1/apache2/php.ini
file_uploads = On
allow_url_fopen = On
memory_limit = 512M
upload_max_filesize = 256M
max_execution_time = 360
date.timezone = Europe/Riga

Настройка базы:
$ sudo mysql -u root -p
CREATE DATABASE nextcloud;
CREATE USER 'nextclouduser'@'localhost' IDENTIFIED BY 'new_password_here';
GRANT ALL ON nextcloud.* TO 'nextclouduser'@'localhost' IDENTIFIED BY 'user_password_here' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;

Скачиваем и устанавливаем NextCloud:
$ wget https://download.nextcloud.com/server/releases/latetst.zip
$ unzip latest.zip
$ sudo mv nextcloud /var/www/html/nextcloud/
$ sudo chown -R www-data:www-data /var/www/html/nextcloud/
$ sudo chmod -R 755 /var/www/html/nextcloud/

Конфиг нового виртуального хоста, нужен только для начальной отладки:
$ sudo vim /etc/apache2/sites-available/nextcloud.conf

<VirtualHost *:80>
ServerAdmin admin@domain.tld
DocumentRoot /var/www/html/nextcloud/
ServerName office.domain.tld
ServerAlias doc.domain.tld
Alias /nextcloud "/var/www/html/nextcloud/"
<Directory /var/www/html/nextcloud/>
Options +FollowSymlinks
AllowOverride All
Require all granted
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Включим необходимые модули и рестартуем Apache:
$ sudo a2ensite nextcloud.conf
$ sudo a2enmod rewrite
$ sudo a2enmod headers
$ sudo a2enmod env
$ sudo a2enmod dir
$ sudo a2enmod mime
$ sudo systemctl restart apache2.service

Генерируем сертификат RSA со сроком 10 лет:
$ sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Подробная информация по параметрам в статье на Digital Ocean: “How To Create a Self-Signed SSL Certificate for Apache in Ubuntu 16.04”.

Создаем рабочий конфиг виртуального хоста:
$ sudo vim /etc/apache2/sites-available/nextcloud-le-ssl.conf

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin admin@domain.tld
DocumentRoot /var/www/html/nextcloud/
ServerName office.domain.tld
ServerAlias doc.domain.tld

Alias /nextcloud "/var/www/html/nextcloud/"

<Directory /var/www/html/nextcloud/>
Options +FollowSymlinks
AllowOverride All
Require all granted
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

</VirtualHost>
</IfModule>

Рестартуем Apache, заходим через веб на сервер, заканчиваем настройку:
$ sudo systemctl restart apache2.service

После первоначальной настройки необходимо сделать еще несколько полезных вещей:
1. Настроить SMTP-сервер для отправки почты:
Settings -> Administration -> Basic settings -> Email server

2. Включить кеширование данных, для небольшого сервера достаточно APCu:
$ sudo vim /var/www/html/nextcloud/config/config.php
'memcache.local' => '\OC\Memcache\APCu',

3. Отключить быстрый набор контактов, это повышает приватность данных:
Settings -> Administration -> Sharing -> [ ]Allow username autocompletion in share dialog…

4. Ускорить чистку удаленных файлов.
Дело в том, что по умолчанию удаленные файлы хранятся как минимум 30 дней и удаляются из “корзины” только если в систем осталось мало места на диске. Нам это совсем не нужно, пусть удаляются через 35 дней:
$ sudo vim /var/www/html/nextcloud/config/config.php
'trashbin_retention_obligation' => '30, 35',

Enjoy!

Быстро перекодировать пачку видео для просмотра на iPad – ffmpeg в помощь

На Маке понадобилось залить сезон сериала жене на iPad. Тратить деньги на программы перекодирования видео как-то не хочется. Вспоминаем про старый добрый ffmpeg:
$ brew install ffmpeg
$ for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done

Для *.mkv иногда достаточно сменить контейнер. Операция происходит очень быстро, но есть шанс, что на планшете не заработает.
$ for i in *.mkv; do ffmpeg -i "$i" -codec copy "${i%.*}.mp4"; done

Получившиеся файлы слегка переименовываем – ставим индекс серии в начало названия, так как проигрыватель на iOS сильно обрезает имена файлов. Заливаем на устройство через iTunes.

Еще парочку нюансов:
1. Иногда при перекодировании avi в mp4 убивается звук. Можно попробовать звуковую дорожку просто скопировать:
$ for i in *.avi; do ffmpeg -i "$i" -acodec copy "${i%.*}.mp4"; done
2. Теги mp4 частенько не совпадают с названием файла, можно поправить:
$ for i in *.mp4; do mp4tags -s `basename "$i" .mp4` $i; done

Автоматизация резервного копирования сайта по расписанию. FTP

Некоторые провайдеры не дают доступ к размещенным сайтам по SFTP, поэтому всем удобный rsync работать не будет. Придется довольствоваться старым небезопасным ftp. Самый удобный инструмент – wget. Делаем примитивный однострочник:
$ wget --no-passive -r -l 0 -q 0 ftp://isp3.service.tld/web/ -P /tmp; zip -q -r /var/backup/sites/site1/backup_`date +\%Y\%m\%d\%H\%M\%S`.zip /tmp/isp3.service.tld; rm -fr /tmp/isp3.service.tld

Опция --no-passive включает активный режим. В пассивном режиме, который включается по умолчанию, траффик ftp может быть зарезан файерволом. Если все работает без этой опции, то в активном режиме режиме нет необходимости.
Комбинация опций -r -l 0 указывает рекурсивность и неограниченную глубину дерева каталогов.

Как видно, логин и пароль в командной строке отсутствуют. Их, конечно, можно указать как параметры wget, например --user="serviceftp" --password="$uperPa$$w0rd", но лучше так не делать.
Специально для хранения логинов и паролей ftp/http есть файл .netrc. И wget будет читать информацию из этого файла при получении запроса авторизации от сервера.

$ touch ~/.netrc
$ chmod 600 ~/.netrc
$ echo 'machine isp3.service.tld login serviceftp password $uperPa$$w0rd' >> ~/.netrc

Сайт в моем случае статичный и обновляется редко. Резервные копии нужны на случай, если пользователь сайт поломает, а у провайдера не будет рабочего бекапа. Бекап Шредингера, так сказать.

Добавим такую строчку в crontab (5:30 каждого первого числа):

30 5 1 * * /usr/bin/wget --no-passive -r -l 0 -q 0 ftp://isp3.service.tld/web/ -P /tmp; zip -q -r /var/backup/sites/site1/backup_`date +\%Y\%m\%d\%H\%M\%S`.zip /tmp/isp3.service.tld;rm -fr /tmp/isp3.service.tld > /dev/null

Debian 8 и старое ядро OpenVZ

UPD: конфигурация нерабочая – сервисы не стартуют! Так как проблема заключается в старой версии vzctl, а менять ядро на хост-системе никто не будет, то от идеи Debian 8 со старым ядром придется отказаться.

В далекой-далекой Галактике… не, не так… на далеком-далеком хостинге, на древнем-древнем сервере…
Короче, на действительно древнем сервере, корый я настраивал для клиента в 2009 году и обновлял в 2014, понадобилось поднять для экспериментов контейнер OpenVZ. Точнее, он уже был создан в 2014 на шаблоне Debian 6.0, но с тех пор не обновлялся. Самое простое – уничтожить контейнер и создать заново с новым шаблоном. Здесь надо быть особенно внимательным – Debian 9 со старым ядром (2.6.32-5-openvz-amd64 #1 SMP Tue May 13 17:16:50 UTC 2014 x86_64 GNU/Linux) не дружит(!) и напрочь теряет сеть. Поэтому ставим Debian 8, для работы более чем достаточно.
$ sudo /usr/sbin/vzctl stop 1009
$ sudo /usr/sbin/vzctl destroy 1009
$ wget http://download.openvz.org/template/precreated/debian-8.0-x86_64-minimal.tar.gz
$ sudo mv debian-8.0-x86_64* /var/lib/vz/template/cache/
$ sudo /usr/sbin/vzctl create 1009 --ostemplate debian-8.0-x86_64-minimal

Старый конфиг сохраняем, необходимо только поменять название шаблона (OSTEMPLATE=”debian-6.0-amd64-minimal” -> OSTEMPLATE=”debian-8.0-x86_64-minimal”)

Пытаемся запустить и обламываемся:
$ sudo /usr/sbin/vzctl start 1009
Starting container ...
Container is unmounted
Container is mounted
Failed to set upstart as init: No such file or directory

Проблема в том, что vzctl пропускает init и использует upstart напрямую, а его у нас в системе нет.
Не мешает добавить DNS-сервер в /etc/resolv.conf, если там пусто. 8.8.8.8 подойдет.
$ sudo -i
# cd /var/lib/vz/root/1009
# chroot .
# vim /etc/resolv.conf
# apt-get update
# apt-get install upstart

Теперь другое дело:
$ sudo /usr/sbin/vzctl start 1009
Starting container ...
Container is unmounted
Container is mounted
Adding IP address(es): 123.45.67.89
Setting CPU units: 1000
Container start in progress...

Автоматизация для бедных. Часть 3 – обработка входящей почты. Fetchmail, procmail и другие

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

Выбор связки fetchmail / procmail в качестве решения вполне очевиден.
$ sudo apt-get install fetchmail procmail incron

Дальше начинается интересное – fetchmail не работает для отдельного пользователя, если нет глобальной конфигурации в /etc/fetchmailrc. И права тоже должны быть установлены корректно.

$ ls -l /etc/fetchmailrc
-rw------- 1 fetchmail root 271 Jan 11 22:08 /etc/fetchmailrc

Нам необходимо забирать всю почту, протокол pop3s с использованием SSL, отдать на обработку юзеру mailman. Период обращения к почтовому серверу – 3 минуты:

$ sudo cat /etc/fetchmailrc
#### .fetchmailrc

set daemon 180
set logfile /var/log/fetchmail.log

poll mail.domail.tld proto POP3
user "robot@domain.tld" pass "password" is "mailman" preconnect "date >> /var/log/fetchmail.log"
ssl
fetchall
no keep
no rewrite
mda "/usr/bin/procmail -f %F -d %T";

На стороне mailman находится конфигурация procmail. Сохраняем все входящие сообщения и отдельно сохраняем вложения, передавая их uudeview для распаковки:
$ cat .procmailrc
:0
*^content-Type:
{
:0c
$HOME/emailbackup
:0fw
| uudeview -i +a +o -p $HOME/attachments -
}

Каталоги ~/emailbackup и ~/attachments необходимо создать заранее.

После создания файлов на диске incron их положит на сервер. Это гораздо быстрее и эффективнее, чем обработка по crontab.
$ incrontab -l
/home/mailman/attachments/ IN_CREATE mv $@/$# /mnt/files/INBOX/

Подробная информация по incron на IBM Developer: “Планирование операций обработки событий в файловой системе”

Теперь начинаются костыли.
Иногда, по какой-то непонятной причине, incron не перемещает файлы на сервер. Приходится их подбирать по расписанию, каждые 5 минут:
*/5 * * * * /usr/bin/find /home/mailman/attachments -mmin +1 -type f -exec mv '{}' /mnt/files/INBOX/ \; > /dev/null

Еще один костыль для латышского языка. Файлы с неправильными названиями на национальных языках иногда не обрабатываются скриптами. Есть замечательная утилита для переименования файлов со слетевшими кодировками:
*/5 * * * * /usr/bin/find /home/mailman/attachments -mmin +1 -type f -exec /usr/bin/convmv -f cp1257 -t utf8 -r --notest '{}' \; > /dev/null

Может, не самое оптимальное решение, но работает. Буду рад советам и предложениям.

←Older