Warning: require(): open_basedir restriction in effect. File(x) is not within the allowed path(s)

Столкнулся с ошибкой во время переноса скрипта на другой сервер. Для управления сайтами используется панель Vesta CP. Проблема заключается в том, что на сервере не правильно прописана опция open_basedir. Для нормальной работы скрипта нам нужно обеспечить доступ к каталогу /home/system/web/system.ru/yii/.

Warning: require(): open_basedir restriction in effect. File(/home/system/web/system.ru/yii/vendor/autoload.php) is not within the allowed path(s): (/home/system/web/system.ru/public_html:/home/system/1) in /home/system/web/system.ru/public_html/admin/index.php on line 10

Warning: require(/home/system/web/system.ru/yii/vendor/autoload.php): failed to open stream: Operation not permitted in /home/system/web/system.ru/public_html/admin/index.php on line 10

Fatal error: require(): Failed opening required '/home/system/web/system.ru/public_html/admin/../../yii/vendor/autoload.php' (include_path='.:/usr/share/pear:/usr/share/php') in /home/system/web/system.ru/public_html/admin/index.php on line 10

Для решения проблемы Warning: require(): open_basedir restriction in effect. File(x) is not within the allowed path(s) переходим в каталог с конфигами Apache. У меня Vesta CP и они расположены по следующему пути:

cd /home/system/conf/web

Далее добавляем или правим настройки в конфигах:

system.ru.httpd.conf
system.ru.httpd.ssl.conf

Следующую опцию:

<Directory /home/system/web/system.ru/public_html>
        AllowOverride All
        SSLRequireSSL
        Options +Includes -Indexes +ExecCGI
        php_admin_value open_basedir   /home/system/web/system.ru/public_html:/home/system
        php_admin_value upload_tmp_dir /home/system/tmp
        php_admin_value session.save_path /home/system/tmp
    </Directory>

Установка Python 2 и sqlite 3 в CentOS 7

Небольшая заметка по настройке связки Python 2 и sqlite 3 в CentOS 7. Данная связка потребовалась мне для автоматизации повседневных задач на моем сервере.

На момент написания статьи в версия пакета sqlite 3.7.17 в репозитории CentOS 7:

# yum install sqlite3
Available Packages
Name        : sqlite
Arch        : i686
Version     : 3.7.17
Release     : 8.el7
Size        : 396 k
Repo        : base/7/x86_64
Summary     : Library that implements an embeddable SQL database engine
URL         : http://www.sqlite.org/
License     : Public Domain
Description : SQLite is a C library that implements an SQL database engine. A
            : large subset of SQL92 is supported. A complete database is stored
            : in a single disk file. The API is designed for convenience and
            : ease of use. Applications that link against SQLite can enjoy the
            : power and flexibility of an SQL database without the
            : administrative hassles of supporting a separate database server.
            : Version 2 and version 3 binaries are named to permit each to be
            : installed on a single host

Устанавливаем sqlite3:

yum install sqlite

Для установки Python модуля sqlite необходимо установить утилиту pip:

yum install python-pip

Проверим корректность установки командой:

# pip --version
pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)

Установим модуль sqlite3 для Python:

pip install pysqlite3

Увеличение диска в Linux

Дата: 06.08.2018Метки: ,

В данной заметке я расскажу как без потери данных увеличить размер диска в Linux. Действия производились на системе CentOS 7. Раздел был отформатирован в файловой системе ext4. Перед выполнением указанных ниже действий, рекомендую сделать бэкап данных.

Кратко процесс увеличения диска в Linux можно разделить на следующие шаги. Удаление старого раздела, создание нового раздела большего размера, увеличение размера файловой системы.

Загружаемся с любого LiveCD, подойдет Ubuntu. Для начала выполняем выполните команду:

fdisk /dev/sda -l

В данном примере я указал свое название диска sda, которое может отличатся от вашего.
Получаю следующий результат:

# fdisk /dev/sda -l
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.

Disk /dev/sda: 480.1 GB, 480103981056 bytes, 937703088 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: gpt
Disk identifier: 005F2749-8E5A-4457-91EB-7227A4222981


#         Start          End    Size  Type            Name
 1         2048      1048575    511M  EFI System      primary
 2      1048576     42006527   19.5G  Linux filesyste primary
 3     42006528    937703054  427.1G  Linux filesyste

Из результата выполнения команды важно записать значение начального сектора раздела, в моем случае это 42006528

Теперь выполняем команду:

fdisk /dev/sda

