пятница, 13 декабря 2019 г.

Nginx 403 error directory index of is forbidden, client 1.2.3.4

There wasn't index index.php; in config file in my case.

https://www.ionos.com/community/server-cloud-infrastructure/nginx/solve-an-nginx-403-forbidden-error/

Nginx php in subdirectory

Wordpress is in sub-directory nested, and blog address is domain.tld/nested

useful links
https://serversforhackers.com/c/nginx-php-in-subdirectory
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

server {
  listen 80 default_server; 
  listen [::]:80 default_server; 
  root /var/www/top/public; 
  index index.html index.htm index.php; 
  server_name _; 

  location / { 
    try_files $uri $uri/ /index.php$is_args$args; 
  } 

  location /nested { 
    alias /var/www/nested/public; 
    try_files $uri $uri/ @nested; 

    location ~ \.php$ { 
      index index.php;
      include snippets/fastcgi-php.conf; 
      fastcgi_param SCRIPT_FILENAME $request_filename; 
      fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; 
    } 
  } 
  location @nested { 
    rewrite /nested/(.*)$ /nested/index.php?/$1 last; 
  } 
  location ~ \.php$ { 
    include snippets/fastcgi-php.conf; 
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; 
  }
}

Short explanations.

1) root of blog is not domain as domain.tld, but it is address location as domain.tld/nested. So there should be rewrite rule:

    rewrite /nested/(.*)$ /nested/index.php?/$1 last;

2) We use alias, because of explanation from one of useful links below.
Note that distinction - with that alias, Nginx does NOT look for files within /var/www/nested/public/nested/foo, like it would with the root directive.

3) We use $request_filename instead of $document_root$fastcgi_script_name because of next explanation.
If you use the alias directive with $document_root$fastcgi_script_name, $document_root$fastcgi_script_name will return the wrong path.
Request /api/testing.php:
  • $document_root$fastcgi_script_name == /app/www//api/testing.php
  • $request_filename == /app/www/testing.php
Request /api/:
  • $document_root$fastcgi_script_name == /app/www//api/index.php
  • $request_filename == /app/www/index.php
4) And if you use $request_filename, you should set index using index directive, fastcgi_index will not work.
It means index index.php; in location

воскресенье, 3 ноября 2019 г.

понедельник, 28 октября 2019 г.

Linux Ubuntu 18.04 Use redis for cache pages and PHP sessions storage

apt update -y && apt install redis-server php-redis

/etc/php/7.2/fpm/pool.d/user.conf
php_admin_value[session.save_handler] = redis
php_admin_value[session.save_path] = "tcp://127.0.0.1:6379?persistent=1&weight=1&database=2"

phpinfo should display redis info on the page.
There is link https://github.com/phpredis/phpredis#php-session-handler for save_path parameters

The checking script is 

<?php

  $redisinstance = new Redis();
  $redisinstance->connect("127.0.0.1", 6379);
  $result = $redisinstance->get("test");

  if ($result) {
      echo $result;
  } else {
      echo "No matching key found. Refresh the browser to add it!";
      $redisinstance->set("test", "Successfully retrieved the data!") or die("Couldn't save anything to redis...");
  }
?>
After refreshing page

redis-cli
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> keys "*"
1) "test"
127.0.0.1:6379> get "test"
"Successfully retrieved the data!"

пятница, 25 октября 2019 г.

Nginx inclusive locations processing

https://habr.com/ru/company/oleg-bunin/blog/313666/

Short explanation afterwards

https://www.zagirov.name/post/nginx-config/

manual - http://nginx.org/ru/docs/http/ngx_http_core_module.html#location

Example: how to open phpinfo.php only for 1.2.3.4 address

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/dev/shm/php-user72.sock;                
                deny all;
        }

        location ^~ /phpinfo {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/dev/shm/php-user72.sock;

                allow 1.2.3.4;
                deny all;
        }

Prefix location with ^~ disables first regexp location.

четверг, 24 октября 2019 г.

Linux Ububntu 18.04 Use memcached for PHP session storage

https://devdocs.magento.com/guides/v2.3/config-guide/memcache/memcache_ubuntu.html

apt update -y && apt install php-memcached memcached
/etc/php/7.2/fpm/php.ini
session.save_handler = "memcached"
session.save_path = "127.0.0.1:11211"

