Архив за месяц: Март 2015

Как добавить https на сайт с сервером apache

В данной статье расскажу как пошагово установить ssl сертификат на apache (вариант easy, без заморочек)

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

openssl req -new -x509 -days 30 -keyout server.key -out server.pem

однако в данном варианте у ваших посетителей в браузере появится отпугивающее предупреждение о недоверии к сайту. Чтобы этого не было, надо обратиться к компании, в которой выдают проверенные сертификаты. К счастью сейчас есть варианты, когда можно бесплатно получить сертификат. Но обычно (особенно для коммерческого использования и для юридических лиц) за сертификат придется выложить денежку, причем цена сильно варьируется в зависимости от типа сертификата, количество доменов итд итп. Я воспользовался сервисом wosign и получил халявный сертификат на 3 года :) Таким образом после первого шага у нас есть 2 ключа: открытый *.crt (расширение может быть другое, например pem) и закрытый *.key.

2. Открытый ключ кладем в папку /etc/ssl/certs/ , закрытый в папку /etc/ssl/private/

3. Настраиваем виртуальный хост для нашего сайта. Для этого идем в /etc/apache2/sites-available/ и открываем на редактирование mysyte.ru.conf

4. В открытом конфигурационном файле есть тег <VirtualHost *:80>. Копируем все содержимое этого тега и создаем точно такой же, но вместо *:80 пишем <VirtualHost *:443> . После этого осталось добавить 3 важные строчки:

SSLEngine on
# Публичный сертификат
SSLCertificateFile    /etc/ssl/certs/*.pem
# Приватный ключ
SSLCertificateKeyFile /etc/ssl/private/*.key

5. На последнем шаге делаем стандартную операцию «[sudo] service apache2 restart» и любуемся на сайт в https .

Простой анализ лог файла access.log apache на php

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

  1. десять IP адресов, с которых идет больше всего запросов
  2. десять самых популярных страниц

Данную задачу я даю студентам для ознакомления с регулярными выражениями. Одно регулярное выражение должно выбирать айпи адрес с начала строки, а над вторым надо немного пофантазировать. Для написания программы прежде всего следует ознакомиться со структурой access.log.  Приведем типичную строку из файла логов apache, который имеет следующую структуру (Combined Log Format).

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"

Как видим логируется айпишник с которого идет запрос (127.0.0.1), время запроса, метод (GET), URL запроса, статус ответа (200), количество байт (2326), referrer, информация о браузере и операционной системе.

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

<?php
//считываем файл
$text=file_get_contents('access.log');
//задаем шаблон регулярного выражения
$pattern='#(([0-9]{1,3}\.){3}[0-9]{1,3}).{1,}GET ([0-9a-z/\_\.\-]{1,})#i';
//вытаскиваем данные в массив matches
preg_match_all($pattern,$text,$matches);
$ip=array_count_values($matches[1]);
$adr=array_count_values($matches[3]);
//сортируем по убыванию
arsort($ip);
arsort($adr);
//выделяем десятку
$ip_10=array_slice($ip,0,10);
$adr_10=array_slice($adr,0,10);

echo "10 самых активных пользователей по ip адресу";
echo "IP Количество\n";
foreach($ip_10 as $key=>$value)
{
	echo $key.' '.$value;
}

echo "10 самых посещаемых страниц\n";
echo "Страница Количество\n";
foreach($adr_10 as $key=>$value)
{
	echo $key.' '.$value;
}

Исследуем НГУ на самый холостяцкий факультет с помощью VK API

В данном посту опишу пример использования API метода вконтакте users.search и, чтобы было интереснее, приложение будет определять самый холостяцкий факультет в Новосибирском государственном университете. Обычно считается, что обучение на определенном факультете откаладывает на поведении человека некоторый отпечаток. Попробуем выяснить влияет ли как-то факультет на семейное положение на примере данных из сайта «вконтакте». Для самых нетерпеливых сразу график. По оси X — возраст, по оси Y — процент холостяков. Подсказка: по легенде можно кликать, тем самым включая или выключая график для выбранного факультета.

Выборку по возрасту взял с 21 года до 32ух лет. Для каждого возраста-факультета выбиралось общее количество человек и количество тех, у кого в статусе указано «не женат». Используя эти 2 цифры можно получить число холостых в процентах, что собственно и отображено на графике.

Как видно из графика — тенденция на уменьшение холостяков с возрастом есть почти для всех факультетов, но не сильно заметная, как ожидал. Наиболее явно это прослеживается на самом многочисленном факультете — ММФ. Но например если взять юридический факультет, то тут неожиданно обратная картина. В данном случае экономический факультет выглядит определенным углоком стабильности, количество холостяков в любом возрасте примерно 20% .

Меня немного удивил пик на физическом факультете при возрасте в 27 лет. Сделал соответсвующий запрос для проверки и действительно 67 из 180 холостые. (картинка кликабельна)холостяки Физфака VK API

Ниже приведен прокомментированный код для получения данных, отображенных на графике. Из примечаний могу сказать, что сервера вконтакте обрабатывают не больше 3ёх запросов в секунду, поэтому задержка необходима (есть ещё вариант смотреть в сторону метода execute). Массив факультетов брал, используя стандартный поиск в вконтакте, подсмотрев данный параметр в url строке.

    //определяем массив факультетов
    var departments = [
     1640, // - MMF
     1641, // - FF
     1642, // - ГГФ
     1643, // - ФЕН
     1644, // - ГФ
     1645, // - ЖФ
     1646, // - филосовский
     1647, // - юридический
     1648, // - экономический
     1649, // - ФИТ
     1650, // - психологии
     1651, // - ИнЯз
     1652 // - медицинский
    ]
    //определяем массив возрастов(по году рождения)
    var ages = []
    for (var i=21; i<33; i++){         ages.push(i);     }     // массив статусов по семейному положению 1 — Не женат, 2 — Встречается, 3 — Помолвлен, 4 — Женат, 7 — Влюблён, 5 — Всё сложно, 6 — В активном поиске.     var statuses = [1/*,2,3,4,5,6,7*/]     // массив всех параметров запроса к API     var ALL_PARAMS = []     for (var yy in ages){         for (var ss in statuses){             for (var ff in departments){                 var pp = new Object();                 pp.university = '671' //              pp.has_photo = 1                 pp.university_faculty = departments[ff]                 pp.sex = 2//1-women, 2-men                 pp.status = statuses[ss]; //                pp.birth_year = ages[yy]                 pp.age_from = ages[yy]                 pp.age_to = ages[yy]                 pp.count = 0                 ALL_PARAMS.push(pp)             }         }     }     //now works without statuses     function makeChartData(num, sum){         var chartOut = []         var res_index = 0;         for (var yy in ages){             var lineOut = [ages[yy]]             for (var ff in departments){                 if (sum[res_index] == 0){                     var chartPercent = 0                 }else{                     var chartPercent = (num[res_index]*1.)/(sum[res_index]*1.)                 }                 lineOut.push(chartPercent)                 res_index++;             }             chartOut.push(lineOut)         }         return chartOut;     }     var finalResult = [];     var finalResultSum = [];     var chartData = null;     VK.init(function() {         // API initialization succeeded         // Your code here         var current_param = 0;         var repeatIt = setInterval(function(){             if (current_param>=ALL_PARAMS.length){
                //destroy interval if no more need
                clearInterval(repeatIt);
                $('#debug').text( finalResult.join(",") )
                $('#sum').text( finalResultSum.join(",") )
                chartData = makeChartData(finalResult, finalResultSum)
                $('#chartData').text( JSON.stringify(chartData) )
                console.log(chartData)
                return;
            }
            VK.api('users.search',ALL_PARAMS[current_param],function(data) {
                if (data.response){
                    finalResult.push(data.response.count);
                    console.log(finalResult)
                }else{
                    //выдаст ошибку, если что-то пошло не так
                    console.log(data)
                }
            })
            //подсчитываем общее количество
            var qNoStatus = JSON.parse( JSON.stringify( ALL_PARAMS[current_param] ) );
            qNoStatus.status = 0
            VK.api('users.search', qNoStatus, function(data) {
                if (data.response){
                    finalResultSum.push(data.response.count);
                    console.log(finalResultSum)
                }else{
                    console.log(data)
                }
            })
            current_param++;
            //небольшая задержка, чтобы не заблокировали за бомбежку запросами (Too many requests per second)
        }, 2500);

    }, function() {
        // API initialization failed
        // Can reload page here
    }, '5.28');

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

Не следует сильно серьёзно относится к данному мини исследованию, оно лишь дает некоторое представление, так как основаны на данных, взятых из социальной сети. А она, как известно, полна ботами. Кому нужны официальные данные — добро пожаловать в росстат :)

Есть пожелания, комментарии, выводы по графику, идеи — пишите  vk.com/id12982