Выполним d для удаления существующего раздела. Далее n – для создания нового, p – для primary, 3 – это номер раздела. В процессе укажем начало и конец раздела в секторах. Начальный сектор должен соответствовать начальному сектору раздела, который был удален. Последний сектор раздела выбираем максимально допустимый. Жмем w для записи изменений и выхода из fdisk.

Перезапускаем систему, загружаемся снова в LiveCD. Теперь нам необходимо расширить файловую систему на весь раздел:

e2fsck /dev/sda3
resize2fs /dev/sda3

В процессе проверки файловой системы будут найдены ошибки — это нормально. Соглашаемся и жмем y для исправления. Загружаемся с диска и проверяем изменения:

df -h

Для изменения диска в графическом режиме удобно использовать LiveCD с программой gparted

Прогресс выполнения команды dd

Дата: 09.06.2018Метки: ,

Запустил бэкап диска с передачей данных на другой сервер:

dd if=/dev/sda | gzip -3 - | ssh root@1.1.1.1 dd of=/storage/image.gz

Главная проблема данного метода состоит в том, что отсутствует информация о прогрессе выполнения команды dd. Посмотреть на каком этапе находится процесс создания бэкапа можно следующим образом.

Открываем еще одну консоль и в ней выполняем команду:

pkill -USR1 dd

Возвращаемся в консоль, где запущен команда dd и видим примерно следующий результат:

46581824+0 records in
46581823+0 records out
23849893376 bytes (24 GB) copied, 650.728 s, 36.7 MB/s
52076416+0 records in
52076415+0 records out
26663124480 bytes (27 GB) copied, 736.246 s, 36.2 MB/s
232366273+0 records in
232366272+0 records out
118971531264 bytes (119 GB) copied, 1193.34 s, 99.7 MB/s
234441648+0 records in
234441648+0 records out
120034123776 bytes (120 GB) copied, 1198.1 s, 100 MB/s

Что бы каждый раз не вбивать команду в консоли, можно сделать так:

watch -n 10 pkill -USR1 dd

Linux disk write timeout

Дата: 30.04.2018Метки:

При интенсивных операциях записи в Debian 9 поймал disk write timeout. К сожалению, точное содержание ошибки не записал, но в общем суть понятна. Система выдавала таймаут при записи на диск. Сначала пытался увеличить следующее значение:

echo 180 > /sys/block/sda/device/timeout

Но конкретно данная манипуляция не дала никакого результата. В итоге удалось решить проблему указав значения параметров кэширования в Linux dirty_background_ratio и dirty_ratio:

echo 5 > /proc/sys/vm/dirty_background_ratio
echo 10 > /proc/sys/vm/dirty_ratio

dirty_background_ratio — основной инструмент настройки, обычно уменьшают этот параметр. Если ваша цель снизить количество данных, хранимое в кэше, так что данные будут писаться на диск постепенно, а не все сразу, то уменьшение этого параметра наиболее эффективный путь. Более приемлемо значение по умолчанию для систем имеющих много оперативной памяти и медленные диски.

dirty_ratio — второй по значимости параметр для настройки. При значительном снижении этого параметра приложения, которые должны писать на диск, будут блокироваться все вместе.

/bin/sh can’t access tty

Дата: 15.10.2017Метки:

На одном из серверов упал сайт. В браузере отображалась информация об отсутствии подключения к MySQL. Запускаться вручную MySQL отказывался. Отправил сервер на перезагрузку, после чего система отказалась запускаться. Если подключится к консоли можно увидеть вот такое сообщение об ошибке:

/bin/sh can't access tty

У меня была установлена система Debian 8, вылечилось достаточно просто. Запустил проверку файловой системы:

fsck -t ext4 /dev/sda1

В процессе проверки были найдены ошибки, на всех запросах жал Y для подтверждения. После перезапуска система ожила.

SMART мониторинг SSD в Linux

Дата: 21.06.2017Метки:

У каждого производителя SSD есть специализированная утилита для мониторинга состояния диска в Windows. Что касается Linux, то ситуация состоит сложнее. По моему опыту я сталкивался с наличием такой утилиты под Linux только для PRO и энтерпрайз серии SSD дисков. Но если говорить по сути, то особой нужды в них нет. В качестве альтернативы мы будем использовать утилиту smartmontools доступную для большинства дистрибутивов Linux.

Для начала выполним установку. В CentOS необходимо выполнить команду:

yum install smartmontools

Для Debian и Ubuntu аналогично:

apt-get install smartmontools

