Linuxでトラフィックを促進します。 パート2

ここで最初の部分を読んでください



この記事では、次のことを検討します。

-MySQLデータベースからのユーザーの承認。

-方向のトラフィックの詳細。





MySQLからの承認。 フリー半径



前の記事では、承認の設定に焦点を当てず、そのままにしておきました。 ユーザーアカウントはテキストファイルに保存されていました。 これは、5〜10人のユーザーがいて、パスワードをめったに変更しない場合に便利ですが、それ以上のユーザーがいると問題が発生します。 pptpdがユーザーテーブルからユーザーアカウントを取得すると、ユーザーログイン/パスワードとそのIPアドレスが既に存在するので、はるかに便利です。



PPTPDは、Radius認証サーバーを使用してデータベースと通信します(実際、テキストファイル以外の認証方法の場合)。



インストール:

root@srv:~# apt-get install freeradius freeradius-mysql radiusclient1





PPTPDがradius経由でログインするとします。このために、 / etc / ppp / pptpd-optionsファイルに次の行を追加します。

plugin radius.so







freeradiusを構成します。



すべての主要な構成は/ etc / freeradiusディレクトリに保存されます。 radiusd.conf config 、セクションを見つけます:

authorize {

#

# The preprocess module takes care of sanitizing some bizarre

# attributes in the request, and turning them into attributes

# which are more standard.

...






パラメータのコメントを外します

# See "Authorization Queries" in sql.conf

sql

...






sql.conf構成を次のようにします。

sql {

driver = "rlm_sql_mysql"

server = "localhost"



login = "ulog"

password = "1234"

radius_db = "ulogdb"



deletestalesessions = yes



sqltrace = no

sqltracefile = ${logdir}/sqltrace.sql



num_sql_socks = 5

connect_failure_retry_delay = 60



sql_user_name = "%{User-Name}"



authorize_check_query = "SELECT id, login, 'User-Password' AS \"Attribute\", `password` AS \"Value\", '==' AS \"op\" FROM users WHERE login = '%{SQL-User-Name}'"

authorize_reply_query = "SELECT id, login, 'Framed-IP-Address' as \"Attribute\", ip as \"Value\", ':=' as \"op\" FROM users WHERE login = '%{SQL-User-Name}'"

authorize_group_check_query = "SELECT '1' as \"id\",'default' AS \"GroupName\", 'Auth-Type' as \"Attribute\", CASE WHEN status='1' THEN 'MS-CHAP' ELSE 'REJECT' END as \"Value\", ':=' as \"op\" FROM users WHERE login='%{SQL-User-Name}'"

}






loginpasswordradius_dbパラメーターに注意し、データベースにアクセスするためのユーザー名とパスワード、およびデータベース自体の名前を指定します。



PPTPDはradiusclientを使用して半径を参照するため、 radiusサーバー自体をネットワーク上の別のマシンにすることができます。相互作用のために、「クライアント」freeradiusと「サーバー」radiusclientを指定する必要があります。



clients.confファイルを開き、セクションを見つけます。

client 127.0.0.1







secretパラメーターの値を単語に変更すると、radiusclient'aの一種の「パスワード」になります。

secret = habrahabra





radiusサーバーに関するエントリを/ etc / radiusclient / serversファイルに追加します。

localhost habrahabra





既にお気づきのように、2番目の単語は「パスワード」です。これは、 clients.confで指定しました。



デフォルトでは、radiusclientはms-chapを実行できません。これには、属性の追加辞書が必要です。 コピー:

root@srv:~# cp /usr/share/freeradius/dictionary.microsoft /etc/radiusclient/





他の辞書に接続し、 / etc / radiusclient /辞書ファイルの最後に次の行を追加します。

INCLUDE /etc/radiusclient/dictionary.microsoft





pptpdとfreeradiusを再起動します。

root@srv:# /etc/init.d/freeradius restart && /etc/init.d/pptpd restart





これでpptpdとfreeradiusの設定が完了しました。これで、データベースから認証が行われます。 サーバーに接続してみてください。すべてが機能する場合は先に進みます。



方向別の詳細



ほとんどすべてのプロバイダーには特定の「タリフゾーン」があり、これらはサブネット全体またはIPアドレスの範囲であり、トラフィックのMbの価格は外部トラフィックのMbの価格とは大きく異なります。 たとえば、内部メディアまたはゲームサーバー、Yandexサービス。 そして、どのタリフィケーションゾーンのトラフィックが来たのかを見るといいでしょう。 始めましょう:)



