Ivanovo Linux Users Group - Not logged in
Forum Help Search Login
Previous Next Up Topic Администрирование / Общее администрирование / SQUID to ip route2 (47812 hits)
- By PAHA Date 05.04.06 11:13
собственно проблема также как и вопрос

имеем много юзеров
тачку с Linux + ip route 2 + squid
4 канала в инет

хотим логировать похождения юзеров на сайты посредством прокси
хотим чтобы определёные групы пользователей ходили в нет через разных провайдеров

можно ли посредством сквида после авторизации юзеров чтобы запросы ходили по разным каналам в зависимости от того от какого юзера пришол запрос ?
Parent - By LOE (Site/forum admin) Date 05.04.06 12:45
Я бы начал с 2-х вариантов:

1. Запустить 4 разных сквида на разные IP, назначив нужные tcp_outgoing_address и разрулив по исходящему IP используемый внешний канал. Пользователям прописать нужный сквид и в каждом сквиде - своя политика ACL-ек

2. Более сложно и менее гибко - один сквид. Назначить tcp_outgoing_address=0.0.0.0 и заставить слушать все IP в системе.
Разрулить запросы от пользователей на разные IP сквида (чтоб запрос от _сквида_ пошел с нужного)
Но рулить можно уже только на основании сетевых реквизитов (IP и MAC пользователя), а не имя-пароль.

ИМХО первый вариант гораздо гибче. 4 сквида на 4 внешних канала, каждый со своей политикой авторизации и правил.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 06.04.06 04:21
второй вариант можно по подробней ?
Parent - By LOE (Site/forum admin) Date 06.04.06 08:40
Если вкратце:
На проксе 2 адреса: a.a.a.a и b.b.b.b

Входящие правила:
- если запрос на проксю на порт сквида от клиента A, направить его на a.a.a.a:порт
- если запрос на проксю на порт сквида от клиента B, направить его на b.b.b.b:порт

Исходящие правила:
- если запрос от прокси с адреса a.a.a.a то направить его в канал 1-ого провайдера
- если запрос от прокси с адреса b.b.b.b то направить его в канал 2-ого провайдера
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 10.04.06 07:45
а не будет ли прокся ходить с одного и тогоже адреса ?
Parent - By LOE (Site/forum admin) Date 10.04.06 16:26

> Назначить tcp_outgoing_address=0.0.0.0 и заставить слушать все IP в системе.


чтобы запрос уходил с того адреса, на который пришел пакет от клиента
Ну и конечно пробовать, пробовать и пробовать. 2-й вариант сложнее, о чем и написал.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 11.04.06 05:15
еслди я всё проавильно понял то поднимем eth0 ip 192.168.71.3 and eth0:1 192.168.71.4 итд итп
а на eth2 чего поднимать тогда ? (по умолчанию всё выходить в инет должно  с этого интерфейса)
Parent - By LOE (Site/forum admin) Date 11.04.06 05:25
А поднять взгляд выше?

> Исходящие правила:
> - если запрос от прокси с адреса a.a.a.a то направить его в канал 1-ого провайдера
> - если запрос от прокси с адреса b.b.b.b то направить его в канал 2-ого провайдера


То у тебя 4 канала в инет, то только eth2...
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 12.04.06 08:13
тоестькак я понимаю надо убедт на eth2 поднимать разные интерфесы типа eth2 80.***** eth2:1 81.*** eth2:2 82*** eth2.3 83.****
а в сквиде где эт овсё указывать ?
Parent - By LOE (Site/forum admin) Date 12.04.06 09:11
Паш, читай внимательно мои посты.
Поднимать разные интерфейсы - не обязательно.
Исходящий трафик зарулить можно на шлюзе (если сквид не на нем работает)
Разные ИПы сквида можно и локальные использовать (для каждой группы пользователей - свои)

Почему не хочешь 1-м способом сделать?
Проще и гибче можно будет несколько сквидов настроить (каждый четко на своем ИП или порту), чем один сквид и мучаться еще и с входящими правилами.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 12.04.06 11:23
нужен 1 сквид
Parent - By PAHA Date 12.04.06 11:52
значит кое чего сделали