Если не знаете название диска, то список всех подключенных дисков можно посмотреть командой:

find /dev -name 'sd*'

Теперь, когда известно название диска, можем вывести информацию SMART. У меня результат выполнения команды выглядит следующим образом:

# smartctl -A /dev/sda
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.10.0-514.21.1.el7.x86_64] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 1
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  9 Power_On_Hours          0x0032   099   099   000    Old_age   Always       -       215
 12 Power_Cycle_Count       0x0032   099   099   000    Old_age   Always       -       9
177 Wear_Leveling_Count     0x0013   100   100   000    Pre-fail  Always       -       0
179 Used_Rsvd_Blk_Cnt_Tot   0x0013   100   100   010    Pre-fail  Always       -       0
181 Program_Fail_Cnt_Total  0x0032   100   100   010    Old_age   Always       -       0
182 Erase_Fail_Count_Total  0x0032   100   100   010    Old_age   Always       -       0
183 Runtime_Bad_Block       0x0013   100   100   010    Pre-fail  Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0032   069   063   000    Old_age   Always       -       31
195 Hardware_ECC_Recovered  0x001a   200   200   000    Old_age   Always       -       0
199 UDMA_CRC_Error_Count    0x003e   100   100   000    Old_age   Always       -       0
235 Unknown_Attribute       0x0012   099   099   000    Old_age   Always       -       2
241 Total_LBAs_Written      0x0032   099   099   000    Old_age   Always       -       1357065631

Теперь немного информации о данных, которые содержат важную информацию о состоянии вашего диска. В первую очередь обратите внимание на значение RAW_VALUE для параметра Reallocated_Sector_Ct — количество переназначенных секторов. Нулевое значение говорит нам, что диск в полном порядке. Далее обратите внимание на Power_On_Hours, параметр отображает информацию о суммарном времени работы диска. Информация может быть полезна при аренде сервера и дает общее представление о времени его работы. Далее второй по значимости параметр Total_LBAs_Written — общее количество записанных байт.

Что бы предоставить информацию из Total_LBAs_Written можно воспользоваться онлайн калькулятором. В калькуляторе важно указать размер сектора диска, его можно посмотреть командой:

fdisk -l /dev/sda

Зомби процессы в Linux

Дата: 10.04.2017Метки:

Если в вашей системе завелись зомби процессы, не расстраивайтесь. Не смотря на страшное название зомби процесс не может нанести серьезный вред вашей системе. Для начала давайте разберемся как обычный процесс превращается в зомби.

Когда дочерний процесс получает команду на завершение, он освобождает все используемые ресурсы и продолжает как зомби существовать в системе с ранее присвоенным ему PID. Далее с помощью сигнала SIGCHLD система уведомляет родительский процесс о завершении зомби процесса. Если по какой-либо причине родительский процесс игнорирует этот сигнал, то зомби процесс так и продолжает отображаться в системе.

Как вы уже поняли, зомби процессы не используют системные ресурсы, поэтому их можно просто игнорировать. Убить зомби процесс на прямую командой kill у вас не получиться. В данном случае единственный вариант полностью убрать зомби процесс — убить или перезапустить его родительский процесс.

Что бы убить зомби процесс, для начала нужно получить его PID:

# ps aux | grep -w Z
root      2037  0.0  0.0      0     0 ?        Z    09:44   0:00 [httpd] 
root      8470  0.0  0.0 112652   984 pts/10   S+   10:43   0:00 grep --color=auto -w Z

В моем примере PID зомби процесса 2037. Теперь получим PID родительского процесса:

# ps o ppid 2037
 PPID
 2033

Когда мы знаем PID, правильнее всего определить что это за процесс командой top, а затем перезапустить его.

В крайнем случае можно убить родительский процесс:

# kill -9 2033

Добавить сервис в systemd

В этой заметке я расскажу о том, как настроить сервис Linux для автоматического запуска демона после сбоя или перезагрузки. В качестве примера я буду использовать Nginx и PHP но вы можете этот способ для любых приложений.

Уже прошло достаточно много времени с того момента, как большинство популярных дистрибутивов Linux перешли на системный менеджер systemd. Тем не менее, до сих пор старая система инициализации SysV продолжает параллельно функционировать на ряду с systemd. И как и раньше, большинство пакетов после установки добавляют стартовый скрипт в каталог init.d.

Не буду вдаваться в подробности про механизмы параллелизации systemd и скорость загрузку системы. Это все хорошо и прекрасно. Но для меня главный аргумент в ползу перехода на systemd — это наличие встроенных функций отслеживания и контроля состояния сервисов. Что бы было понятнее, давайте представим следующую ситуацию.