これを行うには、ベースを近代化し、別のテーブルを追加します。

CREATE TABLE `zones` (

`id` int(11) NOT NULL auto_increment,

`name` varchar(64) NOT NULL,

`firstip` bigint(20) NOT NULL,

`lastip` bigint(20) NOT NULL,

`prio` int(11) NOT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY (`prio`)

) ENGINE=MyISAM DEFAULT CHARSET utf8;






既存のデータテーブルを変更します。

ALTER TABLE `data` ADD COLUMN `id_zone` int(11) NOT NULL;

ALTER TABLE `data` ADD UNIQUE (`id_user`,`id_zone`,` ts`);






3つの関税ゾーンを追加します。

#

insert into zones (name,firstip,lastip,prio) values('local',inet_aton('10.1.0.1'),inet_aton('10.1.0.254'),0);

#

insert into zones (name,firstip,lastip,prio) values('habrahabr',inet_aton('62.213.122.2'),inet_aton('62.213.122.2'),1);

#

insert into zones (name,firstip,lastip,prio) values('inet',inet_aton('0.0.0.1'),inet_aton('254.254.254.254'),2);






prioフィールドの値に注意してください。関税ゾーンを追加するときは、ルールから先に進む必要があります。トラフィックが安いほど、優先順位が高くなります(0-最高)。



パーサースクリプト:

#!/usr/bin/perl



use DBI;



# ...

sub inet_aton {

my @addr = split(/\./,$_[0]);

my $dec = 0;

for($n = 3; $n >= 0; $n--) {

$dec += ($addr[-$n-1] << 8 * $n);

}

return $dec;

}



# ,

my $db_name = "ulogdb";

my $db_user = "ulog";

my $db_pass = "1234";



# -

$account_log = "/var/log/ulog-acctd/account.log";



#

my $DBH = DBI->connect("DBI:mysql:$db_name:localhost",$db_user,$db_pass) or die "Error connecting to database";



# ip+id_user

my $STH = $DBH->prepare("select ip,id from users");

$STH->execute;

while (@tmp = $STH->fetchrow_array()) {

$users{$tmp[0]} = $tmp[1];

}

$STH->finish;



#

my $STH = $DBH->prepare("select prio,firstip,lastip,id from zones order by prio");

$STH->execute;

while (@tmp = $STH->fetchrow_array()) {

$zones[$tmp[0]] = [$tmp[1], $tmp[2], $tmp[3]];

}

$STH->finish;



#

system "cp $account_log /tmp/ulog-parser.tmp && cat /dev/null > $account_log";

open LOGFILE,"< /tmp/ulog-parser.tmp";

while (<LOGFILE>) {

chomp;

($ts,$saddr,$daddr,$bytes) = split /\t/;



# ,

#

# . 1



$ts = $ts - $ts % 60;



#

# -

# :

# -> id ->



if (exists($users{$daddr})) {

#

$zone_id = 0;

for($i=0;$i>=$zones;$i++) {

$nip = inet_aton($saddr);

if ($zones[$i][0] <= $nip and $zones[$i][1] >= $nip) {

$zone_id = $zones[$i][2];

last;

}

}

$data{$ts}{$users{$daddr}}{$zone_id} += $bytes;

}

}

close LOGFILE;

unlink("/tmp/ulog-parser.tmp");



# , mgyk :)

my $STH = $DBH->prepare("insert into data (id_user,id_zone,ts,bytes) values(?,?,?,?) on duplicate key update bytes=bytes+?");



#

#

for $ts (keys %data) {

for $id_user (keys %{$data{$ts}}) {

for $id_zone(keys %{$data{$ts}{$id_user}}) {

$STH->execute($id_user,$id_zone,$ts,$data{$ts}{$id_user}{$id_zone},$data{$ts}{$id_user}{$id_zone});

$STH->finish;

}

}

}

#

$DBH->disconnect;







これですべてです。次のパートでは、トラフィック制限と速度制限について説明します。



UPD:おっと、スクリプトのコードにエラーがあり、修正されました(:



All Articles