cookies:
|
- #!/usr/bin/perl
- ########################################
- ### Хранит функции работы с системой ###
- ########################################
- package System;
- use strict;
- use warnings;
- use Conf;
- use File::Path qw(make_path);
- use File::Copy;
- use File::Read;
- use DBI;
-
- ##################################
- ### Функции для работы с linux ###
- ##################################
-
- # возвращает аптайм
- sub linux_get_uptime
- {
- my @uptime = split(/,/, `/usr/bin/uptime 2>/dev/null`, 3);
- $uptime[0] =~ s/^[\s]+//;
- chomp $uptime[2];
- return $uptime[0] . "," . $uptime[2];
- }
-
- # возвращает версию ядра
- sub linux_get_kernel_version
- {
- my $tmp = `/bin/uname -r -m`;
- chomp $tmp;
- return $tmp;
- }
-
- # возвращает hostname
- sub linux_get_hostname
- {
- my $tmp = `/bin/hostname -f 2>/dev/null`;
- chomp $tmp;
- return $tmp;
- }
-
- # возвращает информацию о свободном месте на примонтированых ext234 файловых системах
- sub linux_get_spaceinfo
- {
- my @tmp = `/bin/df 2>/dev/null -h -l -t ext4 -t ext3 -t ext2 | tail -n +2`;
- my $result = '';
- foreach (@tmp) {
- my @line = split /\s+/;
- $result .= $line[5] . ': ' . $line[3] . ', ';
- }
- $result =~ s/^(.*),/$1/i;
- return $result;
- }
-
- # возвращает информацию о памяти
- sub linux_get_usage
- {
- my @meminfo = `cat /proc/meminfo 2>/dev/null |egrep -i "memtotal|memfree|swaptotal|swapfree"`;
- my $result = '';
- my @tmp;
- @tmp = split /:\s+/, $meminfo[0];
- chomp $tmp[1];
- $tmp[1] =~ s/[\s]+//i;
- $result .= $tmp[1];
- @tmp = split /:\s+/, $meminfo[1];
- $tmp[1] =~ s/[\s]+//i;
- chomp $tmp[1];
- $result .= '/' . $tmp[1] . ', ';
- @tmp = split /:\s+/, $meminfo[2];
- $tmp[1] =~ s/[\s]+//i;
- chomp $tmp[1];
- $result .= $tmp[1];
- @tmp = split /:\s+/, $meminfo[3];
- $tmp[1] =~ s/[\s]+//i;
- chomp $tmp[1];
- $result .= '/' . $tmp[1];
- return $result;
- }
-
- # возвращает ip сервера для интерфейса
- sub linux_get_ip
- {
- my $server_ip = `/bin/ip 2>/dev/null addr show dev eth0 |grep inet |grep -v inet6`;
- my @server_ip = split /\s+/, $server_ip;
- if (defined($server_ip[2])) {
- $server_ip = (split /\//, $server_ip[2])[0];
- return $server_ip;
- } else {
- return '';
- }
- }
-
- # возвращает список пользователей
- sub linux_get_users
- {
- my %users;
- open my $fh, "<", "/etc/passwd"
- or Logger::warn('Manager: could not read /etc/passwd');
- while (<$fh>) {
- chomp;
- my @fields = split /:/;
- if (@fields && ($fields[2] >= 1000) && ($fields[2] <= 65000)) {
- $users{$fields[2]} = \@fields;
- }
- }
- close $fh;
- return %users;
- }
-
- # возвращает пользователя по id
- sub linux_get_user
- {
- my ($user_id) = @_;
- my @user;
-
- open my $fh, "<", "/etc/passwd"
- or Logger::warn('Manager: could not read /etc/passwd');
-
- while (<$fh>) {
- chomp;
- my @fields = split /:/;
- if (@fields && $user_id && ( $fields[2] eq $user_id ) ) {
- @user = @fields;
- last();
- }
- }
- close $fh;
-
- return @user;
- }
-
- # проверяет логин пользователя на свободность
- sub linux_login_free
- {
- my $login = shift();
- my $result = `cat /etc/passwd 2>/dev/null | egrep '^$login:'`;
- chomp $result;
- return ($result) ? 0 : 1;
- }
-
- # меняет пароль пользователю
- sub linux_passwd
- {
- my ($login, $password) = @_;
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User password length must be grater 0'}
- if (length ($password) == 0);
-
- # нет ли ещё такого пользователя
- my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
- chomp $usercounter;
- return {'status' => $?, 'message' => 'User NOT exists'}
- if ($usercounter == 0);
-
- # Меняем пароль
- my $cmd = '/bin/echo -e "' . $login . ':' . $password . '" | chpasswd -c SHA512';
- system($cmd);
- }
-
- # добавляет пользователя
- sub linux_add_user
- {
- my ($login, $password) = @_;
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # проверяем формат
- return {'status' => 1, 'message' => 'Error in format of login (^[a-z][-a-z0-9_\.]*$)'}
- if ($login !~ m/^[a-z][-a-z0-9_\.]*$/);
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User password length must be grater 0'}
- if (length ($password) == 0);
-
- # нет ли уже такого пользователя
- my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
- chomp $usercounter;
- return {'status' => $?, 'message' => 'User exists'}
- if ($usercounter > 0);
-
- my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
- my $phash = crypt($password, '$6$' . $salt . '$');
- $phash =~ s/\$/\\\$/g;
- my $add_result = system("/usr/sbin/useradd -d /var/www/$login -s /bin/false -m -p $phash $login 2>/dev/null");
-
- # нет ли ошибок при создании пользователя
- return {'status' => $add_result, 'message' => 'error adding user'}
- if ($add_result != 0);
-
- # создаем структуру каталогов
- make_path( '/var/www/' . $login . '/data',
- '/var/www/' . $login . '/data/www',
- '/var/www/' . $login . '/data/logs',
- '/var/www/' . $login . '/data/tmp', {
- mode => 0755,
- owner => $login,
- group => $login
- });
-
- return {'status' => 0, 'message' => 'User successfully created'};
- }
-
- # удаляет пользователя
- sub linux_del_user
- {
- my $login = shift();
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # нет ли ещё такого пользователя
- my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
- chomp $usercounter;
- return {'status' => $?, 'message' => 'User NOT exists'}
- if ($usercounter == 0);
-
- return system("userdel -f $login");
- }
-
- # производит операции с сервисом linux
- sub linux_service
- {
- my ($daemon, $action) = @_;
- my $tmp = `/etc/init.d/$daemon $action 2>&1`;
- #возвращаем результат
- return {'status' => $?,
- 'message' => $tmp};
- }
-
- # производит операции с сервисом linux (утилитой service)
- sub linux_service2
- {
- my ($daemon, $action) = @_;
- my $tmp = `/usr/bin/service $daemon $action 2>&1`;
- #возвращаем результат
- return {'status' => $?,
- 'message' => $tmp};
- }
-
-
-
-
-
- ####################################
- ### Функции для работы с proftpd ###
- ####################################
-
- # получает список фтп пользователей из файла ftp пользователей
- sub linux_ftp_get_users
- {
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
- open(my $fh, '<', $ftp_passwd_file)
- or Logger::warn('Manager: could not read FTP passwd file');
- my @users;
- my %users;
- while (<$fh>) {
- chomp;
- push(@users, $_);
- my @fields = split /:/;
- $users{$fields[0]} = \@fields;
- }
- close($fh);
- return %users;
- }
-
- # проверяет логин пользователя на свободность
- sub linux_ftp_login_free
- {
- my $login = shift();
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
- open(my $fh, '<', $ftp_passwd_file)
- or Logger::warn('Manager: could not read FTP passwd file');
- my $user = '';
- while (<$fh>) {
- chomp;
- if (m/$login:/) {
- $user = $_;
- last();
- }
- }
- close($fh);
- return (length($user)) ? 0 : 1;
- }
-
- # добавляет фтп пользователя
- sub linux_ftp_add_user
- {
- my ($login, $passw, $owner_id, $homedir) = @_;
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # проверяем формат
- return {'status' => 2, 'message' => 'Error in format of login (^[a-z][-a-z0-9_\.]*$)'}
- if ($login !~ m/^[a-z][-a-z0-9_\.]*$/);
-
- # проверяем длину
- return {'status' => 3, 'message' => 'User password length must be grater 0'}
- if (length ($passw) == 0);
-
- # если логин свободен
- if (linux_ftp_login_free($login))
- {
-
- my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
- my $phash = crypt($passw, '$6$' . $salt . '$');
-
- $homedir =~ s/^\///;
- my @user = linux_get_user($owner_id);
-
- if (@user) {
- $homedir = $user[5] . '/' . $homedir;
-
- # добавляем пользователя
- open(my $fh, '>>', $ftp_passwd_file)
- or Logger::warn('Manager: could not open FTP passwd file for write');
- my $userstr = $login . ":" . $phash . ":" . $owner_id . ":" . $owner_id . "::" . $homedir . ":/bin/false\n";
- print($fh $userstr);
- close($fh);
-
- # перезагружаем фтп сервер
- linux_service('proftpd', 'force-reload');
-
- # все ок
- return {'status' => 0, 'message' => 'User added'};
- } else {
-
- # id родителя указано не верно
- return {'status' => 4, 'message' => 'Owner user not found'};
- }
-
- } else {
- # логин уже занят
- return {'status' => $?, 'message' => 'User exists'};
- }
- }
-
- # удаляет пользователя из файла ftp аккаунтов
- sub linux_ftp_del_user
- {
- my $login = shift();
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # есть ли такой пользователь
- return {'status' => 2, 'message' => 'User NOT exists'}
- if (linux_ftp_login_free($login));
-
- # читаем пользователей кроме искомого в массив
- open(my $fh, '<', $ftp_passwd_file)
- or Logger::warn('Manager: could not read FTP passwd file');
- my @users;
- while (<$fh>) {
- chomp;
- if ($_ !~ m/^$login:/) {
- push(@users, $_);
- }
- }
- close($fh);
-
- # создаем временный файл с пользователями
- open(my $fh2, '>', $ftp_passwd_file . ".tmp")
- or Logger::warn('Manager: could not open FTP passwd temp file ' . $ftp_passwd_file . ".tmp" . ' for write');
- foreach (@users)
- {
- print($fh2 $_ . "\n");
- }
- close($fh2);
-
- # копируем временный файл в реальный, а реальный предварительно бекапим
- copy($ftp_passwd_file, $ftp_passwd_file . '-');
- move($ftp_passwd_file . ".tmp", $ftp_passwd_file);
-
- # перезагружаем фтп сервер
- linux_service('proftpd', 'force-reload');
-
- # все ОК
- return {'status' => 0, 'message' => 'User deleted'}
- }
-
- # изменяет пароль пользователю
- sub linux_ftp_passwd
- {
- my ($login, $passw) = @_;
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
- # проверяем длину
- return {'status' => 2, 'message' => 'User password length must be grater 0'}
- if (length ($passw) == 0);
-
- # ищем пользователя
- my @found_user = linux_ftp_get_user($login);
-
- # удаляем пользователя и добавляем нового с новым паролем
- if (@found_user) {
-
- # удалим пользователя
- my $r = linux_ftp_del_user($login);
- return $r
- if ($r->{'status'} != 0);
-
- # добавим нового с новым паролем
- $r = linux_ftp_add_user($login, $passw, $found_user[2], $found_user[5]);
- return $r
- if ($r->{'status'} != 0);
-
- # перезагружаем фтп сервер
- linux_service('proftpd', 'force-reload');
-
- # все ок
- return {'status' => 0, 'message' => 'Password updated!'};
- } else {
-
- # пользователь для изменения пароля не найден
- return {'status' => 3, 'message' => 'User NOT exists'};
- }
- }
-
- # изменяет домашнюю директорию
- sub linux_ftp_homedir
- {
- my ($login, $homedir) = @_;
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
-
- # trim
- $login =~ s/^\s+//;
- $login =~ s/\s+$//;
- $homedir =~ s/^\///;
-
- # проверяем длину
- return {'status' => 1, 'message' => 'User login length must be grater 0'}
- if (length ($login) == 0);
-
-
- # ищем пользователя
- my @found_user = linux_ftp_get_user($login);
-
- # удаляем пользователя и добавляем нового с новым паролем
- if (@found_user)
- {
-
- # ищем владельца
- my @owner_user = linux_get_user($found_user[2]);
-
- if (@owner_user) {
- # удаляем пользователя
- my $r = linux_ftp_del_user($login);
-
- return $r
- if ($r->{'status'} != 0);
-
- # trim
- $owner_user[5] =~ s/\/$//;
-
- # добавим нового с новым паролем
- $r = linux_ftp_add_user($found_user[0], $found_user[1], $found_user[2], $homedir);
- return $r
- if ($r->{'status'} != 0);
-
- # перезагружаем фтп сервер
- linux_service('proftpd', 'force-reload');
-
- # все ок
- return {'status' => 0, 'message' => $owner_user[5] . '/' . $homedir};
- } else {
- # родительский пользователь не найден
- return {'status' => 4, 'message' => 'Owner user NOT exists'};
- }
- } else {
- # пользователь для изменения пароля не найден
- return {'status' => 3, 'message' => 'User NOT exists'};
- }
- }
-
- # получает фтп пользователя из файла users.txt по логину
- sub linux_ftp_get_user
- {
- my $login = shift();
- my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
- open(my $fh, '<', $ftp_passwd_file)
- or Logger::warn('Manager: could not read FTP passwd file');
- my $user;
- while (<$fh>) {
- chomp;
- if (m/$login:/) {
- $user = $_;
- last();
- }
- }
- close($fh);
-
- return split(/:/, $user);
- }
-
-
-
-
- ####################################
- ### Функции для работы с apache2 ###
- ####################################
-
- # возвращает все виртуалхосты
- sub apache2_vhost_get_all
- {
- my @sites_available = `ls /etc/apache2/sites-available/ 2>/dev/null`;
- chomp @sites_available;
-
- my %vhosts;
- foreach (@sites_available) {
- $vhosts{$_} = (-e '/etc/apache2/sites-available/' . $_) ? 1 : 0;
- }
- return %vhosts;
- }
-
- # возвращает все виртуалхосты для пользователя
- sub apache2_vhost_get_all_for_user
- {
- my ($user_id) = @_;
-
- my @sites_available = `ls /etc/apache2/sites-available/ 2>/dev/null | egrep -i "^_$user_id"`;
- chomp @sites_available;
-
- my %vhosts;
- foreach (@sites_available) {
- $vhosts{$_} = (-e '/etc/apache2/sites-available/' . $_) ? 1 : 0;
- }
- return %vhosts;
- }
-
- # получает параметры виртуалхоста
- sub apache2_vhost_get
- {
- my ($vhost_filename) = @_;
- return {} if (!apache2_vhost_exists($vhost_filename));
-
- # вначале читаем vhost в массив
- my @vhost_lines;
- open my $fh, "<", "/etc/apache2/sites-available/" . $vhost_filename
- or Logger::warn('Manager: could not read apache2 vhost file ' . "/etc/apache2/sites-available/" . $vhost_filename);
- while (<$fh>) {
- chomp;
- push(@vhost_lines, $_);
- }
- close $fh;
-
- # собираем все свойства
- my $properties = {};
- my @directives;
-
- # парсим ServerName
- @directives = grep(/ServerName/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/ServerName[\s]+(\S+)/i;
- $properties->{'ServerName'} = trim($1);
- }
- # парсим ServerAlias
- @directives = grep(/ServerAlias/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/ServerAlias[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'ServerAlias'} = trim($1);
- }
- # парсим ServerAdmin
- @directives = grep(/ServerAdmin/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/ServerAdmin[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'ServerAdmin'} = trim($1);
- }
- # парсим AssignUserID
- @directives = grep(/AssignUserID/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/AssignUserID[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'AssignUserID'} = trim($1);
- }
- # парсим DocumentRoot
- @directives = grep(/DocumentRoot/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/DocumentRoot[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'DocumentRoot'} = trim($1);
- }
- # парсим CustomLog
- @directives = grep(/CustomLog/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/CustomLog[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'CustomLog'} = trim($1);
- }
- # парсим ErrorLog
- @directives = grep(/ErrorLog/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/ErrorLog[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'ErrorLog'} = trim($1);
- }
- # парсим DirectoryIndex
- @directives = grep(/DirectoryIndex/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/DirectoryIndex[\s]+(.*?)(?:\s)?+$/i;
- $properties->{'DirectoryIndex'} = trim($1);
- }
- #########################################
- # парсим установки php
- # парсим memory_limit
- @directives = grep(/memory_limit/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+memory_limit[\s]+(\S*)/i;
- $properties->{'memory_limit'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим max_execution_time
- @directives = grep(/max_execution_time/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+max_execution_time[\s]+(\S*)/i;
- $properties->{'max_execution_time'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим upload_max_filesize
- @directives = grep(/upload_max_filesize/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+upload_max_filesize[\s]+(\S*)/i;
- $properties->{'upload_max_filesize'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим post_max_size
- @directives = grep(/post_max_size/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+post_max_size[\s]+(\S*)/i;
- $properties->{'post_max_size'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим error_log
- @directives = grep(/php_.*error_log/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+error_log[\s]+(\S*)/i;
- $properties->{'error_log'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим error_reporting
- @directives = grep(/error_reporting/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+error_reporting[\s]+(\S*)/i;
- $properties->{'error_reporting'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим display_errors
- @directives = grep(/display_errors/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+display_errors[\s]+(\S*)/i;
- $properties->{'display_errors'} = {
- directive => $1,
- value => trim($2)
- };
- }
- # парсим log_errors
- @directives = grep(/log_errors/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+log_errors[\s]+(\S*)/i;
- $properties->{'log_errors'} = {
- directive => $1,
- value => trim($2)
- };
- }
-
- return $properties;
- }
-
- # проверяет существует ли файл виртуалхоста в /etc/apache2/sites-available/
- sub apache2_vhost_exists {
- my ($file_name) = @_;
- return (-e '/etc/apache2/sites-available/' . $file_name) ? 1 : 0;
- }
-
- # возвращает количество виртуалхостов апача
- sub apache2_vhosts_count
- {
- my @enabled = `/bin/ls -l /etc/apache2/sites-enabled 2>/dev/null | tail -n +2`;
- my @available = `/bin/ls -l /etc/apache2/sites-available 2>/dev/null | tail -n +2`;
- return @enabled . '/' . @available;
- }
-
- # проверяет конфиг апача
- sub apache2_configtest
- {
- my $tmp = `/usr/sbin/apache2ctl -t 2>&1`;
- #возвращаем результат
- return {'status' => $?,
- 'message' => $tmp};
- }
-
- # возвращает текстовую строку статуса апача
- sub apache2_status
- {
- my $result = linux_service('apache2', 'status');
- #возвращаем результат
- chomp $result->{'message'};
- return $result->{'message'};
- }
-
- # Добавляет vhost для апача. принимает:
- # строка $vhostsroot - корневая директория (/var/www)
- # строка $username - логин владельца vhost'а (домашняя директория пользователя, $vhostsroot . '/' . $username)
- # строка $servername - имя сервера (hostname)
- # строка|реф массив строк $alias - строка|строки алиасов домена
- # строка $adminemail - e-mail администатора домена
- sub apache2_add_vhost
- {
- my ($vhostsroot, $username, $servername, $alias, $adminemail) = @_;
- $vhostsroot =~ s/\/*$//;
-
- if (ref $alias eq 'ARRAY') {
- $alias = sprintf "@{$alias}";
- }
-
- my $vhost_config = '
- <VirtualHost *:8080>
- ServerName ' . $servername . '
- ServerAlias ' . $alias . '
- ServerAdmin ' . $adminemail . '
- AssignUserID ' . $username . ' ' . $username . '
- DocumentRoot ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . '
- CustomLog ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.access.log combined
- ErrorLog ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log
- DirectoryIndex index.php index.html index.htm
-
- AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
- AddType application/x-httpd-php-source .phps
-
- php_admin_value open_basedir "' . $vhostsroot . '/' . $username . '/data:."
- php_admin_value upload_tmp_dir "' . $vhostsroot . '/' . $username . '/data/tmp"
- php_admin_value session.save_path "' . $vhostsroot . '/' . $username . '/data/tmp"
-
- # runtime configuration
- php_value memory_limit "64M"
- php_value max_execution_time "300"
-
- # uploading configuration (memory_limit > post_max_size > upload_max_filesize)
- php_value upload_max_filesize "10M"
- php_value post_max_size "12M"
-
- # error handling
- php_value error_log "' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log"
- php_value error_reporting "7"
- php_flag display_errors "Off"
- php_flag log_errors "On"
-
- # directories configuration
- <Directory "' . $vhostsroot . '/' . $username . '/data/www/' . $servername . '/">
- AllowOverride All
- Options -Indexes
- </Directory>
- </VirtualHost>
- ';
-
- my $confname = '/etc/apache2/sites-available/' . $servername . '.conf';
- my $enabledname = '/etc/apache2/sites-enabled/' . $servername . '.conf';
-
- # создаем конфиг виртуалхоста
- open(my $fh, '>', $confname)
- or Logger::warn('Manager: could not open ' . $confname . ' for write!');
- print($fh $vhost_config);
- close($fh);
-
- # создаем симлинк на файл виртуалхоста
- symlink($confname, $enabledname);
- }
-
- # проверяет включен ли виртуалхост
- sub apache2_vhost_enabled
- {
- my ($vhost_filename) = @_;
- if (!-e '/etc/apache2/sites-available/' . $vhost_filename) {
- return 0;
- }
- if (!-e '/etc/apache2/sites-enabled/' . $vhost_filename) {
- return 0;
- }
- return 1;
- }
-
- # удаляет виртуалхост апача
- sub apache2_vhost_delete
- {
- my ($vhost_filename) = @_;
- if (-e '/etc/apache2/sites-enabled/' . $vhost_filename) {
- unlink('/etc/apache2/sites-enabled/' . $vhost_filename)
- or Logger::warn('Manager: could not unlink file ' . '/etc/apache2/sites-enabled/' . $vhost_filename);
- }
- if (-e '/etc/apache2/sites-available/' . $vhost_filename) {
- unlink('/etc/apache2/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not unlink file ' . '/etc/apache2/sites-available/' . $vhost_filename);
- }
- return 1;
- }
-
- # получает текст виртуалхоста
- sub apache2_vhost_get_text
- {
- my ($vhost_filename) = @_;
- return read_file('/etc/apache2/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not read file ' . '/etc/apache2/sites-available/' . $vhost_filename);
- }
-
- # устанавливает текст виртуалхоста
- sub apache2_vhost_set_text
- {
- my ($vhost_filename, $vhost_text) = @_;
- # обновляем конфиг виртуалхоста
- open(my $fh, '>', '/etc/apache2/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not open ' . '/etc/apache2/sites-available/' . $vhost_filename . ' for write!');
- print($fh $vhost_text);
- close($fh);
- }
-
-
- ##################################
- ### Функции для работы с nginx ###
- ##################################
- sub nginx_vhost_count
- {
- my @enabled = `/bin/ls -l /etc/nginx/sites-enabled 2>/dev/null| tail -n +2`;
- my @available = `/bin/ls -l /etc/nginx/sites-available 2>/dev/null| tail -n +2`;
- return @enabled . '/' . @available;
- }
-
- sub nginx_configtest
- {
- my $tmp = `/usr/sbin/nginx -t 2>&1`;
- #возвращаем результат
- return {'status' => $?,
- 'message' => $tmp};
- }
-
- sub nginx_status
- {
- my $result = linux_service('nginx', 'status');
- #возвращаем результат
- chomp $result->{'message'};
- return $result->{'message'};
- }
-
- # проверяет существует ли файл виртуалхоста в /etc/nginx/sites-available/
- sub nginx_vhost_exists {
- my ($file_name) = @_;
- return (-e '/etc/nginx/sites-available/' . $file_name) ? 1 : 0;
- }
-
- # Добавляет vhost для nginx. принимает:
- # строка $vhostsroot - корневая директория (/var/www)
- # строка $username - логин владельца vhost'а (домашняя директория пользователя, $vhostsroot . '/' . $username)
- # строка $servername - имя сервера (hostname)
- # строка|реф массив строк $alias - строка|строки алиасов домена
- sub nginx_add_vhost {
- my ($vhostsroot, $username, $servername, $alias) = @_;
- $vhostsroot =~ s/\/*$//;
-
- if (ref $alias eq 'ARRAY') {
- $alias = sprintf "@{$alias}";
- }
-
- my $vhost_config = '
- server {
- listen 80;
- server_name ' . $servername . ' ' . $alias . ';
- root ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . ';
- access_log ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.access.log;
- error_log ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log;
- index index.php index.html index.htm;
- error_page 500 502 503 504 /50x.html;
- server_name_in_redirect off;
- client_max_body_size 12M;
-
- location = /50x.html
- {
- root /var/www/nginx-default;
- }
-
- location /
- {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_pass http://127.0.0.1:8080;
- #proxy_redirect http://' . $servername . ':8080/ /;
- }
-
- location ~* ^.+\.(jpg|jpeg|gif|png|rar|txt|tar|wav|bz2|exe|pdf|doc|xls|ppt|bmp|rtf|js|ico|css|zip|tgz|gz)$
- {
- root ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . ';
- expires 30d;
- access_log off;
- }
-
- location ~ /\.ht
- {
- deny all;
- }
- }
- ';
-
- my $confname = '/etc/nginx/sites-available/' . $servername . '.conf';
- my $enabledname = '/etc/nginx/sites-enabled/' . $servername . '.conf';
-
- # создаем конфиг виртуалхоста
- open(my $fh, '>', $confname)
- or Logger::warn('Manager: could not open ' . $confname . ' for write!');
- print($fh $vhost_config);
- close($fh);
-
- # создаем симлинк на файл виртуалхоста
- symlink($confname, $enabledname);
- }
-
- # получает параметры виртуалхоста
- sub nginx_vhost_get
- {
- my ($vhost_filename) = @_;
- return {}
- if (!nginx_vhost_exists($vhost_filename));
-
- # вначале читаем vhost в массив
- my @vhost_lines;
- open my $fh, "<", "/etc/nginx/sites-available/" . $vhost_filename
- or Logger::warn('Manager: could not read file' . "/etc/nginx/sites-available/" . $vhost_filename);
- while (<$fh>) {
- chomp;
- push(@vhost_lines, $_);
- }
- close $fh;
-
- # собираем все свойства
- my $properties = {};
- my @directives;
-
- # парсим server_name
- @directives = grep(/server_name/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/server_name[\s]+(.*);/i;
- $properties->{'server_name'} = trim($1);
- }
- # парсим root
- @directives = grep(/root/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/root[\s]+(.*);/i;
- $properties->{'root'} = trim($1);
- }
- # парсим access_log
- @directives = grep(/access_log/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/access_log[\s]+(.*);/i;
- $properties->{'access_log'} = trim($1);
- }
- # парсим error_log
- @directives = grep(/error_log/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/error_log[\s]+(.*);/i;
- $properties->{'error_log'} = trim($1);
- }
- # парсим index
- @directives = grep(/index/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/index[\s]+(.*);/i;
- $properties->{'index'} = trim($1);
- }
- # парсим client_max_body_size
- @directives = grep(/client_max_body_size/i, @vhost_lines);
- if (defined($directives[0])) {
- $directives[0] =~ m/client_max_body_size[\s]+(.*);/i;
- $properties->{'client_max_body_size'} = trim($1);
- }
-
- return $properties;
- }
-
- # проверяет включен ли виртуалхост
- sub nginx_vhost_enabled
- {
- my ($vhost_filename) = @_;
- if (!-e '/etc/nginx/sites-available/' . $vhost_filename) {
- return 0;
- }
- if (!-e '/etc/nginx/sites-enabled/' . $vhost_filename) {
- return 0;
- }
- return 1;
- }
-
- # удаляет виртуалхост nginx
- sub nginx_vhost_delete
- {
- my ($vhost_filename) = @_;
- if (-e '/etc/nginx/sites-enabled/' . $vhost_filename) {
- unlink('/etc/nginx/sites-enabled/' . $vhost_filename)
- or Logger::warn('Manager: could not unlink file ' . '/etc/nginx/sites-enabled/' . $vhost_filename . '');
- }
- if (-e '/etc/nginx/sites-available/' . $vhost_filename) {
- unlink('/etc/nginx/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not unlink file ' . '/etc/nginx/sites-available/' . $vhost_filename . '');
- }
- return 1;
- }
-
- # получает текст виртуалхоста
- sub nginx_vhost_get_text
- {
- my ($vhost_filename) = @_;
- return read_file('/etc/nginx/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not read file ' . '/etc/nginx/sites-available/' . $vhost_filename);
- }
-
- # устанавливает текст виртуалхоста
- sub nginx_vhost_set_text
- {
- my ($vhost_filename, $vhost_text) = @_;
- # обновляем конфиг виртуалхоста
- open(my $fh, '>', '/etc/nginx/sites-available/' . $vhost_filename)
- or Logger::warn('Manager: could not open ' . $vhost_filename . ' for write!');
- print($fh $vhost_text);
- close($fh);
- }
-
-
-
-
- ##################################
- ### Функции для работы с MySQL ###
- ##################################
- sub mysql5_get_space
- {
- my @tmp = split /\s+/, `/usr/bin/du /var/lib/mysql -h --max-depth 0 2>/dev/null`;
- return $tmp[0];
- }
-
- sub mysql5_status
- {
- my $result = linux_service2('mysql', 'status');
- #возвращаем результат
- chomp $result->{'message'};
- return $result->{'message'}
- }
-
- # возвращает mysql пользователей
- sub mysql5_get_users
- {
- my $mysql_user = Conf::get('Manager.mysql_user');
- my $mysql_pass = Conf::get('Manager.mysql_pass');
- my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
- my $results = $dbh->selectall_hashref('SELECT * FROM `user` u WHERE u.User != "root" AND u.User != "debian-sys-maint" GROUP BY `User`', 'User');
- $dbh->disconnect();
- return $results;
- }
-
- # проверяет свободность логина
- sub mysql5_login_free {
- my ($login, $hostname) = @_;
-
- # проверяем на заполненность
- if (!length ($login) || !length ($hostname)) {
- return 0;
- }
-
- my $mysql_user = Conf::get('Manager.mysql_user');
- my $mysql_pass = Conf::get('Manager.mysql_pass');
- my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
- my @results = $dbh->selectrow_array('SELECT count(*) as `count` FROM `user` u WHERE `u`.`User`=\'' . $login . '\' AND `u`.`Host`=\'' . $hostname . '\' LIMIT 1');
- $dbh->disconnect();
- return ($results[0] > 0) ? 0 : 1;
- }
-
-
- # удаляет mysql пользователя без баз
- sub mysql5_del_user {
- my $login = shift();
- my $mysql_user = Conf::get('Manager.mysql_user');
- my $mysql_pass = Conf::get('Manager.mysql_pass');
- my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
- $dbh->do('DROP USER ' . $login);
- $dbh->disconnect();
- }
-
- # добавляет mysql пользователя
- sub mysql5_add_user {
- my ($login, $passw, $properties) = @_;
-
- if (!length ($login)) {
- return {'status' => 1,
- 'message' => 'user login not specified'};
- }
-
- if (!length ($passw)) {
- return {'status' => 1,
- 'message' => 'user passw not specified'};
- }
-
- my $mxucs = '0';
- my $mxuph = '0';
- my $mxqph = '0';
- my $mxcph = '0';
-
- # менять ли max updates per hour
- if (defined($properties->{'mxuph'}) && length($properties->{'mxuph'})) {
- $mxuph = $properties->{'mxuph'};
- }
- # менять ли max queries per hour
- if (defined($properties->{'mxqph'}) && length($properties->{'mxqph'})) {
- $mxqph = $properties->{'mxqph'};
- }
- # менять ли max connections per hour
- if (defined($properties->{'mxcph'}) && length($properties->{'mxcph'})) {
- $mxcph = $properties->{'mxcph'};
- }
- # менять ли max user connections
- if (defined($properties->{'mxucs'}) && length($properties->{'mxucs'})) {
- $mxucs = $properties->{'mxucs'};
- }
-
- my $mysql_user = Conf::get('Manager.mysql_user');
- my $mysql_pass = Conf::get('Manager.mysql_pass');
- my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
- $dbh->do('CREATE USER ' . $login . ' IDENTIFIED BY \'' . $passw . '\'');
- $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' IDENTIFIED BY \'' . $passw . '\' WITH MAX_QUERIES_PER_HOUR ' . $mxqph . ' MAX_CONNECTIONS_PER_HOUR ' . $mxcph . ' MAX_UPDATES_PER_HOUR ' . $mxuph . ' MAX_USER_CONNECTIONS ' . $mxucs);
- $dbh->do('FLUSH PRIVILEGES');
- $dbh->disconnect();
- }
-
- #изменяет mysql пользователя
- sub mysql5_update_user {
- my ($login, $properties) = @_;
-
- if (!length ($login)) {
- return {'status' => 1,
- 'message' => 'user login not specified'};
- }
-
- my $passw = '';
- my $mxucs = '';
- my $mxuph = '';
- my $mxqph = '';
- my $mxcph = '';
-
- # менять ли пароль
- if (defined($properties->{'passw'}) && length($properties->{'passw'})) {
- $passw = $properties->{'passw'};
- }
- # менять ли max updates per hour
- if (defined($properties->{'mxuph'}) && length($properties->{'mxuph'})) {
- $mxuph = $properties->{'mxuph'};
- }
- # менять ли max queries per hour
- if (defined($properties->{'mxqph'}) && length($properties->{'mxqph'})) {
- $mxqph = $properties->{'mxqph'};
- }
- # менять ли max connections per hour
- if (defined($properties->{'mxcph'}) && length($properties->{'mxcph'})) {
- $mxcph = $properties->{'mxcph'};
- }
- # менять ли max user connections
- if (defined($properties->{'mxucs'}) && length($properties->{'mxucs'})) {
- $mxucs = $properties->{'mxucs'};
- }
-
- # выполняем действия
- my $mysql_user = Conf::get('Manager.mysql_user');
- my $mysql_pass = Conf::get('Manager.mysql_pass');
- my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
- my $updated = 0;
- if (length($passw)) {
- $dbh->do('SET PASSWORD FOR ' . $login . ' = PASSWORD(\'' . $passw . '\')');
- $updated = 1;
- }
- if (length($mxucs) && ($mxucs =~ m/^[\d]+$/)) {
- $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_USER_CONNECTIONS ' . $mxucs);
- $updated = 1;
- }
- if (length($mxcph) && ($mxcph =~ m/^[\d]+$/)) {
- $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_CONNECTIONS_PER_HOUR ' . $mxcph);
- $updated = 1;
- }
- if (length($mxqph) && ($mxqph =~ m/^[\d]+$/)) {
- $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_QUERIES_PER_HOUR ' . $mxqph);
- $updated = 1;
- }
- if (length($mxuph) && ($mxuph =~ m/^[\d]+$/)) {
- $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_UPDATES_PER_HOUR ' . $mxuph);
- $updated = 1;
- }
- if ($updated) {
- $dbh->do('FLUSH PRIVILEGES');
- }
- $dbh->disconnect();
- }
-
-
-
-
- #################################
- ### Функции для работы с php5 ###
- #################################
- sub php_get_version
- {
- my $version = `/usr/bin/php -r 'echo phpversion();' 2>/dev/null`;
- chomp $version;
- return $version;
- }
-
-
-
- # вспомогательная функция тримящая пробелы и кавычки
- sub trim
- {
- my($string) = @_;
- if (!defined($string)) {
- $string = '';
- }
- for ($string) {
- s/^[\s'"]+//;
- s/[\s'"]+$//;
- }
- return $string;
- }
-
- return 1;
|