Для примера мы установили OpenVPN, для которого по умолчанию используется механизм запуска System V. Во время установки пакета в каталог /etc/init.d будет скопирован скрипт инициализации, который будет отвечать за автоматический запуск приложения после перезагрузки. Если в один прекрасный день OpenVPN упадет, без дополнительных настроек, нужно будет каждый раз запускать этот процесс вручную.

Теперь возьмем ситуацию, когда для запуск сервиса выполнен через systemd. Если произойдет крэш или даже если вы захотите специально убить процесс, то systemd автоматически это обнаружит и повторно запустит процесс. При этом systemd обратно совместим с командами System V и сценариями инициализации.

А теперь давайте рассмотрим, как быстро добавить сервис в systemd. Демон systemd запускает сервисы описанные в его конфигурации. Конфигурация состоит из файлов, которые называют юнитами. Для юнитов созданных вручную используется каталог:

/etc/systemd/system/

В простом варианте юнит состоит из трех секции: [Unit], [Service], [Install].

Секция [Unit]

Описание юнита:

Description=MyUnit

Далее указываем порядок загрузки, после какого сервиса systemd запустить наш юнит:

After=syslog.target
After=network.target

Секция [Service]

Задаем тип сервиса:

Type=simple

Используется по умолчанию. Служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы.

Type=forking

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

Расположение pid-файла:

PIDFile=/run/service.pid

Рабочий каталог приложения:

WorkingDirectory=/usr/local/service

Пользователь и группа, под которым будет запускаться сервис:

User=unit
Group=unit

Задаем приоритет убийства процесса при нехватке памяти:

OOMScoreAdjust=-100

Минимальное значение -1000 — полный запрет.

Команды запуска, остановки и перезапуска сервиса:

ExecStart=/usr/sbin/service
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID

Таймаут запуска или остановки сервиса:

TimeoutSec=300

Контроль запуска сервиса и автоматический запуск в случае крєша:

Restart=always

Секция [Install]

Уровень запуска сервиса:

WantedBy=multi-user.target

В итоге мы получили следующий юнит:

[Unit]
Description=MyUnit
After=syslog.target
After=network.target

[Service]
Type=forking
PIDFile=/run/service.pid
WorkingDirectory=/usr/local/service
User=munit
Group=unit
OOMScoreAdjust=-100

ExecStart=/usr/sbin/service
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutSec=300

[Install]
WantedBy=multi-user.target

Добавляем юнит в каталог:

nano /etc/systemd/system/unit_name

Включаем, запускаем и смотрим статус юнита:

systemctl enable unit_name
systemctl start unit_name
systemctl -l status unit_name
systemctl daemon-reload

А теперь привожу примеры работающих юнитов.

Юнит systemd для запуска Nginx:

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Юнит systemd для запуска php-fpm:

[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=simple
PIDFile=/usr/local/php-fpm/var/run/php-fpm.pid
ExecStart=/usr/local/php-fpm/sbin/php-fpm --nodaemonize --fpm-config /usr/local$
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Access denied for user ‘debian-sys-maint’@’localhost’

С проблемой можно столкнуться в результате некорректной установки MySQL. Полностью ошибка выглядит следующим образом:

mysql_upgrade: Got error: 1045: Access denied for user 'debian-sys-maint'@'localhost' (using password: YES) while connecting to the MySQL server

Суть проблемы состоит в том, что mysql_upgrade не может получить доступ к нашей базе под указанным в файле debian.cnf паролем. Если выполнить команду:

cat /etc/mysql/debian.cnf

Мы получить результат следующего вида:

# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host     = localhost
user     = debian-sys-maint
password = n4aSHUP04s1J32X5
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
user     = debian-sys-maint
password = n4aSHUP04s1J32X5
socket   = /var/run/mysqld/mysqld.sock
basedir  = /usr

Нас интересует параметр password. Копируем это пароль, после чего в MySQL необходимо выполнить запрос:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'debian-sys-maint'@'localhost' IDENTIFIED BY 'n4aSHUP04s1J32X5';

С первого раза не сработало, MySQL ругался на то, что пароль не соответствует правилам безопасности. Тогда просто можно добавить к паролю любой символ и повторить команду. При этом не забудьте указать новый пароль в фале debian.cnf.

Для того чтобы имения вступили в силу, необходимо перезапустить MySQL.