My blog http://v-alexeev.ru Yes, it is my blog Tue, 23 Aug 2016 11:33:22 +0000 ru-RU hourly 1 https://wordpress.org/?v=4.6.23 SAMS перестал считать трафик, решение проблемы http://v-alexeev.ru/sams-offset/ http://v-alexeev.ru/sams-offset/#comments Thu, 27 Sep 2012 10:50:48 +0000 http://v-alexeev.ru/?p=166 Читать далее »

]]>
Столкнулся со следующей проблемой: SAMS работал-работал и вдруг перестал считать трафик. В базе данных в таблицу squidcache ничего не пишется. Полдня искал проблему (поиск в интернете упорно ничего не давал) и всё-таки нашёл: отрицательный offset (смещение с начала файла) у access.log.

Как узнать, что у вас такая же проблема?

  1. На странице настроек прокси в веб-интерфейсе SAMS (SQUID -> Название прокси-сервера, по умолчанию Proxy server) посмотреть строчку «Смещение с начала файла access.log (byte)». Если там отрицательное число — значит у вас такая проблема.
  2. Запустить sams2daemon --config=/usr/local/etc/sams2.conf --no-fork --debug=10 --logger=console (по умолчанию находится в директории /usr/local/bin). Сразу после запуска он начнёт парсить access.log и вскоре будет подобная строчка: squidlogparser.cpp:149 [0x9bb4348->parseFile] file size 64743249, use offset 4661223. Если здесь «use offset» отрицательный — значит у вас такая проблема.

Как исправить?

Зайти в базу SAMS (обычно sams2db) в консоли БД и исправить параметр s_endvalue (например, поставить туда 1) у нужного прокси (таблица proxy). Если в вашей конфигурации всего 1 прокси, то проще всего это сделать командой update proxy set s_endvalue=1;