squid.conf
#
тут ещё всякие там авторизации итд итп
#
acl group1 src 10.*.19.0/255.255.255.0
tcp_outgoing_address 10.*.*.4 group1
acl group2 src 10.*.71.0/255.255.255.0
tcp_outgoing_address 10.*.*.5 group2
acl group3 src 10.*.65.0/255.255.255.0
tcp_outgoing_address 10.*.*.6 group3
#
также надо поднять виртуальные интерфейсы

ifconfig eth0:1 10.*.*.4 netmask 255.255.255.0 up
ifconfig eth0:2 10.*.*.5 netmask 255.255.255.0 up
ifconfig eth0:3 10.*.*.6 netmask 255.255.255.0 up

без этого в логах сквида лезет вот такое

commBind: Cannot bind socket FD 19 to 10.*.*.5:0: (99) Cannot assign requested address

теперь мы имеем разные группы юзеров с разными ИП теперь осталось их только отправить в нужный канал и замаскарадить :-)

также можно разрулить юзеров по их логину авторизации

acl MYUSERS proxy_auth dima petya vasya (пример 3 имени пользователя) этот вариант ещё не опробован но в процессе
Parent - By G0thic Date 13.04.06 05:43
Молоток. Не знал, что tcp_outgoing_address можно акл использовать. Надо будет попробовать :-)
Как дальше будешь делать тоже напиши.
Когда кругозор человека сужается к минимуму, он называет это своей точкой зрения.
Parent - By Bercut Date 14.04.06 05:54
да красивое решение, былобы у меня стока кАНАЛОВ в тырнет, я бы тож ченить эдакое замутил тока ещо круче,
например десяток сквидов и одна базенка в которую логи класть кстати паш тебе тоже так мона было сделать
русский язык подобен искуству кун-фу, и великий мастер никогда не применит его без необходимости...
Parent - By PAHA Date 14.04.06 07:16
зачем мне куча сквидов и 1 база ?? у меня железки не резиновые :-) шо у каождог осквида кеш был по 2 гига :-)
мне нужен 1 сквид и 1 база для него :-)
Parent - By LOE (Site/forum admin) Date 14.04.06 10:07
А зачем у каждого по 2 гига кэша?
Связываешь их в цепочку и будет тебе взаимное использование кэшей.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent By Bercut Date 17.04.06 04:28
во во и я это хотел сказать
:-)
русский язык подобен искуству кун-фу, и великий мастер никогда не применит его без необходимости...
Parent - By PAHA Date 14.04.06 04:49
так едем дальше
Parent By PAHA Date 14.04.06 05:07
с разруливанем по каналам разобрались дальше будем делать авторизацию юзеров чтобы юзеры брались из базы Mysql

auth_param basic program /home/program/squid/bin/sqauth
#свой скриптик для авторизации (Авторизатор)
auth_param basic children 5
#количество запущеных процесов авторизации
auth_param basic realm access inet auth
#то что будет написано в таблике кторая будет запрашивать логин и пароль на авторизацию
auth_param basic credentialsttl 2 hours

ACL

acl password proxy_auth REQUIRED
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 10.16.0.0/16

http_access allow password
http_access allow localhost
http_access deny all
Parent - By PAHA Date 14.04.06 06:58
скрипт авторизатора

authsql

#!/bin/sh
mysqluser=юзер к базе
mysqlpass=парольк базе
mysqlprog=`which mysql`
if [ "$mysqlprog" = "" ]; then
    echo "MySQL not found!"
    exit 1
fi
while read username password; do
    status=`$mysqlprog -u $mysqluser -p$mysqlpass -D squidlog -e "SELECT username FROM auth WHERE username='$username' AND password=$password"`
    if [ "$status" = "" ]; then
        echo "ERR"
    else
        echo "OK"
   fi
done
Parent By LOE (Site/forum admin) Date 14.04.06 10:06
Крайне не эффективно тягать команду mysql каждый раз.
Единственное оправдание, что авторизатор вызывается сравнительно редко.

Ну и опять-же, совершенно четко можно сделать sql-инъекцию и грохнуть всю твою базу.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent - By PAHA Date 14.04.06 07:13
SQL

захдаём базу для сквида

потом подрубьаемся
mysql -u ЮЗЕР -pПАРОЛЬ -D БАЗА

скрипт для создания нужных баз (squid.sql)

CREATE TABLE auth (
  username char(12) default NULL,
  password char(30) default NULL,
  admin char(1) NOT NULL default 'N',
  maxdaily bigint(15) NOT NULL default '0',
  maxweekly bigint(15) NOT NULL default '0',
  maxmonthly bigint(15) NOT NULL default '0',
  UNIQUE KEY username (username)
) TYPE=MyISAM;

