sysmerge IT

26 дек. 2018 г.

Roundcube SMTP ошибка (550): Невозможно установить отправителя (Access denied - Invalid HELO name (See RFC2821 4.1.3))

Centos 7. В roundcube при попытке отправить письмо на любой адрес появляется ошибка "SMTP ошибка (550): Невозможно установить отправителя "test@mail.com" (Access denied - Invalid HELO name (See RFC2821 4.1.3)) ".

Ошибка говорит сама за себя - отсутствует helo. Для решения проблемы в конфигурационном файле /etc/roundcubemail/defaults.inc.php есть соответствующий параметр $config['smtp_helo_host'], который в нашем случае наверняка пуст. Пропишите туда hostname отправителя почты.
31 окт. 2018 г.

SystemRescueCd настройка сети

Опишу быстрый способ поднять доступ в сеть из  SystemRescueCd.

Поднимаем интерфейс с ip адресом сервера
[root@login ~]# ifconfig eth0 95.198.165.92 netmask 255.255.252.0
Проверяем таблицу маршрутизации
[root@login ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
95.198.164.0    0.0.0.0         255.255.252.0   U     0    0        0 eth0

Нам необходимо добавить маршрут по-умолчанию на шлюз с интерфейса eth0 для доступа наружу:

[root@login ~]# route add default gw 185.198.164.1 eth0

[root@login ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         95.198.164.1 0.0.0.0         UG    100    0        0 eth0
95.198.164.0    0.0.0.0         255.255.252.0   U     0    0        0 eth0
Готово, сеть работает.

[root@login ~]# ping google.com
PING google.com (216.58.215.110) 56(84) bytes of data.
64 bytes from waw02s17-in-f14.1e100.net (216.58.215.110): icmp_seq=1 ttl=54 time=71.1 ms
64 bytes from waw02s17-in-f14.1e100.net (216.58.215.110): icmp_seq=2 ttl=54 time=73.6 ms
64 bytes from waw02s17-in-f14.1e100.net (216.58.215.110): icmp_seq=3 ttl=54 time=70.9 ms
22 июл. 2018 г.

Настройка twemproxy (nutcracker) на Debian 8

twemproxy (или как он еще называется nutcracker) - разработка Twitter, представляет из себя прокси для Memcached или Redis. В данном примере мы будет проксировать именно к нескольким Redis-серверам. Особенностью twemproxy является встроенный шардинг (шардинг, по простому, когда данные, хранящиеся на редиса-бекендах, распределены между каждым бекендом, распределение выполняется по выбранному алгоритму). Шардинг позволит сократить запросы к Redis-бекендам, тем самым решая проблемы горизонтального масштабирования.

Кстати, на данный момент сам Redis уже вполне неплохо умеет в Redis-cluster, который сам делает шардинг, умеет в замену слотов, перемещение хеш-слотов, реплики и тд. Но речь не об этом сейчас.

Итак, изначально нам нужно установить несколько Redis серверов.
Качаем свежий релиз отсюда. Распковываем и идем в /redis-stable/utils:
root@test:~/redis-stable/utils# bash install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Success!
Starting Redis server...
Installation successful!
root@test:~/redis-stable/utils# systemctl start redis_6379
root@test:~/redis-stable/utils# systemctl enable redis_6379
Synchronizing state for redis_6379.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d redis_6379 defaults
Executing /usr/sbin/update-rc.d redis_6379 enable
root@test:~/redis-stable/utils# bash install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 6380
Please select the redis config file name [/etc/redis/6380.conf]
Selected default - /etc/redis/6380.conf
Please select the redis log file name [/var/log/redis_6380.log]
Selected default - /var/log/redis_6380.log
Please select the data directory for this instance [/var/lib/redis/6380]
Selected default - /var/lib/redis/6380
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port           : 6380
Config file    : /etc/redis/6380.conf
Log file       : /var/log/redis_6380.log
Data dir       : /var/lib/redis/6380
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6380.conf => /etc/init.d/redis_6380
Installing service...
Success!
Starting Redis server...
Installation successful!
root@test:~/redis-stable/utils#
root@test:~/redis-stable/utils# systemctl start redis_6380
root@test:~/redis-stable/utils# systemctl enable redis_6380
Synchronizing state for redis_6380.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d redis_6380 defaults
Executing /usr/sbin/update-rc.d redis_6380 enable
root@test:~/redis-stable/utils# netstat -ln | grep redis
root@test:~/redis-stable/utils# netstat -apln | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      9214/redis-server 1
tcp        0      0 127.0.0.1:6380          0.0.0.0:*               LISTEN      9291/redis-server 1

На примере выше мы подняли 2 редис сервера, можно больше.

Устанавливаем  twemproxy:
root@test:~/# apt-get install nutcracker
В конфиг /etc/nutcracker/nutcracker.yml добавляем следующее:
redisserver:
  listen: 10.10.10.10:65123
  hash: fnv1a_64
  hash_tag: "{}"
  distribution: ketama
  auto_eject_hosts: false
  timeout: 400
  redis: true
  servers:
   - 127.0.0.1:6379:1 redis1
   - 127.0.0.1:6380:1 redis2

Запускаем
service nutcracker start
Итак, наш прокси слушает внешний IP 10.10.10.10 порт 65123, проксируя соединения к двум редис серверам, которые не имеют доступа наружу. У обоих одинаковый приоритет. Автоматическое извлечение редис-сервера в случае ошибок отключено.

Статистику twemproxy  выдает на 22222 порту в формате JSON.
6 июл. 2018 г.

Ispmanager5 - Доступ к панели заблокирован администратором. Возможно панель в данный момент обновляется

Обратился клиент с проблемой с панелью Ispmanager5, щеголяющей надписью "Доступ к панели заблокирован администратором. Возможно панель в данный момент обновляется ". Правда никаких обновлений при этом в системе запущено не было.
Попытки прибить ISPManager5 панель с помощью
# killall -9 core
или
# /usr/local/mgr5/sbin/mgrctl -m ispmgr exit
 Никакого результата не принесли.

--unlock тоже как-то не подействовал
# /usr/local/mgr5/sbin/mgrctl --unlock ispmgr

При этом сама панель особо о своих заботах не делилась и ошибок нет. В итоге решено было сделать вот так
# rm /usr/local/mgr5/tmp/ispmgr.lock

 И панель снова с нами.
9 апр. 2018 г.

Настройка django + supervisor gunicorn и daphne

Имеется джанго приложение, отлично себе работает на gunicorn, но потребовалось добавить туда чат и в качестве бекенда к нему использовать вебсокет сервер Daphne. Ну и конечно все это нужно как-то поднимать, этим занимается supervisor.  Для начала что из себя представляет конфиг nginx: 

upstream gunicorn_server {
  server unix:/app/run/gunicorn.sock fail_timeout=0;
}
upstream daphne {
        server 127.0.0.1:8001;
}
server {
        server_name localhost;
        client_max_body_size 4G;
        charset UTF-8;
        index index.html index.php;
        disable_symlinks if_not_owner from=$root_path;
        access_log /var/www/httpd-logs/app.access.log;
        error_log /var/www/httpd-logs/app.error.log notice;
        location /static/ {
        alias   /app/static_cdn/;
        }
        location /media {
        alias   /app/media_cdn/;
        }
        listen 127.0.0.1:80;
        location / {
                location ~ [^/]\.ph(p\d*|tml)$ {
                        try_files /does_not_exists @fallback;
                }
                location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
                        try_files $uri $uri/ @fallback;
                }
                location / {
                        try_files /does_not_exists @fallback;
                }
        }
        location /chat/ {
                proxy_pass http://daphne;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Port $server_port;
                add_header X-Backend "daphne";
        }
        location @fallback {
                proxy_pass http://gunicorn_server;
                proxy_http_version 1.1;
                proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Port $server_port;
                add_header X-Backend "Gunicorn";
                access_log off;
        }
}
Ну, выглядит все предельно просто, имеется 2 апстрима на gunicorn и daphne, куда мы, по локейшенам, раскидываем запросы.

Теперь нужно настроить supervisor для запуска нужных нам приложений. Начнем с daphne. Создаем конфиг в /etc/supervisor.d/daphne.conf :
# ====================================================
[program:daphne]
user = app_user
directory = /app/src
environment = DJANGO_SETTINGS_MODULE="myapp.settings.production",
command = /app/bin/daphne -b 0.0.0.0 -p 8001 myapp.asgi:channel_layer
autorestart = true
stderr_logfile = /app/logs/daphne_errors.log
# ===============================================
Вы уже должны были заметить, что приложение мое носит незатейливое имя MYAPP, соответственно пути к модулям получаются что-то вроде myapp.settings.production.

Теперь то же самое проделаем с gunicorn, это будет /etc/supervisord/gunicorn.conf:

# ===============================================
[program:gunicorn]
command = /app/bin/gunicorn_start 
user = app_user                                                     
stdout_logfile = /app/logs/gunicorn_supervisor.log
redirect_stderr = true                                             
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8
# ===============================================
Теперь осталось запустить воркеры питона для непосредственной работы, воркеров сделаем 2 штуки, можно в одном файле конфига супервайзора, разделив их:

# ====================================================
[program:worker-first]
user = app_user
directory = /app/src
environment = DJANGO_SETTINGS_MODULE="myapp.settings.production",
command = /app/bin/python3 manage.py runworker
autorestart = true
stderr_logfile = /app/logs/worker.log
# ===============================================
# ====================================================
[program:worker-second]
user = app_user
directory = /app/src
environment = DJANGO_SETTINGS_MODULE="myapp.settings.production",
command = /app/bin/python3 manage.py runworker
autorestart = true
stderr_logfile = /app/logs/worker.log
# ===============================================

Ну и все, запускаем supervisor, проверяем, что он поднял все нужные нам сервисы и можно тестить приложение

5 апр. 2018 г.

HTTPS на Blogger платформе

Ого, на дворе 2018 и в Гугле таки решили, что пора включить на платформе Blogger поддержку HTTPS не только для гуглосабдоменов, но и для доменов второго уровня. Сертификаты выдаются LetsEncrypt'ом и абсолютны бесплатные, что круто.

Включить можно в НАСТРОЙКА - ОСНОВНОЕ. Для настройки так же доступен режим автоматического редиректа с http на https.

ТЕХНОЛОГИИ
13 мар. 2018 г.

ISPManager 5: domain already exists. Удаление домена из sqlite db

Бывает такая неприятная вещь при работе с Ispmanager5, что удалив домен из панели внезапно указывается, что назад он уже не добавляется, потому что уже существует. Существует он в базе данных sqlite, где хранит все данные ispmanager, откуда, вероятно, по какой-то причине не смог удалиться. В нашем случае случилось так, что половина доменов была настроена на дочерних днс, настройки всего это добра были сделаны вручную через конфиг named, в результате эти доменные имена в самой панели не отображались и при удалении www-домена запись о DNS домене так и осталась в bd. Давайте удалим.
Заходим в нужную бд

sqlite3 /usr/local/mgr5/etc/ispmgr.db
Смотрим, что за таблицы у нас имеются:

sqlite> .tables
aps                     email_forward           phpparam_available   
aps_assign              email_notify_settings   preset               
aps_entry               email_options           preset_props         
backup_queue            email_responder         props                
core_blacklist          email_whitelist         slave_ns             
core_funcs              emaildomain             sociallink           
core_members            emaildomain_options     socialrequest        
core_restorepasswd      emaildomain_props       source               
core_slaveserver        emailfilter             sslcert_csr          
core_users              ftp_users               totp                 
core_usrparam           geoip_country           userprops            
db_assign               geoip_locale            users                
db_configassign         global_index            usrquota             
db_mysql_servers        grpquota                webdisk_settings     
db_server               history_users           webdomain            
db_users_password       ispfeatures             webdomain_access_dir 
docker_container        isppackages             webdomain_access_users
dockerprops             isppkginfo              webdomain_alias      
domain                  letsencrypt_log         webdomain_error      
domain_auto             letsencrypt_ssl         webdomain_ipaddr     
email                   mfilteraction           webdomain_redirect   
email_alias             mfiltercond          
email_blacklist         mfiltercondvals

Нас интересует таблица webdomain и domain. Там соответственно хранятся записи о www-доменах и dns доменах. Проверим, правда ли домена нет в "www-домены":

sqlite> Select * from webdomain where name like '%domain%';
Таки нет.
Проверим теперь наличие его в "доменных именах":

sqlite> Select * from domain where name like '%domain%';
24|domain.ru|domain.ru||slave
А вот и он, родимый, который мешает передобавить.
Его id нам известен, осталось удалить:
sqlite> delete from domain where id like 24;
Теперь домен можно передобавлять

25 февр. 2018 г.

Centos: grub file system compatibility error, cannot read whole file

При переносе данных с одного диска на другой (по сути замена дискового устройства на ВПС),

иногда приходится сталкиваться с системами, на которых еще установлен grub legacy.

Его ручная установка:
    # grub
    grub>root (hd1,0)
    grub>setup (hd1)
    checking if "/boot/grub/stage1" existes... no
    checking if "/grub/stage1" existes... no
    Error 14: Filesystem compatibility error, cannot read whole file
заканчивается с ошибкой "Error 14: Filesystem compatibility error, cannot read whole file".
Причем, обе файловые системы под /boot являются ext4. Дело в том, что при создании нового экземляра ext4 с помощью mkfs.ext4 на новом диске по умолчанию используются новые фичи файловой системы(в частности metadata_csum и 64 bit features), которые и ломают установку grub legacy, данные опции не поддерживающий.

Как самый ленивый - просто разметил в ext3. А вообще пора бы и на grub2 переходить.
4 февр. 2018 г.

3proxy - конфиг прокси сервера с вышестоящим parent proxy

 Пример конфига для 3proxy, где используются 2 юзера, с лимитированным трафиком, сам прокси при этом имеет вышестоящий прокси, который в итоге является "исходящим".

daemon

nserver 8.8.8.8
nserver 77.88.8.8

nscache 65536

timeouts 1 5 30 60 180 1800 15 60

log /var/log/3proxy.log D
logformat "- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"

internal 217.10.1.1 #Ip сервера с промежуточным прокси, где, собственно, находится этот конфиг, не обязательная настройка

users user1:CL:pwd1
users user2:CL:pwd2

auth strong

maxconn 300

counter "/var/log/3proxy.3cf" D "/var/log/traf"
countin "1/user1" M 1000 user1 * * * *  #1gb трафика в месяц для user1

allow user1
parent 1000 http us-s1.geosurf.io 11111 #первый исходящий прокси
proxy -p8001 -t
flush

allow user2
parent 1000 http us-s2.geosurf.io 22222 #второй исходящий прокси
proxy -p8002 -t
flush

По сути такая схема может применяться для перепродажи прокси, как вариант
12 янв. 2018 г.

goaccess анализатор логов - настройка онлайн мониторинга трафика на сайтах

Goaccess.io - анализатор логов, который в итоге выдает нагора симпатичные графики по всевозможным параметрам, которые будут спаршены с логов соответственно (юзерагенты, ипишки, запросы, виртуалхосты, реферы и тд). Более того, кроме вывода в консоль позволяет генерировать выхлоп в .html, например, и даже быть динамическим, используя вебсокеты для обновления данных.
Итак, сделаем простую настройку. Будем считать, что у нас несколько сайтов и, соответственно, несколько логов для каждого из них. Goaccess умеет кушать несколько логов.
В первую очередь нужно будет чуть-чуть подправить стандартный log_format nginx, создадим такой:
log_format goaccess '$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
По сути он выглядит как дефолтный, только мы добавили туда вывод имени хоста - $host. Он пригодится нам для разделения результата парсинга логов по виртуалхостам.
Как устанавливать сам goaccess описывать не буду, более того для популярных дистрибутивов данное По можно ставить прямо с пакетного менеджера. Если что инструкции тут.
У нас система Centos 7. Глобальный конфиг Goaccess лежит тут /etc/goaccess.conf. Нам нужно внести туда несколько правок, настроив, соответственно, формат времени из логов, формат даты, и сам формат лога, то есть шаблон, по которому Goaccess будет парсить строки из логов.
Тут нам поможет один неплохой скрипт - https://github.com/stockrt/nginx2goaccess, который
ест на входе формат логов nginx и выдает нам нужные параметры для конфига goaccess.
# ./nginx2goaccess.sh '$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'

- Generated goaccess config:
time-format %T
date-format %d/%b/%Y
log_format %v %h - %^ [%d:%t %^] "%r" %s %b "%R" "%u"
Соответственно используем эти настройки в goaccess.conf, а так же перечисляем файлы логов для парсинга:
log-file /var/log/nginx/site1.access
log-file /var/log/nginx/site2.access
log-file /var/log/nginx/site3.access
Стоит отметить, что имеются предопределенные шаблоны стандартных форматов логов, времени и даты для различных серверных решений, которых вам может вполне хватить .
И запускаем goaccess в виде демона, с динамическим обновлением, который будет писать html в один из сайтов, сюда, например,  /var/www/site1.ru/report.html:
 goaccess  -o  /var/www/site1.ru/report.html --real-time-html  --daemon
Внезапно можем обнаружить, что автоматическая обновление данных не работает, а слева лампочка не горит зеленым (сообщающая о том, что вебсокет работает). Проверяем, слушается ли порт 7890
# netstat -alpn | grep 7890
tcp        0      0 0.0.0.0:7890            0.0.0.0:*               LISTEN      20602/goaccess 
Значит проблема  в том, что порт закрыт. В iptables суем
iptables-A INPUT -p tcp -m state --state NEW -m tcp --dport 7890 -j ACCEPT
Оп, и все заработало.