После этого необходимо перезапустить sams2daemon, иначе новые настройки он не подхватит!

]]>
http://v-alexeev.ru/sams-offset/feed/ 8
(English) MongoDB-specific widgets for Django admin app http://v-alexeev.ru/django_mongodb_extras/ http://v-alexeev.ru/django_mongodb_extras/#respond Sat, 16 Jun 2012 14:45:00 +0000 http://v-alexeev.ru/?p=145 Извините, эта запись доступна только на English

]]>
http://v-alexeev.ru/django_mongodb_extras/feed/
Как установить SAMS2 и Squid на Ubuntu 12.04 LTS с авторизацией через AD http://v-alexeev.ru/sams-squid-ubuntu-12-04/ http://v-alexeev.ru/sams-squid-ubuntu-12-04/#comments Tue, 12 Jun 2012 09:49:01 +0000 http://v-alexeev.ru/?p=129 Читать далее »

]]>
В качестве базы данных будем использовать MySQL. В качестве веб-сервера nginx + php5-fpm.

  1. Устанавливаем все необходимые для нас пакеты: sudo apt-get install build-essential squid3 nginx php5-fpm libpcre3-dev libpcre3 libpcre++-dev libpcre++0 libpcrecpp0 mysql-server libmysqlclient-dev php5-ldap libfpdf-tpl-php libfpdi-php autoconf automake libtool doxygen libldap2-dev php5-gd php5-mysql krb5-user libkrb5-3 ldap-utils samba winbind samba-common-bin
  2. Получаем исходники SAMS2: wget https://github.com/PavelVinogradov/sams2/archive/master.zip
    Распаковываем: unzip master.zip
  3. Собираем скрипт конфигурации: make -f Makefile.cvs
  4. ./configure
    По окончании работы скрипта вы должны увидеть следующее сообщение:Use MySQL API: yes
    Use PostgreSQL API: no
    Use unixODBC API: no
    Use LDAP API: yes
    Using pcre: pcre
    Use dynamic plugin: yes
  5. Файл libtool, который генерирует скрипт, нуждается в патче. Набираем «patch -l» и вставляем следующий текст. В конце нужно два раза нажать Ctrl-D, чтобы он понял, что это конец файла.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    --- libtool.old 2012-02-14 17:34:10.363994833 +0400
    +++ libtool     2012-02-14 15:55:27.142358890 +0400
    @@ -5986,7 +5986,8 @@
            case $dir in
            [\\/]* | [A-Za-z]:[\\/]*) ;;
            *)
    -         absdir=`cd "$dir" && pwd`
    +#        absdir=`cd "$dir" && pwd`
    +         absdir="/usr/lib"
              test -z "$absdir" && \
                func_fatal_error "cannot determine absolute directory name of \`$dir'"
              dir="$absdir"
  6. Если у вас 64-битная система, то файл src/proxy.h нуждается в исправлении, иначе sams2daemon будет падать с ошибкой сегментирования после «mysqlquery.cpp:437 [0x1c1f910->fetch] ok». Для этого открываем src/proxy.h и дописываем ко всем enum тип long следующим образом:
    1
    2
    3
    4
    
    enum ParserType: long
    {
    ...
    };

    (спасибо за этот метод решения проблемы с 64 битами Владимиру)

  7. Собираем SAMS2: make
  8. Устанавлиаваем: sudo make install
  9. Меняем владельца директории sams2 на www-data: sudo chown www-data:www-data -R /usr/local/share/sams2/
  10. Конфигурируем nginx следующим образом:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    server {
            listen   80;
     
     location / {
            root /usr/local/share/sams2;
            index index.php;
            if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php?q=$1 last;
                break;
            }
        }
     
        error_page 404 /index.php;
     
        location ~ .php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
     
            fastcgi_param SCRIPT_FILENAME /usr/local/share/sams2/$fastcgi_script_name;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
        }
     
    }
  11. Заходим на http://localhost/setup.php там всё делаем по инструкции
  12. Записываем в файл /usr/local/etc/sams2.conf параметры подключения к базе данных:
    имя пользователя для подключения к базе данных
    DB_USER=username
    пароль
    DB_PASSWORD=userpassword
    Также в этом файле нужно поменять пути к squid:
    SQUIDROOTDIR=/etc/squid3
    SQUIDLOGDIR=/var/log/squid3
  13. Делаем symlink (иначе sams не будет работать): sudo ln -s /usr/sbin/squid3 /usr/sbin/squid
  14. Копируем из папки с исходниками скрипт для init.d: sudo cp debian/init.d /etc/init.d/sams2daemon
  15. Даём права на исполнение: sudo chmod a+x /etc/init.d/sams2daemon
  16. Редактируем скрипт /etc/init.d/sams2daemon
    Нужно прописать правильный путь к конфигу sams:
    SAMSPATH=`cat /usr/local/etc/sams2.conf | grep SAMSPATH | tr «SAMSPATH=» «\0″`

    А также включить его:
    SAMS_ENABLE=true

  17. Запускаем: sudo /etc/init.d/sams2daemon start
  18. Проверяем, что запустился:$ ps aux | grep sams
    root 5334 0.0 0.2 22908 2520 pts/0 S 14:27 0:00 sams2daemon

    Если такого процесса нет, значит что-то пошло не так. Ошибки ищите в syslog.

  19. Заходим в админку sams (http://localhost/), стандартные логин и пароль admin и qwerty. Там всё настраиваем по вкусу, настройки достаточно простые, описывать их здесь не буду.
  20. Теперь нужно подключить к сквиду ntlm и kerberos. Это можно сделать по инструкции с сайта сквида: http://wiki.squid-cache.org/ConfigExamples/Authenticate/WindowsActiveDirectory
    Единственное — пункт Kerberos лучше делать иначе, потому что с msktutil лично у меня ничего не получилось:
  21. Вместо того, чтобы мучиться с msktutil делаем всё то же самое из-под Windows на доменном контроллере.
    1. создаём учётную запись компьютера в AD (например proxyserver)
    2. запускаем терминал с правами администратора
    3. setspn -A HTTP/squidproxy.example.local EXAMPLE\proxyserver
    4. 1
      2
      3
      4
      5
      6
      7
      
      ktpass -out c:\PROXY.keytab
      -princ HTTP/squidproxy.example.local@EXAMPLE.LOCAL
      -mapUser EXAMPLE\proxyserver
      -mapOp set
      -pass was1edu
      -crypto RC4-HMAC-NT
      -pType KRB5_NT_PRINCIPAL
    5. Копируем PROXY.keytab на сервер прокси в директорию /etc/squid3/

Всё, squid и sams должны работать и прозрачно аутентифицировать пользователей через AD.

]]>
http://v-alexeev.ru/sams-squid-ubuntu-12-04/feed/ 338
Проксирование POP/IMAP через NGINX c помощью Django http://v-alexeev.ru/%d0%bf%d1%80%d0%be%d0%ba%d1%81%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-popimap-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-nginx-c-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-django/ http://v-alexeev.ru/%d0%bf%d1%80%d0%be%d0%ba%d1%81%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-popimap-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-nginx-c-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-django/#comments Sun, 25 Mar 2012 10:52:54 +0000 http://v-alexeev.ru/?p=38 Читать далее »

]]>
Одной из не так часто используемых возможностей nginx является возможность проксировать POP/IMAP. Когда это может быть полезно? Ну например для распределения нагрузки в высоконагруженной почтовой службе. Второй вариант — для прозрачной для пользователей переадресации на стороннюю почтовую службу.