CREATE TABLE logger (
  date date default NULL,
  time time default NULL,
  elapsed decimal(10,0) default NULL,
  bill double default NULL,
  code tinyint(3) unsigned NOT NULL default '0',
  status decimal(3,0) default NULL,
  bytes double default NULL,
  url char(255) default NULL,
  userident char(15) default NULL,
  host char(15) default NULL
) TYPE=MyISAM;

CREATE TABLE rdnload (
  userident char(12) default NULL,
  date date default NULL,
  download bigint(15) NOT NULL default '0'
) TYPE=MyISAM;

CREATE TABLE usernames (
  username char(12) NOT NULL default '',
  realname char(30) default NULL,
  title char(30) NOT NULL default '',
  department char(30) NOT NULL default '',
  phone char(8) NOT NULL default '',
  email char(30) NOT NULL default '',
  datereg date NOT NULL default '2002-01-01'
) TYPE=MyISAM;

теперь застпавим сквид писать логи через pipe канал сразу в базу
Вместо текстового файла будет находится
   pipe-канал. Ничегонеподозревающий Squid будет писать логи о юзерах в
   один конец трубы, а perl-скрипт squidsql считывать из другого конца
   трубы, разбирать и заносить в базу данных MySQL. Если MySQL будет не
   доступен, то информация временно будет записана в файл
   /var/log/squid/backup.log

mkfifo /путь/к/логам сквида/access.log

сам скрипт который заносит всё в базу

#!/usr/bin/perl
$mysqluser="user";                 # MySQL user name
$mysqlpass="pass";                    # MySQL user password
$mysqlserv="localhost";                 # MySQL server
$mysqlport="3306";                      # MySQL server port
$mysqldbas="база";                  # MySQL database name
$mysqltabl="logger";                    # MySQL database table
$backuplog="/var/log/squid/backup.log"; # Backup log if couldnt connect to MySQL

# billing setup
$valuepermeg=4;                         # four roubles per meg
$valueperhour=0;                        # none per hour, leased line +2880p
# billing method
# 0 for user accounting, 1 for hosts accounting
$usehosts=0

use DBI;
use DBI::DBD;

$dbh=DBI->connect("DBI:mysql:database=$mysqldbas;host=$mysqlserv;port=$mysqlport",$mysqluser,$mysqlpass,{AutoCommit=>1,PrintError=>1})||&errorcon;
$sth=$dbh->prepare("INSERT INTO logger(date,time,elapsed,bill,code,\
status,bytes,url,userident,host)\
VALUES(?,?,?,?,?,?,?,?,?,?)");

open(FBLOGRET,$backuplog);

close(FBLOGRET);

