Привязка номера ppp интерфейса к UID клиента
Добавлено: Вс ноя 02, 2008 2:28 pm
Наваял тут на досуге сабж... Мож кому тоже пригодится 
Что делает
Да собсно сабж и делает... То есть усер всегда цепляется на ифейс ppp<unit>, где unit = $conf{PPPD_UNIT_START} + UID
По дефолту $conf{PPPD_UNIT_START} = 1000. Соответственно усер с UID = 123 всегда будет цепляться на ифейс ppp1123 а усер с UID = 321 - на ифейс ppp1321
А нафига оно?
Если такой вопрос возникает, дальше можно не читать - вам оно точно ненада
Что нужно сделать
1. Организовать передачу номера ppp интерфейса через радиус атрибут
Для этого добавляем новый атрибут в словари радиуса (сервера и клиента)и перезапускаем радиуссервер
2. Сформировать атрибут для радиуссервера
Не придумал пока ничего лучше, как пропатчить Abills/mysql/Auth.pm. Пишем патчсохраняем его в /usr/abills/auth.patch и патчимПроверяем. Теперь /var/run/radattr.ppp* должны выглядеть где-то так:
Радиусклиент у нас кто? Правильно - pppd... его и будем патчить (оставим любознательным возможность самим догадаться, почему не стОит переименовывать пппдшый ифейс из скриптов типа /etc/ppp/ip-pre-up
). Поэтому пишем патч к pppd (я юзаю ppp-2.4.4, мож и на другие версии прокатит)сохраняем его в каталог с сырцами pppd с именем pppdunit.patch, переходим в этот каталог и патчим
4. Собираем пропатченный pppd
Желающим лентяям могу намылить готовый rpm/src.rpm для оупенсюзи 10.3
Собсно всё... Останавливаем туннельный сервер (с прибитием всех pppd процессов разумеется), инсталлим собранный pppd (для счастливых обладателей rpm: rpm -Uvh --force ppp-2.4.4-70.i586.rpm
), запускаем туннельный сервер. При подключении усеров наблюдаем в логах где-то отаке:

Что делает
Да собсно сабж и делает... То есть усер всегда цепляется на ифейс ppp<unit>, где unit = $conf{PPPD_UNIT_START} + UID
По дефолту $conf{PPPD_UNIT_START} = 1000. Соответственно усер с UID = 123 всегда будет цепляться на ифейс ppp1123 а усер с UID = 321 - на ифейс ppp1321
А нафига оно?
Если такой вопрос возникает, дальше можно не читать - вам оно точно ненада

