Привязка номера ppp интерфейса к UID клиента

Установка, настройка, поддержка
Ответить
ran
Сообщения: 2298
Зарегистрирован: Вс окт 21, 2007 2:29 pm

Привязка номера ppp интерфейса к UID клиента

Сообщение ran »

Наваял тут на досуге сабж... Мож кому тоже пригодится ;)

Что делает

Да собсно сабж и делает... То есть усер всегда цепляется на ифейс 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') {
сохраняем его в /usr/abills/auth.patch и патчим

Код: Выделить всё

cd /usr/abills
patch -p0 < auth.patch
Проверяем. Теперь /var/run/radattr.ppp* должны выглядеть где-то так:
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
3. Обрабатывать атрибут радиусклиентом

Радиусклиент у нас кто? Правильно - pppd... его и будем патчить (оставим любознательным возможность самим догадаться, почему не стОит переименовывать пппдшый ифейс из скриптов типа /etc/ppp/ip-pre-up :P ). Поэтому пишем патч к pppd (я юзаю ppp-2.4.4, мож и на другие версии прокатит)

Код: Выделить всё

--- 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		*/
сохраняем его в каталог с сырцами pppd с именем pppdunit.patch, переходим в этот каталог и патчим

Код: Выделить всё

patch -p0 < pppdunit.patch
4. Собираем пропатченный pppd

Желающим лентяям могу намылить готовый 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

Tiger
Сообщения: 45
Зарегистрирован: Пт фев 08, 2008 7:01 pm

Re: Привязка номера ppp интерфейса к UID клиента

Сообщение Tiger »

Только мне пришлось перед ним наложить патч ppp-2.4.2-ifname. Все заработало. Спасибо run. + Собрал деб пакет для убунту 8.10, может и на других дебианоподобных покатит. Если надо, в ЛС.
Вложения
ppp-2.4.2-ifname.zip
(2.03 КБ) 499 скачиваний

ran
Сообщения: 2298
Зарегистрирован: Вс окт 21, 2007 2:29 pm

Re: Привязка номера ppp интерфейса к UID клиента

Сообщение ran »

Только мне пришлось перед ним наложить патч ppp-2.4.2-ifname
ну поскольку это патч от сюзи то ессно в пакете ппп от сюзи он накладывается автоматом поэтому я и не обратил внимания ;)
Любой тупик - это тщательно замаскированный выход.

Ответить