while(<>) {
#
# 0 timestamp.millisec
# 1 duration
# 2 remotehost
# 3 code/status
# 4 bytes
# 5 method
# 6 URL
# 7 username
# 8 peerstatus/peerhost
# 9 type
#
#
    chop;                               # here we now get a string!
#                                       splitting string onto subdata
    @lines=split(' ');

#                                       timestamp
    $lines[0]=~tr/./ /;
    @_timestamp=split(' ',$lines[0]);
    $cts=$_timestamp[0];

#   date=

    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($cts);
    $year=$year+1900;
    $mon=$mon+1;
    $hour=$hour+7;
    if ($hour>24) {
        $hour=$hour-24;
        $mday=$mday+1;
    }
    $cdate="$year-$mon-$mday";

#   time=
    $ctime="$hour:$min:$sec";

#   elapsed=
    $duration=$lines[1];
#   host=
    $remotehost=$lines[2];

    @codestatus=split('/',$lines[3]);
    if ($codestatus[0] eq "TCP_HIT") { $_code=0; }
    if ($codestatus[0] eq "TCP_MISS") { $_code=1; }
    if ($codestatus[0] eq "TCP_REFRESH_HIT") { $_code=2; }
    if ($codestatus[0] eq "TCP_REF_FAIL_HIT") { $_code=3; }
    if ($codestatus[0] eq "TCP_REFRESH_MISS") { $_code=4; }
    if ($codestatus[0] eq "TCP_CLIENT_REFRESH_MISS") { $_code=5; }
    if ($codestatus[0] eq "TCP_IMS_HIT") { $_code=6; }
    if ($codestatus[0] eq "TCP_SWAPFILE_MISS") { $_code=7; }
    if ($codestatus[0] eq "TCP_NEGATIVE_HIT") { $_code=8; }
    if ($codestatus[0] eq "TCP_MEM_HIT") { $_code=9; }
    if ($codestatus[0] eq "TCP_DENIED") { $_code=10; }
    if ($codestatus[0] eq "TCP_OFFLINE_HIT") { $_code=11; }
    if ($codestatus[0] eq "UDP_HIT") { $_code=12; }
    if ($codestatus[0] eq "UDP_MISS") { $_code=13; }
    if ($codestatus[0] eq "UDP_DENIED") { $_code=14; }
    if ($codestatus[0] eq "UDP_INVALID") { $_code=15; }
    if ($codestatus[0] eq "UDP_MISS_NOFETCH") { $_code=16; }
    if ($codestatus[0] eq "NONE") { $_code=17; }
#   status=

    $_status=$codestatus[1];
#   bytes=
    $objectsize=$lines[4];
#   bill=
    $bill=(($duration/60000)*($valueperhour/60))+(($objectsize/1048576)*$valuepermeg);
#   method=
    $fetchmethod=$lines[5];
#
    $URLlink=$lines[6];
    $username=$lines[7];

    @peerstatus_host=split('/',$lines[8]);
    $peerstatus=$peerstatus_host[0];
    $peerhost=$peerstatus_host[1];

    $objecttype=$lines[9];

############################################################
##
##  transfer data to mysql table
##
############################################################

if (($_code ne "10")&&($username ne "-")&&($_status ne "404")&&($_status ne "400")) {

    $sth->execute($cdate,
    $ctime,
    $duration,
    $bill,
    $_code,
    $_status,
    $objectsize,
    $URLlink,
    $username,
    $remotehost) || die "cannot transfer data";

    $aff="SELECT * FROM rdnload WHERE userident='$username' AND date='$cdate'";
    $rows_affected=$dbh->do($aff);
    if ($rows_affected < 1) {
        $stn=$dbh->prepare("INSERT INTO rdnload(userident,date,download) VALUES (?,?,?)");
        $stn->execute($username,$cdate,$objectsize);
    }
    $aff="UPDATE rdnload SET download=download+$objectsize WHERE userident='$username' AND date='$cdate'";
    $rows_affected=$dbh->do($aff);
}

}

$dbh->disconnect;

exit 1;

sub errorconn {
    while(<>) {
        open(FBLOG,">>".$backuplog);
        print FBLOG $_;
        close(FBLOG);
    }
    die "cannot log to MySQL -- data buffered";
}

для запуска сквида рекомендую сделать скриптик /etc/rc.d/rc.squid

следующего соджержания

#!/bin/sh
case "$1" in 
start)
      /usr/local/squid/sbin/squid2mysql < /var/log/squid/access.log &
                # Читаем логи Squid через pipe-канал
      /usr/local/squid/sbin/squid                # запускаем Squid
      echo "Squid starting"                      # информируем
      ;;
stop)
      /usr/local/squid/sbin/squid -k shutdown    # останавливаем Squid
      echo "Squid stoping"                       # информируем
      ;;
*)
      /usr/local/squid/sbin/squid -k reconfigure # рестартуем Squid
      echo "Squid restarting"                    # информируем
      ;;
esac
exit 0
Parent By LOE (Site/forum admin) Date 14.04.06 10:04
Ты бы хоть лишние комментарии вычистил.
Не говоря о том, что скрипт не полный.
Если долгое время не будет обращений к MySQL, то сервер отключит тебя и скрипт навернется медным тазом.
Частично обработка предусмотрена, но совершенно не реализована.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent By LOE (Site/forum admin) Date 14.04.06 10:02
Прямо таки окровение! ;-)))

Паш, если ты выкладываеш скрипты/конфиги, оформляй хоть по-нормальному. Есть псевдотэг [ block ] ... [ /block ] (без пробелов), который отлично оформит скрипты и конфиги.
"No! Try not! Do. Or do not. There is no try." -- Yoda
Previous Next Up Topic Администрирование / Общее администрирование / SQUID to ip route2 (47812 hits)

Powered by mwForum 2.12.0 © 1999-2007 Markus Wichitill

Page created in 0.079s with 10 database queries.