Что нужно сделать
1. Организовать передачу номера ppp интерфейса через радиус атрибут
Для этого добавляем новый атрибут в словари радиуса (сервера и клиента)
Код: Выделить всё
# PPPD Unit
ATTRIBUTE PPPD-Unit 238 integer
2. Сформировать атрибут для радиуссервера
Не придумал пока ничего лучше, как пропатчить Abills/mysql/Auth.pm. Пишем патч
Код: Выделить всё
--- Abills/mysql/Auth.pm 2008-10-25 12:53:29.000000000 +0300
+++ Abills/mysql/Auth.pm 2008-10-31 16:29:43.000000000 +0200
@@ -628,6 +628,13 @@
$RAD_PAIRS->{'PPPD-Downstream-Speed-Limit'} = int($EX_PARAMS->{speed}->{0}->{OUT});
$RAD_PAIRS->{'PPPD-Upstream-Speed-Limit'} = int($EX_PARAMS->{speed}->{0}->{IN});
}
+ #PPPD-Unit = UID
+ if ($NAS->{NAS_TYPE} eq 'pppd') {
+ if (! defined($CONF->{PPPD_UNIT_START})) {
+ $CONF->{PPPD_UNIT_START}=1000;
+ }
+ $RAD_PAIRS->{'PPPD-Unit'} = int($self->{UID}) + $CONF->{PPPD_UNIT_START};
+ }
}
#Chillispot www.chillispot.org
elsif ($NAS->{NAS_TYPE} eq 'chillispot') {
Код: Выделить всё
cd /usr/abills
patch -p0 < auth.patch
3. Обрабатывать атрибут радиусклиентомMS-CHAP2-Success \201S=8056C8D7E1676B8E80EB6CA47593422FDAC1D607
MS-MPPE-Recv-Key \206%\224\364\231\006yc\300\2609\010\256\303U\267a\235\362\235\020\013\260\234\227\247\272\333\366\012\266\345&c
MS-MPPE-Send-Key \2132\362\023\246\244\2437\211\277\216,\333\250\317\251\334\020\332\030\004j6\220\264\036\310\340\235\017>\235B\
MS-MPPE-Encryption-Policy
MS-MPPE-Encryption-Types
Session-Timeout 0
Session-Octets-Limit 0
PPPD-Downstream-Speed-Limit 32
Acct-Interim-Interval 60
PPPD-Upstream-Speed-Limit 256
Octets-Direction Sum
Framed-IP-Address 10.16.1.179
Framed-IP-Netmask 255.255.255.255
PPPD-Unit 1007
Радиусклиент у нас кто? Правильно - pppd... его и будем патчить (оставим любознательным возможность самим догадаться, почему не стОит переименовывать пппдшый ифейс из скриптов типа /etc/ppp/ip-pre-up

Код: Выделить всё
--- pppd/pppd.h 2005-08-26 02:59:34.000000000 +0300
+++ pppd/pppd.h 2008-10-29 15:17:20.000000000 +0200
@@ -668,6 +684,7 @@
#endif
int get_if_hwaddr __P((u_char *addr, char *name));
char *get_first_ethernet __P((void));
+int ren_ifunit __P((int iUnit)); // Rename interface with new unit number
/* Procedures exported from options.c */
int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */
--- pppd/sys-linux.c 2005-08-27 01:44:35.000000000 +0300
+++ pppd/sys-linux.c 2008-10-29 15:17:20.000000000 +0200
@@ -2872,3 +2880,32 @@
return 1;
}
#endif
+
+// Rename interface with new unit number
+
+int ren_ifunit(int iUnit)
+{
+ if(ifunit == iUnit)
+ {
+ return 0;
+ }
+ struct ifreq ifr;
+ char t[MAXIFNAMELEN];
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, ifname, IF_NAMESIZE);
+ slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, iUnit);
+ strncpy(ifr.ifr_newname, t, IF_NAMESIZE);
+ int i = ioctl(sock_fd, SIOCSIFNAME, &ifr);
+ if(i < 0)
+ {
+ error("Couldn't rename interface %s to %s: %m", ifname, t);
+ }
+ else
+ {
+ info("Renamed interface %s to %s", ifname, t);
+ remove_pidfiles();
+ ifunit = iUnit;
+ set_ifunit(1);
+ }
+ return i;
+}
--- pppd/plugins/radius/radattr.c 2004-10-28 03:24:40.000000000 +0300
+++ pppd/plugins/radius/radattr.c 2008-10-29 17:20:22.000000000 +0200
@@ -71,6 +71,29 @@
char name[2048];
char value[2048];
int cnt = 0;
+
+ if ((req_ifname[0] == '\0') && (req_unit < 0))
+ {
+ VALUE_PAIR* pvp;
+ for(pvp = vp; pvp; pvp = pvp->next)
+ {
+ if(!rc_avpair_tostr(pvp, name, sizeof(name), value, sizeof(value)))
+ {
+ if(!strcmp(name, "PPPD-Unit"))
+ {
+ int iUnit;
+ if(sscanf(value, "%d", &iUnit) == 1)
+ {
+ if(ren_ifunit(iUnit) >= 0)
+ {
+ rstate.client_port = ifunit;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ifname);
fp = fopen(fname, "w");
--- pppd/plugins/radius/radius.c 2006-05-22 03:01:40.000000000 +0300
+++ pppd/plugins/radius/radius.c 2008-10-29 17:22:34.000000000 +0200
@@ -104,26 +104,6 @@
#define MAXCLASSLEN 500
#endif
-struct radius_state {
- int accounting_started;
- int initialized;
- int client_port;
- int choose_ip;
- int any_ip_addr_ok;
- int done_chap_once;
- u_int32_t ip_addr;
- char user[MAXNAMELEN];
- char config_file[MAXPATHLEN];
- char session_id[MAXSESSIONID + 1];
- time_t start_time;
- int acct_interim_interval;
- SERVER *authserver; /* Authentication server to use */
- SERVER *acctserver; /* Accounting server to use */
- int class_len;
- char class[MAXCLASSLEN];
- VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */
-};
-
void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
/* The pre_auth_hook MAY set authserver and acctserver if it wants.
@@ -132,7 +112,7 @@
SERVER **authserver,
SERVER **acctserver) = NULL;
-static struct radius_state rstate;
+struct radius_state rstate;
char pppd_version[] = VERSION;
--- pppd/plugins/radius/radiusclient.h 2004-11-14 09:26:26.000000000 +0200
+++ pppd/plugins/radius/radiusclient.h 2008-10-29 17:19:45.000000000 +0200
@@ -378,6 +378,36 @@
#define ENV_SIZE 128
+#ifndef MAXSESSIONID
+#define MAXSESSIONID 32
+#endif
+
+#ifndef MAXCLASSLEN
+#define MAXCLASSLEN 500
+#endif
+
+struct radius_state {
+ int accounting_started;
+ int initialized;
+ int client_port;
+ int choose_ip;
+ int any_ip_addr_ok;
+ int done_chap_once;
+ u_int32_t ip_addr;
+ char user[MAXNAMELEN];
+ char config_file[MAXPATHLEN];
+ char session_id[MAXSESSIONID + 1];
+ time_t start_time;
+ int acct_interim_interval;
+ SERVER *authserver; /* Authentication server to use */
+ SERVER *acctserver; /* Accounting server to use */
+ int class_len;
+ char class[MAXCLASSLEN];
+ VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */
+};
+
+extern struct radius_state rstate;
+
/* Function prototypes */
/* avpair.c */
Код: Выделить всё
patch -p0 < pppdunit.patch
Желающим лентяям могу намылить готовый rpm/src.rpm для оупенсюзи 10.3

Собсно всё... Останавливаем туннельный сервер (с прибитием всех pppd процессов разумеется), инсталлим собранный pppd (для счастливых обладателей rpm: rpm -Uvh --force ppp-2.4.4-70.i586.rpm

Nov 2 16:08:03 abills pppoe-server[10647]: Session 224 created for client 00:13:77:5a:5e:b0 (0.0.0.223) on eth2 using Service-Name ''
Nov 2 16:08:03 abills pppd[10647]: Plugin /etc/ppp/plugins/rp-pppoe.so loaded.
Nov 2 16:08:03 abills pppd[10647]: RP-PPPoE plugin version 3.3 compiled against pppd 2.4.4
Nov 2 16:08:03 abills pppd[10647]: Plugin radius.so loaded.
Nov 2 16:08:03 abills pppd[10647]: RADIUS plugin initialized.
Nov 2 16:08:03 abills pppd[10647]: Plugin radattr.so loaded.
Nov 2 16:08:03 abills pppd[10647]: RADATTR plugin initialized.
Nov 2 16:08:03 abills pppd[10647]: pppd 2.4.4 started by root, uid 0
Nov 2 16:08:03 abills pppd[10647]: using channel 225
Nov 2 16:08:03 abills pppd[10647]: Using interface ppp29
Nov 2 16:08:03 abills pppd[10647]: Connect: ppp29 <--> eth2
Nov 2 16:08:03 abills pppd[10647]: sent [LCP ConfReq id=0x1 <mru 1452> <auth chap MS-v2> <magic 0x30911773>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP ConfReq id=0x0 <mru 1480> <magic 0x9924a92> <callback CBCP>]
Nov 2 16:08:03 abills pppd[10647]: sent [LCP ConfRej id=0x0 <callback CBCP>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP ConfAck id=0x1 <mru 1452> <auth chap MS-v2> <magic 0x30911773>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP ConfReq id=0x1 <mru 1480> <magic 0x9924a92>]
Nov 2 16:08:03 abills pppd[10647]: sent [LCP ConfAck id=0x1 <mru 1480> <magic 0x9924a92>]
Nov 2 16:08:03 abills pppd[10647]: sent [LCP EchoReq id=0x0 magic=0x30911773]
Nov 2 16:08:03 abills pppd[10647]: sent [CHAP Challenge id=0xa9 <9a01a8b65656bd7a8881b73b6a3fe22a>, name = "abills"]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP Ident id=0x2 magic=0x9924a92 "MSRASV5.10"]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP Ident id=0x3 magic=0x9924a92 "MSRAS-0-PETRENKO-I"]
Nov 2 16:08:03 abills pppd[10647]: rcvd [LCP EchoRep id=0x0 magic=0x9924a92]
Nov 2 16:08:03 abills pppd[10647]: rcvd [CHAP Response id=0xa9 <bfc777367c7f6903e6e9bfba24c37d5900000000000000009cd137e3b5fb517670f2d5d01468814da89795134bde258200>, name = "pin"]
Nov 2 16:08:03 abills kernel: [ 7717.550328] ppp29 renamed to ppp1284
Nov 2 16:08:03 abills pppd[10647]: Renamed interface ppp29 to ppp1284
Nov 2 16:08:03 abills pppd[10647]: Using interface ppp1284
Nov 2 16:08:03 abills pppd[10647]: RADATTR plugin wrote 14 line(s) to file /var/run/radattr.ppp1284.
Nov 2 16:08:03 abills pppd[10647]: sent [CHAP Success id=0xa9 "S=3FDE3ACDD562188F22EAEC7611DDFE9375998D90"]
Nov 2 16:08:03 abills pppd[10647]: peer from calling number 00:13:77:5A:5E:B0 authorized
Nov 2 16:08:03 abills pppd[10647]: sent [IPCP ConfReq id=0x1 <addr 192.168.1.1>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [CCP ConfReq id=0x4 <mppe -H -M -S -L -D +C>]
Nov 2 16:08:03 abills pppd[10647]: Unsupported protocol 'Compression Control Protocol' (0x80fd) received
Nov 2 16:08:03 abills pppd[10647]: sent [LCP ProtRej id=0x2 80 fd 01 04 00 0a 12 06 00 00 00 01]
Nov 2 16:08:03 abills pppd[10647]: rcvd [IPCP ConfReq id=0x5 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-wins 0.0.0.0> <ms-dns3 0.0.0.0> <ms-wins 0.0.0.0>]
Nov 2 16:08:03 abills pppd[10647]: sent [IPCP ConfRej id=0x5 <ms-wins 0.0.0.0> <ms-wins 0.0.0.0>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [IPCP ConfAck id=0x1 <addr 192.168.1.1>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [IPCP ConfReq id=0x6 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns3 0.0.0.0>]
Nov 2 16:08:03 abills pppd[10647]: sent [IPCP ConfNak id=0x6 <addr 10.17.0.19> <ms-dns1 192.168.1.1> <ms-dns3 192.168.1.4>]
Nov 2 16:08:03 abills pppd[10647]: rcvd [IPCP ConfReq id=0x7 <addr 10.17.0.19> <ms-dns1 192.168.1.1> <ms-dns3 192.168.1.4>]
Nov 2 16:08:03 abills pppd[10647]: sent [IPCP ConfAck id=0x7 <addr 10.17.0.19> <ms-dns1 192.168.1.1> <ms-dns3 192.168.1.4>]
Nov 2 16:08:03 abills pppd[10647]: Script /etc/ppp/ip-pre-up started (pid 10658)
Nov 2 16:08:03 abills pppd[10647]: Script /etc/ppp/ip-pre-up finished (pid 10658), status = 0x0
Nov 2 16:08:03 abills pppd[10647]: local IP address 192.168.1.1
Nov 2 16:08:03 abills pppd[10647]: remote IP address 10.17.0.19
Nov 2 16:08:03 abills pppd[10647]: Script /etc/ppp/ip-up started (pid 10666)
Nov 2 16:08:03 abills /etc/ppp/ip-up.d/freeswan: this script needs to be run from ip-up or ip-down
Nov 2 16:08:03 abills pppd[10647]: Script /etc/ppp/ip-up finished (pid 10666), status = 0x0