Передо мной стояла следующая задача: в компании было принято решение использовать вместо своих серверов в качестве почтовой службы Яндекс.Почту для Домена. В основном решение было продиктовано огромным потоком спама, с которым не справлялся SpamAssassin, да и с самим объёмом почты сервер справлялся не без труда (на нём было множество других служб). При этом требовалось перенести почту без изменения паролей пользователей. Пароли, естественно, хранились в виде хэшей, поэтому автоматически установить пользователям на Яндексе такие же пароли было невозможно.

Поэтому я принял решение оставить авторизацию пользователей на своих серверах. Как раз с помощью nginx. А для упрощения администрирования этой системы, я написал два Django-приложения: одно для управления пользователями и авторизацией в nginx, а второе для синхронизации первого приложения с Яндекс.Почтой для домена.

Итак,

1. Настройка nginx как POP/IMAP прокси

Конфигурация достаточно простая:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
mail {
 auth_http 127.0.0.1:8080/auth/auth; # адрес авторизационного приложения (см. ниже)
 auth_http_header X-NGX-Auth-Key "SOME_SECRET_KEY"; # HTTP-заголовок, который nginx
                                                    # будет устанавливать, чтобы
                                             # показать авторизационному приложению,
                                             # что это действительно он
 proxy on; # включаем pop/imap прокси
 
 xclient off; # отключаем передачу в SMTP информации о пользователе (команду XCLIENT)
 
# дальше вроде всё понятно
 imap_capabilities "IMAP4rev1" "UIDPLUS";
 server {
 listen 143;
 protocol imap;
 starttls only;
 }
 
 server {
 listen 993;
 protocol imap;
 ssl on;
 }
 
 smtp_auth "plain";
 smtp_capabilities "8BITMIME" "SIZE 42991616" "ENHANCEDSTATUSCODES";
 
 server {
 listen 25;
 listen 587;
 protocol smtp;
 starttls only;
 }
 
 server {
 listen 465;
 protocol smtp;
 ssl on;
 }
 
 pop3_capabilities "TOP" "USER";
 server {
 listen 110;
 protocol pop3;
 starttls only;
 }
 
 server {
 listen 995;
 protocol pop3;
 ssl on;
 }
}

А что с SMTP?

Nginx почему-то не умеет передавать в SMTP авторизацию иначе как через команду XCLIENT (которую, например, яндексовский SMTP не поддерживает). Самый простой выход из такой ситуации — запустить свой SMTP на том же сервере, где nginx, и просто принимать от nginx с локалхоста любую почту без авторизации.

2. Авторизационное приложение

Nginx работает с авторизационным приложением по следующему протоколу:

Он отправляет HTTP-запрос со следующими заголовками:

Auth-Method: plain
Auth-User: user
Auth-Pass: password
Auth-Protocol: imap
Auth-Login-Attempt: 1
X-NGX-Auth-Key: SOME_SECRET_KEY
Client-IP: 192.168.1.1

И ждёт либо положительный ответ (вся информация — в HTTP-заголовках):

Auth-Status: OK
Auth-Server: 192.168.1.10 # адрес почтового сервера
Auth-Port: 110
Auth-User: newname # логин в почтовый сервер
Auth-Pass: password # пароль в почтовый сервер (plaintext)

Либо отрицательный:

Auth-Status: Invalid login or password
Auth-Wait: 3 # таймаут перед следующей попыткой входа

Методы аутентификации

Моё Django-приложение рассчитано на работу с простым методом PLAIN. Мне кажется при работе по SSL/STARTTLS это достаточно безопасно. Особенности работы с nginx остальных методов я сейчас, честно говоря, не вспомню, хотя в своё время это смотрел.

3. Django-приложение для аутентификации

1. Установка