or /etc/php/7.2/fpm/pool.d/user.conf
php_admin_value[session.save_path] = '127.0.0.1:11211'
php_admin_value[session.save_handler] = 'memcached'

phpinfo should display memcached info on the page.

Check working with a script cache-test.php

PHP Nginx error "No input file specified." display on a page, and FastCGI sent in stderr: "Unable to open primary script: *.php (Operation not permitted)" in nginx log

/var/log/nginx/error.log

FastCGI sent in stderr: "Unable to open primary script: /var/www/html/phpinfo.php (Operation not permitted)

Don't forget to check open_basedir parameter

fastcgi_param PHP_ADMIN_VALUE   "open_basedir=/var/www/html/:/tmp/";

среда, 23 октября 2019 г.

Nginx testing proxy_cache_valid parameter

Firstly, I created proxy pass for the site. Test location is there for testing cache.

# the site
http {
    ...
    proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
}
server {
    listen 8080;
    ...
    access_log /var/log/nginx/access.log;
    location /test {
        return 200 “It’s now $time_local\n”;
    }
}
# the proxy
server {
    listen 80 default_server;
    root /var/www/;
    index index.html index.htm;

    server_name example.com;

    charset utf-8;

    location / {
        include proxy_params;
        proxy_pass http://localhost:8080;
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_cache_valid 200 15s;
    }
}
proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

The cache server is already confgured to cache responses with status code 200 for 15 seconds. This typically results in cache updates every 15 or 16 seconds.
proxy_cache_valid 200 15s;
Once per second, we send an HTTP request to the address. The response does not change until the caches on the server expire. This happens every 15 or 16 seconds

$ while sleep 1; do curl http://example.com/test; done
...
It’s now 23/Oct/2019:15:11:12 +0000
It’s now 23/Oct/2019:15:11:12 +0000
It’s now 23/Oct/2019:15:11:12 +0000
It’s now 23/Oct/2019:15:11:28 +0000
It’s now 23/Oct/2019:15:11:28 +0000
It’s now 23/Oct/2019:15:11:28 +0000
^C

We can also inspect the logs on the origin server to confrm that it is receiving
a request only every 15 or 16 seconds

/var/log/nginx/access.log
...
127.0.0.1 - - [23/Oct/2019:15:11:12 +0000] "GET /test HTTP/1.0" 200 38 "-" "curl/7.58.0"
127.0.0.1 - - [23/Oct/2019:15:11:28 +0000] "GET /test HTTP/1.0" 200 38 "-" "curl/7.58.0"

Apache2.4 with PHP7.2-FPM on Ubuntu 18.04

I have installed PHP7.2-FPM on Ubuntu 18.04.
For enabling it in Apache2.4, I run those commands.

a2enmod proxy_fcgi
a2enconf php7.2-fpm

PHP sock file is /dev/shm/php-user7.2.sock
So FilesMatch block have to be added to virtualhost.

<FilesMatch \.php$>
  SetHandler "proxy:unix:/dev/shm/php-user7.2.sock|fcgi://localhost"
</FilesMatch>

or replaced it in /etc/apache2/conf-available/php7.2-fpm.conf

<FilesMatch ".+\.ph(ar|p|tml)$">
  SetHandler "proxy:unix:/dev/shm/php-user72.sock|fcgi://localhost"
</FilesMatch>

вторник, 17 сентября 2019 г.

Mysql error ERROR 1064 (42000) You have an error in your SQL syntax

При выгрузке с 10.4 в 10.3 базу возникла ошибка

ERROR 1064 (42000) at line 13263: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMMENT '(DC2Type:json_array)',
Возле COMMENT '(DC2Type:json_array)' была проверка

CHECK (json_valid(`backup_codes`))

При удалении ее из дампа, загрузка прошла успешно

среда, 11 сентября 2019 г.

Git mirror how to

https://stackoverflow.com/questions/3959924/whats-the-difference-between-git-clone-mirror-and-git-clone-bare
Например, нужно создать на отдельном сервере git mirror, чтобы пайплайн обновлял копию репозитория. На сервере создан аккаунт gitlab-runner и ему дан sudo для запуска git
Пусть он будет находится в папке /home/git/gitlab
Тогда для этого клонируем с проект с опцией mirror

sudo git clone --mirror ssh://git@gitlab.domain.org:2233/domain/projects/project1.git

