Здравствуй, уважаемый %user%. Сегодня я расскажу о том, как я написал простую систему позволяющую получать конфигурацию компьютеров и информацию о том, кто залогинился на компьютерах на работе, и как я перенес ее на Amazon AWS, сделав сервис для общего пользования. Данную статью так же можно считать отчасти подробным руководством о том как поднять свой веб сервер, почту, рассылку писем и правильно настроить его на Amazon AWS. И да эту статью можно отнести к категории – я пиарюсь. Кому стало интересно добро пожаловать под кат. Осторожно будет очень много скриншотов.
Предыстория
Однажды к нам в хелпдеск поступил звонок от заведующего складом. Ответил на его звонок я. Он спросил у меня о том что, можно ли найти компьютер по серийному номеру. Он не мог найти, кто этим компьютером пользуется, на что я ответил это конечно невозможно. Этот разговор навел меня на мысль, а что если создать систему, в которой показывалась бы вся конфигурация компьютера, включая его серийный номер и кто на нем залогинился. Написать клиентское приложение на C#, отправлять все на веб сервер с простеньким интерфейсом для контроля над всем этим.
Серверная часть
Попросил системных администраторов выделить отдельный сервер на Windows Server 2012 R2. Установил на него XAMPP. Добавил Apache и Mysql в службы, чтобы в случае перезагрузки сервера сайт не полег. Создал базу данных «opermon», добавил таблицы.
Веб интерфейс написан с помощью самописного mvc движка. Структура проекта:
- Configs – здесь хранится конфигурационный файл для связи с БД
- Controllers – здесь хранятся классы
- Locale — локализация
- Views – сами страницы, со стилями, картинками и javascript-ами
В корневой папке создадим файл index.php напишем код:
<?php
session_start();
spl_autoload_register(function ($class){
include './app/controllers/' . $class . '.php';
});
$api = new Api($_GET);
$controller = new Controller($_GET, $_POST);
?>
В папке Controllers есть много классов описывающих поведение системы. Одним из важных классов является класс Controller.php. Этот класс является контроллером, который принимает GET и POST запросы в __construct($get, $post) из index.php. Получив определенный запрос он показывает определенную страницу.
Класс Api служит для получения ajax запросов и обработку их. Консоль управления системы загружается всего лишь один раз. Все последующие действия осуществляются с помощью javascript и ajax запросов.
Дизайном системы я вдохновился от Microsoft Azure. Нижу приведу скриншоты финального результата:
Следует отметить, что перед тем как сделать коммерческую версию на Amazon AWS, я полностью переписал систему сделав ее более безопасной, ориентированной на общее использование и часть функций просто убрал из-за ненадобности, но суть осталась одна и та же.
Клиентская часть
Клиентская часть данной системы – это простое приложение службы написанное на c#. При загрузке служба открывает файл конфигурации расположенное по адресу %windows_path%\OperMonitorSystem.xml. Структура данного xml файла:
<OperMonitorSystem>
<Server>http://servername/</Server>
</OperMonitorSystem>
Чтобы служба могла отлавливать события сессии пользователя, следует добавить в инициализацию службы:
this.CanHandleSessionChangeEvent = true;
Следует добавить функцию, которая отлавливает изменения сессии:
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
switch (changeDescription.Reason)
{
case SessionChangeReason.SessionLogon:
//ваше действие
break;
case SessionChangeReason.SessionLogoff:
//ваше действие
break;
case SessionChangeReason.SessionLock:
//ваше действие
break;
case SessionChangeReason.SessionUnlock:
//ваше действие
case SessionChangeReason.RemoteConnect:
//ваше действие
case SessionChangeReason.RemoteDisconnect:
//ваше действие
}
base.OnSessionChange(changeDescription);
}
Используя класс WebClient на сервер отправляется POST запрос. Для получения конфигурации компьютера используются WMI запросы.
Клиентскую часть можно установить вручную на каждый компьютер (если их не много) или развернуть по групповой политике.
Идея о создании сервиса возникла после того как я написал эту статью, а если точнее после этих комментариев:
Во время переписывания системы прошлось ввести некий уникальный код для каждого пользователя – hashid. Это некая последовательность случайных цифр и букв записанных через тире, которая создается один раз при регистрации пользователя. Hashid по виду очень напоминает серийный ключ операционных систем семейства Windows. Каждому пользователю после оплаты нужной подписки скидывается установщик, в котором прописан его уникальный hashid. Именно по этому hashid в БД заносятся данные и это даст гарантию того, что посторонний пользователь не сможет увидеть компьютеры другого пользователя.
Систему я решил поставить на Amazon AWS. Amazon AWS дает год бесплатного пользования всеми возможностями системы, конечно не без ограничений. Регистрируемся на Amazon AWS. Во время регистрации к вам на мобильный телефон придет звонок для подтверждения аккаунта. Во время звонка вы должны будете набрать цифры на телефоне. К сожалению регистрация таким образом у меня не получилась. Я набирал требуемые цифры, но автоответчик все требовал набрать цифры и ничего не происходило. Тогда я обратился к службе поддержки, описал им свою ситуацию. Они назначили проверку личности по звонку с работником поддержки. Вскоре мне позвонил работник поддержки удостоверился что это я и подтвердил мой аккаунт. Следует отметить, что тех поддержка Amazon очень вежливая и лояльна к пользователям. Переходим к самому интересному – настройке Amazon AWS. Все что написано ниже мне удавалось путем долгих поисков проб и ошибок. Пользуясь этим руководством можно полностью все настроить и поднять не прибегая к поиску или еще чего-то.
Настройка Amazon AWS
Route 53
Сперва нам нужно купить доменное имя. Я выбрал opermon.com. Почему именно opermon:
- Oper – от слова operator
- Mon – от слова monitor
- Заходим на Route 53
- Нажимаем на кнопку “Create Hosted Zone”. Справа в меню вписываем адрес, комментарий и выбираем “Public Hosted Zone”. Public Hosted Zone – означает, что имя написанное вами будет доступно всему миру. Следует отметить что аренда доменного имени в Amazon AWS обходится разными ценами. В моем случае обошлось в 12 американских долларов. Оплачивается раз в год. В течении 24 часов доменное имя уже будет готово к использованию.
Amazon EC2
- Заходим в EC2
- Выбираем пункт справа «Instances»
- Нажимаем “Launch Instance”
- Ставим галочку «Free tier only» и выбираем «Select» как показано на скриншоте.
- Нажимаем «Next: Configure Instance Details»
- Нажимаем «Next: Add storage»
- Указываем размер диска. В моем случае 8 гигабайт хватает. Нажимаем «Next: Add tags»
- Нажимаем «Next: Configure Security Group»
- Нажимаем «Add new rule». Выбираем из списка HTTP, Source выбираем Anywhere. Данная процедура нужна чтобы, когда мы установили на нашем сервере apache, то снаружи был бы доступ к нашему веб сайту. Нажимаем «Review and Launch».
- Нажимаем на кнопку «Launch».
- В данном окне выбираем из выпадающего списка «Create a new key pair», вводим имя и нажимаем на кнопку «Download Key Pair». После чего кнопка «Launch Instances» станет активной. Скачанный .pem файл нужно скопировать на разные места для хранения. Терять данный файл ни в коем случае нельзя. Используя этот pem файл мы будем подключаться к нашему инстансу через WinSCP и Putty (далее в статье будет описание как их настроить).
- Через 5 минут наш сервер поднимется и мы сможем к нему подключиться. Стандартная учетная запись «ec2-user». Настроим так чтобы при наборе адреса в браузере, открывался веб-сайт поднятый(далее будет описание как его настроить) на нашем серваке. Переходим в раздел «Instances», выбираем виртуальную машину, которую мы только что создали и смотрим на «Public DNS» и Public IPv4 адрес. У меня выглядит это так:
Скопируем себе это данные. Сейчас он нам понадобятся
- Заходим на Route 53. Выбираем купленный нами домен. Выбираем первую A запись. В правом меню добавляем Public IPv4 адрес нашего инстанса.
- Нажимаем «Create record set». В правом открывшемся боковом меню из списка выбираем «Cname — canonical name». В поле «Name» вписываем «www». В поле «Value» вписываем «Public DNS» адрес нашего инстанса и нажимаем «Create»
Изменения вступят в силу в течении 24 часов.
Настроим приложение Putty и WinSCP
Начнем с Putty. Скачиваем Putty на компьютер и устанавливаем его.
- Открываем сперва Puttygen (приложение находится в меню пуск, в папке Putty). Нажимаем «Load» и выбираем .pem файл, которого мы скачали когда поднимали EC2 инстанс:
- Нажимаем на кнопку «Save private key» и сохраняем файл
- Открываем Putty. В «Host name» записываем «Ip» адрес или «Public dns» адрес инстанса
- Слева в меню выбираем раздел Connection->SSH->Auth и выбираем .ppk файл, которого мы только что создали в Puttygen.
- Слева в меню заходим в раздел Session, вводим текст «linux» в поле «Saved sessions» и нажимаем на кнопку «Save». В списке сессий мы увидим, как добавилась «linux».
- Таким образом следующий раз чтобы подключиться к серверу нам нужно будет просто выбрать только что сохраненную конфигурацию и нажать на кнопку Open.
Перейдем к WinSCP. Скачиваем WinSCP на компьютер и устанавливаем его.
- В «Имя хоста» записываем «Ip» адрес или «Public dns» адрес инстанса. Имя пользователя вводим «ec2-user». Пароль оставляем пустым. Нажимаем на кнопку «Ещё»
- В меню Аутентификация выбираем .ppk файл и нажимаем «ОК»
- Нажимаем на кнопку «Сохранить» чтобы следующий раз не настраивали подключение. Мы увидим, как слева в меню добавилось подключение
Amazon RDS
Создадим реляционную базу данных mysql.
- Открываем Amazon RDS
- Нажимаем на кнопку «Select»
- Выбираем Dev/Test, и нажимаем «Next Step»
- Вводим идентификатор базы данных (у меня opermon), имя пользователя и пароль. Нажимаем «Next step»
- Выбираем VPC, который создался при создании EC2 инстанса, задаем имя нашей БД и нажимаем «Launch DB instance»
- Перейдем в консоль управления RDS в раздел «Instances». Через 5 минут наша база данных станет доступной и на месте Endpoint будет написан адрес нашего БД. Он нам понадобится.
Настраиваем наш инстанс
Открываем Putty и подключаемся к нашему инстансу
- Устанавливаем apache
sudo yum install -y httpd24 php56 php56-mysqlnd
- После установки запускаем его
sudo service httpd start
- Даем доступ себе в папку www
sudo groupadd www sudo usermod -a -G www ec2-user
- Выходим из программы Putty и заново подключаемся к нашему инстансу и задаем команды
sudo chmod 2775 /var/www find /var/www -type d -exec sudo chmod 2775 {} + find /var/www -type f -exec sudo chmod 0664 {} +
Теперь в WinSCP мы можем заходить в директорию /var/www/ и загружать туда наш веб-сайт, движок, html – да что угодно.
Устанавливаем phpmyadmin
Открываем Putty и подключаемся к нашему инстансу
- Устанавливаем phpmyadmin
sudo yum-config-manager --enable epel sudo yum install -y phpMyAdmin
- Находим свой внешний ip пользуясь посторонними сервисами и пишем команду
sudo sed -i -e 's/127.0.0.1/ваш_айпи_адрес/g' /etc/httpd/conf.d/phpMyAdmin.conf
Если ваш ip поменялся, то пишем команду
sudo tail -n 1 /var/log/httpd/access_log | awk '{ print $1 }' здесь_будет_ваш_старый_айпи sudo sed -i -e 's/ваш_старый_айпи/новый_айпи/g' /etc/httpd/conf.d/phpMyAdmin.conf
- Перезагружаем apache сервер чтобы изменения вступили в силу
sudo service httpd restart
- Теперь нужно настроить phpmyadmin, чтобы он подключался к нашей БД
sudo chmod -R 777 /etc/phpMyAdmin
- Открываем WinSCP, заходим по адресу /etc/phpmyadmin копируем себе файл config.inc.php и открываем его в любом текстовом редакторе. Находим показанные ниже строки и меняем их на свои:
$cfg['Servers'][$i]['host'] = 'Endpoint адрес нашей БД без порта'; $cfg['Servers'][$i]['port'] = '3306'; $cfg['Servers'][$i]['user'] = 'имя пользователя'; $cfg['Servers'][$i]['password'] = 'пароль';
- Сохраняем файл и перезаписываем его на сервер. Выйдет ошибка о том, что файл перезаписан, но атрибуты изменены не были. Нажимаем «пропустить» и вводим команду в Putty:
sudo chmod -R 755 /etc/phpMyAdmin
Если эту команду не сделать, то Phpmyadmin откажется открываться ссылаясь на то, что права доступа на файлы были изменены и не соответствуют политике безопасности.
Настроим WorkMail
- Сделаем поиск по консоли Amazon AWS и найдем WorkMail
- Выбираем Add Organization
- Нажимаем «Quick setup»
- Вводим имя организации и нажимаем на «Create». В моем случае организация уже создана, поэтому я нажму на «opermon» в списке на втором скриншоте.
- Переходим в раздел «Domains» и нажимаем «Add domain»
- Вводим имя домена и нажимаем «Add domain»
- Откроется страница, в которых все записи нужно вписать в Route 53, в настройках нашего доменного имени. Написать настройки я думаю вы сможете сами.
После этого возвращаемся сюда
- Переходим в раздел «Users» нажимаем «Create user»
- Вводим имя, фамилию, отображаемое имя и нажимаем «Next step»
- Задаем email адрес, из списка выбираем ваш домен.com, задаем пароль и нажимаем «Add user»
Теперь мы можем зайти в почту зайдя в адрес ваш_домен.awsapps.com/mail.
Настроим Amazon SES
- Открываем Amazon SES, переходим в раздел «Domains» и нажимаем на «Verify a new domain». В открывшемся окне вводим адрес (В моем случае это opermon.com) и нажимаем на «Verify this domain»
- Откроется данное окно. Данные записанные в этом окне нужно будет опять таки вписать в Route 53
- Переходим в раздел Email addresses и нажимаем «Verify a New Email Address», вводим email адрес ранее созданный в WorkMail и нажимаем на «Verify This Email Address». Через некоторое время к нам на указанный адрес придет письмо с ссылкой подтверждения. Открываем почту и нажимаем на ссылку подтверждения. Данная процедура нужна, чтобы в служебных письмах посылаемых нашим веб сайтом, системой и прочим мы могли бы использовать созданный ранее в WorkMail-е адрес отправителя.
- Переходим в раздел «Create my SMTP credentials». Адрес SMTP сервера следует записать где-то.
- Нажимаем «Create»
- Учетная запись создалась, копируем логин и пароль и храним где-то. Они нам тоже понадобятся.
Настроим скрипт отправки писем
В своем самописном движке есть класс Mail. Выглядит он таким образом:
<?php
require_once('app/class/mail/PHPMailerAutoload.php');
class OpermonMail
{
public static function SendMail($subject = 'none', $email, $name, $surname, $text_body = '', $text_altbody = '')
{
$config = parse_ini_file('app/config/mail.ini');
$mail = new PHPMailer;
$mail->isSMTP();
$mail->Host = $config['MAIL_HOST'];
$mail->SMTPAuth = true;
$mail->Username = $config['MAIL_USERNAME'];
$mail->Password = $config['MAIL_PASSWORD'];
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->setFrom($config['MAIL_SETFROMEMAIL'], $config['MAIL_SETFROMNAME']);
$mail->addAddress($email, $name.' '.$surname);
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $text_body;
$mail->AltBody = $text_altbody;
if(!$mail->send())
{
return $mail->ErrorInfo;
}
else
{
return true;
}
}
}
?>
Как видно из кода используется PHPMailer. Сможете найти вы его на github-е.
И так наконец после этого всего, система заработала. При регистрации пользователям отправляется код подтверждения (не даром мы возились с Amazon SES и WorkMail), открывается сам веб-сайт(Amazon EC2 с установленным на нем apache) и можно видеть записи в БД (phpmyadmin). Прилагаю скриншоты готовой системы:
К большому сожалению как сделать сбор установщика в самой системе я не знаю. Плюс в стране в, которой я живу не поддерживается тип бизнес аккаунта PayPal, поэтому не смог написать функцию оплаты прямо в системе. Эти аспекты я вынужден делать вручную.
Спасибо всем за внимание!
Комментарии (18)
fleaump
24.08.2017 09:59Это просто для инвентаризации? Тогда надо интегрировать с системами общего учета. И в чем отличие от бесплатной OCS Inventory, которая легко раскидывается через AD.
Как создать MSI пакет для распространения через ADAkshinM Автор
25.08.2017 23:36Это просто для инвентаризации?
для себя тоже. иногда пользователь отдаленный от компьютерных знаний не может сказать имя компьютера. приходится самому искать по логину.
Как создать MSI пакет для распространения через AD
MSI установщик клиентской части приложения есть. просто я не знаю как сделать так чтобы пользователи сами могли бы через веб-сайт собирать для себя установщик тупо нажав одну кнопку
CheBurashka
24.08.2017 20:42Пока читал никак не покидала мысль — а почему не glpi в паре с fusioninventory? Почему своё стали пилить?
AkshinM Автор
24.08.2017 20:56я даже не знал о существовании такого, да и самописное более под контролем чтоли
San911mustday
24.08.2017 20:42-1Столько всего сделано- интересно почитать! Возьму на заметку =) Спасибо!
Yo1
24.08.2017 20:42и сколько такое будет стоить после 12 месяцев?
AkshinM Автор
24.08.2017 20:43~70 долларов в месяц. это я еще с запасом взял
Yo1
25.08.2017 00:04я сейчас читаю про google app engine, там вроде деньги снимают только если есть запрос, у AWS нет что либо подобного? что бы за только за запрос платить, а не за VM, которая 90% времени ничего не делает?
AkshinM Автор
25.08.2017 00:24смотря что. Например Amazon SES берет определенную плату за 1000 сообщений опять там условия могут меняться. В вашем случае за виртуалку установлена фиксированная цена в час. и им пофиг что она простаивает 90% времени
MetaDone
Мне кажется вы переизобрели OCS Inventory
Добавить пару плагинов типа
https://github.com/PluginsOCSInventory-NG/winusers/releases и получится что ваша задача будет решена готовыми средствами