Лежит на гитхабе и битбакете (там же по соседству можно найти и второе приложение, для Яндекс.Почты, но про него я подробнее напишу позже). Установка:

1
2
3
pip install git+https://V-Alexeev@github.com/V-Alexeev/nginxmailauth.git
или
pip install hg+https://bitbucket.org/v_alexeev/nginxmailauth

Дальше добавляем nginxmailauth в INSTALLED_APPS, urls.py, а также устанавливаем две собственных опции:

1
2
3
NGX_AUTH_KEY = "SOME_SECRET_KEY" # Тот ключ, который мы установили в конфиге nginx
ALLOWED_NGINX_IPS = ("127.0.0.1", "192.168.1.5") # Дополнительная проверка: только
                 # с этих IP-адресов будут разрешаться запросы

Запускаем сервер с нашим приложением и направляем на него nginx. Оно вполне может быть запущено на общедоступном адресе, поскольку в нём есть одна служба для пользователей — смена пароля (по адресу /change_password), а авторизационные запросы фильтруются по IP-адресу и X-NGX-Auth-Key.

2. Что включено

  1. Методы проверки пароля:
    1. Простым текстом
    2. Сравнение с md5-хэшем пароля
    3. Сравнение с md5-хэшем от строки «логин:сервер:пароль».
    4. Чтобы добавить свой метод проверки, достаточно отнаследоваться от класса BaseAuthenticationMethod и переопределить метод get_password (см. докстринги в methods.py).
    5. В планах — добавить проверку пароля через Kerberos.
  2. Управление пользователями через стандартную админку Django.
  3. Страница смены своего пароля самими пользователями (по адресу /change_password).

]]>
http://v-alexeev.ru/%d0%bf%d1%80%d0%be%d0%ba%d1%81%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-popimap-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-nginx-c-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-django/feed/ 2
(English) Using metaclasses in Python http://v-alexeev.ru/using-metaclasses-in-python/ http://v-alexeev.ru/using-metaclasses-in-python/#respond Thu, 29 Dec 2011 14:05:07 +0000 http://v-alexeev.ru/?p=21 Извините, эта запись доступна только на English

]]>
http://v-alexeev.ru/using-metaclasses-in-python/feed/
Яндекс.Почта для домена, API для Python http://v-alexeev.ru/ru%d1%8f%d0%bd%d0%b4%d0%b5%d0%ba%d1%81-%d0%bf%d0%be%d1%87%d1%82%d0%b0-%d0%b4%d0%bb%d1%8f-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%b0-api-%d0%b4%d0%bb%d1%8f-pythonusyandex-mail-for-domain-python-api/ http://v-alexeev.ru/ru%d1%8f%d0%bd%d0%b4%d0%b5%d0%ba%d1%81-%d0%bf%d0%be%d1%87%d1%82%d0%b0-%d0%b4%d0%bb%d1%8f-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%b0-api-%d0%b4%d0%bb%d1%8f-pythonusyandex-mail-for-domain-python-api/#comments Mon, 05 Dec 2011 11:58:22 +0000 http://v-alexeev.ru/?p=9 Читать далее »

]]>
Как известно, у Яндекс.Почты для домена есть официальное API для Питона (ссылка есть тут: https://pdd.yandex.ru/help/section72/). Но оно мне не нравится. Оно

  • Криво написано
  • Выдаёт не нормальные встроенные объекты Питона, а xml.etree.Element, с которым ещё дальше нужно работать самому
  • Как ни странно, реализует далеко не все функции

Так что я написал своё 🙂

Если кому нужно — можно забрать тут: https://github.com/V-Alexeev/yandexmailapi

В качестве тизера: скоро будет целое Django-приложение для работы с Яндекс.Почтой для домена (и, в принципе, не только с ней).

]]>
http://v-alexeev.ru/ru%d1%8f%d0%bd%d0%b4%d0%b5%d0%ba%d1%81-%d0%bf%d0%be%d1%87%d1%82%d0%b0-%d0%b4%d0%bb%d1%8f-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%b0-api-%d0%b4%d0%bb%d1%8f-pythonusyandex-mail-for-domain-python-api/feed/ 10
(English) Hello http://v-alexeev.ru/hello/ http://v-alexeev.ru/hello/#respond Tue, 29 Nov 2011 09:07:59 +0000 http://v-alexeev.ru/?p=6 Извините, эта запись доступна только на English

]]>
http://v-alexeev.ru/hello/feed/