Можно сравнить конфигурацию для mirror и для обычного репозитория с помощью

sudo git config --list

mirror

core.repositoryformatversion=0
core.filemode=true
core.bare=true
remote.origin.url=ssh://git@gitlab.domain.org:2233/domain/projects/project1.git
remote.origin.fetch=+refs/*:refs/*
remote.origin.mirror=true


usual

fetch.recursesubmodules=false
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=ssh://git@gitlab.domain.org:2233/domain/projects/project1.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.issue-4130.remote=origin
branch.issue-4130.merge=refs/heads/issue-4130

Troubleshooting

1) если ошибка

fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

проверить включен ли ssh public key в setting-repository

воскресенье, 8 сентября 2019 г.

RocketChat upgrade from 0.X.X to 1.3.2 version

https://rocket.chat/docs/installation/manual-installation/mongo-replicas/
add replica to config file /etc/mongodb.conf
replication:
  replSetName: "rs01"
systemctl restart mongod
mongo > 
rs.initiate()
Note “ok” value should be 1 in result output
Add this to the Environment line:
export MONGO_OPLOG_URL=mongodb://localhost:27017/local?replSet=rs01
to /etc/init.d/rocketchat in my case

Reload systemd state and restart Rocket.Chat:
systemctl daemon-reload && systemctl restart rocketchat
If you use mongo authentication you have to add roles


воскресенье, 1 сентября 2019 г.

Electrum BTC

Выгрузить приватные ключи

electrum listaddresses | electrum getprivatekeys - > privkeys

Преобразовать файл для загрузки при восстановлении

cp privkeys privkeys.txt
# remove spaces and , " signs
sed -i 's/ //g' privkeys.txt
sed -i 's/,//g' privkeys.txt
sed -i 's/"//g' privkeys.txt
# replace \n to space
awk 1 ORS=' ' privkeys.txt > 1.txt

в результате будет одна строка с ключами через пробел

Восстановить файл кошелька зашифрованный с паролем

cat 1.txt | electrum restore --encrypt_file default_wallet --password PaSSworD -

В результате будет кошелек со статусом imported

вторник, 13 августа 2019 г.

пятница, 2 августа 2019 г.

Linux mariadb doesn't start after upgrading to Debian 10

Mariadb version is 10.3. After upgrading there were errors within service starting:

status
Process: 1232 ExecStartPost=/etc/mysql/debian-start (code=exited, status=203/EXEC)

journal -xe
mariadb.service: Failed at step EXEC spawning /etc/mysql/debian-start: No such file or directory

resolving
https://stackoverflow.com/questions/51317209/mariadb-10-3-8-installation-from-mariadb-repo-missing-files

apt install --reinstall -o Dpkg::Options::="--force-confmiss" mariadb-server-10.3

Configuration file '/etc/mysql/debian-start', does not exist on system.
Installing new config file as you requested.

Configuration file '/etc/mysql/mariadb.conf.d/50-mysqld_safe.cnf', does not exist on system.
Installing new config file as you requested.

Configuration file '/etc/mysql/mariadb.conf.d/50-server.cnf', does not exist on system.
Installing new config file as you requested.

apt install --reinstall -o Dpkg::Options::="--force-confmiss" mysql-common
Configuration file '/etc/mysql/my.cnf', does not exist on system.
Installing new config file as you requested.

Afterwards, there were added requested files.

226 error in LXC container

lxc config set container1 security.nesting true

четверг, 1 августа 2019 г.

Gitlab-ci MR could not retrieve the pipeline status

После релиза, нужно было замержить новую дефолтную ветку в оставшиеся мерж реквесты МР. Хотел автоматизировать и мержил скриптом

source_branch - это новая дефолтная ветка v1.2.3
destiny_branch - это ветка исью issue-1234

local source_branch=$1
local destiny_branch=$2

git fetch origin
git remote set-head origin --auto
git checkout $source_branch
git reset --hard origin/$source_branch
git clean -f -d
git checkout $destiny_branch
git reset --hard origin/$destiny_branch
git merge --no-edit $source_branch
git push origin $destiny_branch

В результате все равно вручную пришлось менять target branch на дефолтную ветку v1.2.3 внутри каждого МР и появилась эта ошибка:

Сould not retrieve the pipeline status 

Также кнопка Merge была не активна.

В конце ошибки предлагалась изучить по ссылке troubleshooting, где пишут что есть такой Bug 

Bug

Merge Request pipeline statuses can't be retrieved when the following occurs:
  1. A Merge Requst is created
  2. The Merge Request is closed
  3. Changes are made in the project
  4. The Merge Request is reopened
To enable the pipeline status to be properly retrieved, close and reopen the Merge Request again.

И предлагают закрыть и переоткрыть МР, что и помогло.
Кнопка Reopen merge request появляется сразу-же на месте Close merge request 
(т.е заходить в закрытые МР и искать этот МР не нужно)


четверг, 25 июля 2019 г.

Linux RabbitMQ-server cluster


https://www.rabbitmq.com/clustering.html
https://kamaok.org.ua/?p=2689
https://blog.flux7.com/blogs/tutorials/how-to-creating-highly-available-message-queues-using-rabbitmq

1) add hostname (do real hostname) between master and slave to /etc/hosts

2) copy /var/lib/rabbitmq/.erlang.cookie from master to slave

systemctl restart rabbitmq-server (on slave)


3) join to cluster

rabbitmqctl stop_app

Stopping rabbit application on node rabbit@<hostname_slave> ...
rabbitmqctl reset

Resetting node rabbit@<hostname_slave> ...

rabbitmqctl join_cluster rabbit@<hostname_slave>

Clustering node rabbit@<hostname_slave> with rabbit@<hostname_master>

rabbitmqctl start_app

Starting node rabbit@<hostname_slave> ...
completed with 0 plugins.


4) check cluster

rabbitmqctl cluster_status

Cluster status of node rabbit@<hostname_slave> ...

[{nodes,[{disc,[rabbit@<hostname_master>,rabbit@<hostname_slave>]}]},

{running_nodes,[rabbit@<hostname_master>,rabbit@<hostname_slave>]},

{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},

{alarms,[{rabbit@<hostname_master>,[]},{rabbit@<hostname_slave>,[]}]}]


5) Configure syncing queues police between master and slave nodes

Run on master

rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
for all vhost

from
https://www.rabbitmq.com/ha.html

ha-sync-mode: manual
- this is the default mode. A new queue mirror will not receive existing messages, it will only receive new messages. The new queue mirror will become an exact replica of the master over time, once consumers have drained messages that only exist on the master. If the master queue fails before all unsychronised messages are drained, those messages will be lost. You can fully synchronise a queue manually, refer to unsynchronised mirrors section for details.

ha-sync-mode: automatic
- a queue will automatically synchronise when a new mirror joins. It is worth reiterating that queue synchronisation is a blocking operation. If queues are small, or you have a fast network between RabbitMQ nodes and the ha-sync-batch-size was optimised, this is a good choice.

for / vhost
rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

Setting policy "ha-all" for pattern "" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "/" ...

for vhost1 vhost
rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}' -p vhost1

Setting policy "ha-all" for pattern "" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "vhost1" ...

вторник, 23 июля 2019 г.

Linux ucarp promote slave to master

Проверяем, что nginx конфиги идентичны на обоих серверах.

https://kamaok.org.ua/?p=1994

# номер группы (число от 1 до 255) одинаковый для всех серверов;
ucarp-vid 1

# отказоустойчивый IP-адрес(VIP)
ucarp-vip 192.168.1.125

# пароль/ключ для шифрования сетевого протокола, одинаковый для серверов в пределах группы;
ucarp-password fahDo7zaze

# управление приоритетом выбора мастера из нескольких кандидатов группы (Чем больше число, тем меньше вероятность, что хост станет Мастером)
ucarp-advskew 1

# интервал оповещения хостов в группе о своем статусе;
ucarp-advbase 1

# Роль в группе при запуске. используется для повышения приоритета при выборе мастера.
ucarp-master yes

# Виртуальный интерфейс
iface eth0:ucarp inet static
address 192.168.1.125
netmask 255.255.255.0


Отсюда следует, 
  1. меняем ucarp-advskew 50 для slave и 10 для master
  2. ucarp-master yes и ucarp-master no меняем соответсвенно
перегружаем настройки на лету
на мастере запускаем

killall -USR2 ucarp
проверяем ip a s 

Linux nginx configs backup

Буду использовать отдельно созданный для этого ssh key из специально созданной папки

mkdir -p /root/sshkey-for-nginx-backup
chmod 0600 /root/sshkey-for-nginx-backup

ssh-keygen -t rsa -b 4096 -f /root/sshkey-for-nginx-backup/id_rsa -C sshkey-for-nginx-backup@hostname

copy ssh pub key to remote server

apt install zstd

#!/bin/bash

function logging {
    echo $(date +%F_%H-%M) "______" "$1"
}

current_date=`date +%F`

tar -cf - /etc/nginx /etc/letsencrypt | zstd -19 | ssh -p 2202 -i /root/sshkey-for-nginx-backup/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no hostname-backup@1.2.3.4 "cat - > /var/www/backup/hostname/nginx.hostname.$current_date.tar.zst" && logging "Backup was sent successfully ..." || logging "Backup wasn't created ..."

Скрипт будет запускаться по крону каждый день

#Backup nginx configs to backup server
20 5 * * * /usr/local/bin/backup-nginx-config.sh >> /var/log/backup-nginx-config.log 2>&1

понедельник, 22 июля 2019 г.

LXC Operation not permitted - Failed to create veth pair "vc1" and "veth


Error:

lxc ct100 20190722062355.822 ERROR network - network.c:instantiate_veth:106 - Operation not permitted - Failed to create veth pair "vc1" and "vethWGA60H"
lxc ct100 20190722062355.822 ERROR network - network.c:lxc_create_network_priv:2457 - Failed to create network device
lxc ct100 20190722062355.822 ERROR start - start.c:lxc_spawn:1626 - Failed to create the network
lxc ct100 20190722062355.822 ERROR start - start.c:__lxc_start:1939 - Failed to spawn container "ct100"
lxc abc100 20190722062355.822 ERROR lxccontainer - lxccontainer.c:wait_on_daemonized_start:842 - Received container state "STOPPING" instead of "RUNNING"
lxc 20190722062355.832 WARN commands - commands.c:lxc_cmd_rsp_recv:132 - Connection reset by peer - Failed to receive response for command "get_state"

Решение

modprobe veth

Linux Bash parse IPs from log by word

Парсить IP с отозванными сертификатами из лога

Mon Jul 22 05:38:54 2019 1.2.3.4:6252 VERIFY ERROR: depth=0, error=certificate revoked: ...

grep revoked openvpn.log | awk '{ print $6 }' | awk -F":" '{ print $1 }' | sort | uniq -u

awk -F":" разделитель, это парсим 1.2.3.4:6252 для получения только IP
Чтобы использовать uniq, сначала нужно отсортировать sort

понедельник, 15 июля 2019 г.

Python запуск команд на удаленном сервере over SSH

Установка

pip3 install paramiko

Пример проверки есть ли уже пользователь на удаленном компьютере:

import paramiko

host = '10.81.156.13'
user = 'root'
#файл может находится в любом удобном месте
keyfilename = '/root/ssh_key_for cheking/id_rsa'
create_user = "newuser"

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
k = paramiko.RSAKey.from_private_key_file(keyfilename)
ssh.connect(hostname=host, port=22, username=user, pkey=k)

cmd = 'grep -c -w ' + create_user + ' /etc/passwd'

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd)

result_ssh = ssh_stdout.readlines()
result_ssh = "".join(result_ssh)
#print(result_ssh[0])

if result_ssh[0] == '0' and result_ssh[0].isdigit():
    print("user not exists and it will be created")



Linux sudo keep environment variables APP_ENV

https://stackoverflow.com/questions/8633461/how-to-keep-environment-variables-when-using-sudo

Добавить в sudoers.d в пользовательский конфиг

Defaults env_keep += "APP_ENV"

пятница, 5 июля 2019 г.

Nginx CORS

На одном нашем сайт site1.com добавили статистику с двух других наших сайтов site2.com site3.com . Нужно разрешить CORS на 2 и 3 сайте для 1 сайта, иначе видим ошибку

Access to XMLHttpRequest at 'https://www.site2.com/api/get-registered-users-count' from origin 'http://www.site1.com' has been blocked by CORS policy.

Пользовался этой статьей
добавил

location / 
    add_header 'Access-Control-Allow-Origin' 'https://www.site1.com'; 
    add_header 'Access-Control-Allow-Credentials' 'true'; 
    add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept'; 
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; 
}

Тест

curl -H "Access-Control-Request-Method: GET" -H "Origin: https://www.site1.com" --head http://www.site2.com

После разрешения появились записи

Access-Control-Allow-Origin: https://site1.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Accept
Access-Control-Allow-Methods: POST, OPTIONS

Git замена мастера другой веткой

Было много изменений и проще было мастер заменить другой веткой.
https://stackoverflow.com/questions/2862590/how-to-replace-master-branch-in-git-entirely-from-another-branch
Использовали

git checkout v1.0.1
git merge -s ours master

Про стратегии статья
Стратегия ours ^
Не следует путать стратегию ours и опцию ours стратегии recursive.

Выполняя git merge -s ours obsolete, вы как бы говорите: я хочу слить истории веток, но проигнорировать все изменения, которые произошли в ветке obsolete. Иногда рекомендуют вместо стратегии ours использовать следующий вариант:

git checkout obsolete 
git merge -s recursive -Xtheirs master

Стратегия ours — более радикальное средство.

среда, 3 июля 2019 г.

Linux /bin/ls: Argument list too long

Нужно было чистить каталог, но стандартная очистка с созданием списка ls показала ошибку при первом запуске с большим количеством файлов (~400 000)
Решение https://www.in-ulm.de/~mascheck/various/argmax/ , из параграфа
How to avoid the limit in a shell выбрал этот вариант:
find /home/folder -mtime +7 -print0 -type f | xargs -0 rm -rf

Все файлы старше семи дней удаляются

Linux rabbitmq-server add read-only user

Включаем плагины менеджмента

rabbitmq-plugins enable rabbitmq_management
Заводим нового пользователя

rabbitmqctl add_user username usernamePassword

Права по порядку config, write, read Даем полные права только на чтение ".*"

rabbitmqctl set_permissions -p / username "^username.*" "^username.*" ".*"

Чтобы подключаться удаленно, нужно дать доступ
по описанию monitiring самый подходящий для этого

rabbitmqctl set_user_tags radly monitoring

Linux Nginx страница обслуживания

При появлении в каталоге файла maitainance_on отображать 503 страницу обслуживания
Проверка на файл:

    location / {
        if (-f /home/www/site/maintenance_on) {
            return 503;
        }

        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

и обработка 503 ошибки

    error_page 503 /maintenance.html;

    location = /maintenance.html {
         root /home/www/site/public;
    }

    location ~ ^/maintenance-assets/(.+\.(jpg|png))$ {
         alias /home/www/site/public/maintenance-assets/$1;
    }

вторник, 2 июля 2019 г.

PHP Phpunit errors in pipeline

Куча разных ошибок в пайплайне
[InvalidArgumentException]
Project directory phpunit-6.5/ is not empty.

PHP Fatal error: Uncaught Error: Class 'Symfony\Bridge\PhpUnit\TextUI\Command' not found in

Failed to download sebastian/global-state from dist: No such zip file

четверг, 27 июня 2019 г.

Git удаление ветки из локального репозитория, после удаления ее через веб интерфейс

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

git fetch origin

Для очистки от удаленной ветки нужно использовать опцию --prune

git remote prune origin --dry-run (для проверки) или
git fetch origin --prune

Ссылки

Python generate ssh key for server ssh access

Установка

pip3 install pycryptodome

Пример:

from os import chmod
from Crypto.PublicKey import RSA

key = RSA.generate(4096)
with open("id_rsa", 'wb') as content_file:
    chmod("id_rsa", 0o600)
    content_file.write(key.exportKey('PEM'))
pubkey = key.publickey()
with open("id_rsa.pub", 'wb') as content_file:
    chmod("id_rsa.pub", 0o600)
    content_file.write(pubkey.exportKey('OpenSSH'))

exportKey('PEM') exportKey('OpenSSH') PEM формат нужен для приватного ключа, OpenSSH - для паблик ключа.
В chmod permissions указаны в соответствии python-дружественным синтаксисом 0o600. 

Linux Nginx location

https://www.linode.com/docs/web-servers/nginx/how-to-configure-nginx/
http://world-blog.ru/nginx-location-regulyarnye-vyrazheniya
https://habr.com/ru/post/348206/

среда, 26 июня 2019 г.

Python OptionParser парсер аргументов строки запуска приложения

link
if __name__ == "__main__":
    parser = OptionParser()
    group = OptionGroup(parser, "Merge Options",
                        "By default, only issues with status "
                        "['To Test' and 'Pending'] will be merged")
    group.add_option("--merge-status-in-progress",
                     action="store_true",
                     dest="merge_in_progress",
                     default=False,
                     help="Merge issue branches with status"
                     "In progress + 100 % [default: False]")
    group.add_option("--merge-all-outdated-branches",
                     action="store_true",
                     dest="merge_all_outdated_branches",
                     default=False,
                     help="Merge all outdated branches")

    parser.add_option_group(group)
    (options, args) = parser.parse_args()

    if options.merge_all_outdated_branches:
        sys.exit(merge_outdated_branches())

    sys.exit(auto_merge(options.merge_in_progress))

Запуск app-merge.py --merge-status-in-progress и без опции вызовет выполнение функции auto_merge()app-merge.py --merge-all-outdated-branches вызовет выполнение функции merge_outdated_branches()

action="store_true" аргумент без параметров (--a)
action="store" аргумент с параметрами (--a 10)

Python форматирование даты

Дату из формата 2019-06-25T09:10:50 +0000 преобразовать в формат 25-06-2019

import datetime

datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%f%z').strftime("%d-%m-%Y")

переменную v iso формата преобразуем в нужный формат %d-%m-%Y (+0000 - это %z)

Пример со сравнением дат:

current_date = datetime.datetime.now()

# дата старше на две недели в iso формате
curr_time_minus_two_weeks = datetime.datetime.isoformat(current_date - timedelta(weeks=2))

for br in branches:
    branches = project.branches.list(all=True)
    for k, v in br.commit.items():
        # check whether commited date older tnan current date in two weeks
        if k == "committed_date" and v < curr_time_minus_two_weeks:
            logger.info("Branch: %s", br.name)            
            logger.info("committed date %s is older than two weeks ago %s", datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%f%z').strftime("%d-%m-%Y"), datetime.datetime.strptime(curr_time_minus_two_weeks, '%Y-%m-%dT%H:%M:%S.%f').strftime("%d-%m-%Y"))

PHP Laravel add user

Задача добавить нового юзера в приложение

php artisan tinker

>>> DB::table('users')->insert(['name'=>'MyUsername','email'=>'thisis@myemail.com','password'=>Hash::make('123456')])

вторник, 18 июня 2019 г.

Linux nginx proxy_pass

Make port with basic http authentication for json requests

server {
    listen 3001;

    location /
    {
        access_log off;
        error_log /var/log/nginx/error_gateway.log;

        auth_basic "gateway";
        auth_basic_user_file /etc/nginx/gateway;

        default_type application/json;
        proxy_pass http://127.0.0.1:3000;
    }
}

Python gitlab branches

List of branches with excluding protected branches and cherry-pick hotfix revert patch words in name of branches

        gitlab_abc = gitlab.Gitlab(GITLAB_URL, TOKEN, api_version=4)
        project = gitlab_abc.projects.get(ABC_PROJECT)

        branches = project.branches.list(all=True)
        for br in branches:
            if not(br.protected) and "cherry-pick" not in br.name and "revert" not in br.name and "hotfix" not in br.name and "patch" not in br.name:
                print("br.name: ", br.name)
                for k, v in br.commit.items():
                    if k == "committed_date":
                        print("committed_date: ", v)

br.name:  issue-1234
committed_date:  2019-05-15T14:39:35.000+00:00

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

Node debug app.js

В помощь по отлову ошибок

node --inspect app.js

help покажет доступные команды, 
run - запустить приложение, 
n (next) - выполнять строка за строкой
.exit - выйти

четверг, 6 июня 2019 г.

Facebook Permanent Page Access Token

Для скрипта, который отслеживает новые сообщения на странице, нужно получить постоянный токен (маркер в русском переводе)
Я добавлен в администраторы https://developers.facebook.com для нужного мне приложения.
Использую этот мануал https://stackoverflow.com/questions/17197970/facebook-permanent-page-access-token
1) Get Short-Lived Access Token
На этой странице, в инструментах https://developers.facebook.com/tools/accesstoken/ , есть краткосрочный токен/маркер
2) Generate Long-Lived Access Token (long_lived_access_token)
Если там нажать отладка/debug можно увидеть срок действия, если краткосрочный, то будет активна кнопка продлить маркер дотупа/токен. Поэтому второй пункт прошел не так как в мануале
3) Get User ID (account_id)
там же в отладке видно user ID
4) Get Permanent Page Access Token
https://graph.facebook.com/v2.10/{account_id}/accounts?access_token={long_lived_access_token}
В отладчике https://developers.facebook.com/tools/debug/accesstoken проверить статус

Отладка новых сообщений:
{app_id}/conversations?fields=updated_time,senders,unread_count
запускать с Permanent Page Access Token

четверг, 30 мая 2019 г.

Linux PHP remove http header X-Powered-By

Для безопасности лучше удалить такие headers
До удаления
curl -I -L example.com
x-powered-by: PHP/7.2.18

Чтобы удалить, прописываем в
php.ini
expose_php = off
И reload php
После этого таких заголовков не наблюдаем

среда, 29 мая 2019 г.

Linux Node FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

Ошибка в стейдже билдинга при запуске karma. Найденные советы не помогли

1) export NODE_OPTIONS=--max_old_space_size=8192
2) node --max-old-space-size=8192 /usr/local/nvm/versions/node/v8.15.0/bin/npm run unit


помогло

node --max_old_space_size=4096 node_modules/karma/bin/karma start karma.conf.js

в unit строке package.json

среда, 22 мая 2019 г.

Linux Debian rsyslog перенаправление в другой лог файл без дублирования

Был установлен lm_sensors и стал засирать kern.log на который стоит триггер zabbix мониторинга на изменение. Что было сделано,
В rsysylog.d создан sensors.conf

:msg, contains, "temperature"      /var/log/sensors.log
#if $syslogfacility-text == 'kern' and $msg contains 'temperature' then /var/log/sensors.log
& stop

Вариант с if - это как альтернатива для более глубокой детализации поиска если нужно.
& stop это как раз нужно для того, чтобы не дублировалось в другие логи. В kern.log теперь не попадает информация от sensors.

И не забыть перестартовать rsyslog

systemctl restart rsyslog

Еще пример лога

Jun 21 14:20:12 server node[6038]: 2019-06-21 14:20:12 INFO  RPC server listening at localhost

имя программы здесь node, пример
:programname, isequal, "node"      /var/log/node.log

& stop
отсюда
Также немаловажно изменить таг в логе для программы
https://stackoverflow.com/questions/37585758/how-to-redirect-output-of-systemd-service-to-a-file

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=New_tag


пятница, 3 мая 2019 г.

Linux nodejs PhantomJS error loading dso:conf_mod.c:285:module=ssl_conf, path=ssl_conf

02 05 2019 18:52:46.133:INFO [launcher]: Starting browser PhantomJS
02 05 2019 18:52:46.694:ERROR [phantomjs.launcher]: Auto configuration failed
140452918341248:error:25066067:DSO support routines:DLFCN_LOAD:could not load the shared library:dso_dlfcn.c:185:filename(libssl_conf.so): libssl_conf.so: cannot open shared object file: No such file or directory
140452918341248:error:25070067:DSO support routines:DSO_load:could not load the shared library:dso_lib.c:244:
140452918341248:error:0E07506E:configuration file routines:MODULE_LOAD_DSO:error loading dso:conf_mod.c:285:module=ssl_conf, path=ssl_conf
140452918341248:error:0E076071:configuration file routines:MODULE_RUN:unknown module name:conf_mod.c:222:module=ssl_conf

02 05 2019 18:52:46.696:ERROR [launcher]: Cannot start PhantomJS

На версии openssl 1.1.0 работает, на 1.1.1 не работает
Помог комментарий
Закомментировал [default_conf] в /etc/ssl/openssl.cnf

пятница, 26 апреля 2019 г.

Linux buster Zabbix Apache choose PHP version

После upgrade to buster вылезла проблема с zabbix. Он был установлен из официального репозитория. Но с ним возникла проблема с зависимостями
libcurl3 (>= 7.28.0)` but `libcurl4` in buster and `libevent-2.0-5` but `libevent-2.1-6
Но в репозиториях buster есть zabbix 4.0.4, поэтому переустановил оттуда.
Фронтенд (на apache2) пришлось также переустанавливать через remove и install. Но версия php обновилась тоже и было теперь две версии php 7.0 и 7.3, причем php-mysql . Нужно было поменять ее для apache. Это делается через
a2dismod php7.0
a2enmod php7.3
systemctl restart apache2