It is currently Fri May 26, 2017 11:30 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: multi-pool radius selection
PostPosted: Sun May 06, 2012 8:49 pm 

Joined: Sat Jun 04, 2011 9:18 am
Posts: 15
Hi All,

I've got a remote radius server that can inform the various LNS setups that's running from which ippool to select IP addresses, but doesn't know which exact IPs are available on which LNSs. So basically the idea would be to set it up such that each LNS has a set of pools, with the same names on each server, so for example:

server one:

Code:
pool create pool_name=pool1
pool address add pool_name=pool1 first_addr=192.168.0.0 num_addrs=128 netmask=255.255.255.0

pool create pool_name=pool2
pool address add pool_name=pool2 first_addr=192.168.1.0 num_addrs=128 netmask=255.255.255.0


server two:

Code:
pool create pool_name=pool1
pool address add pool_name=pool1 first_addr=192.168.0.128 num_addrs=128 netmask=255.255.255.0

pool create pool_name=pool2
pool address add pool_name=pool2 first_addr=192.168.1.128 num_addrs=128 netmask=255.255.255.0


Now, from radius I'd like to be able to inform the pppd process which ip pool to use, ie, something like:

Code:
Framed-Pool: pool1


For example. Is this possible with the existing ippool.c plugin, or would it perhaps be possible to do this relatively trivially?

I've got another requirement for this too, normal VPN users that VPNs in, some users needs to attach to one LAN segment, and others to another, this would make it trivial to achieve this as well, but not my current requirement.


Top
 Profile  
 
 Post subject: Re: multi-pool radius selection
PostPosted: Sun May 06, 2012 10:19 pm 

Joined: Sat Jun 04, 2011 9:18 am
Posts: 15
Short answer, no.

Long answer, it's possible, patch below:

Code:
--- ippool-1.3.o/pppd/ippool.c   2004-09-12 23:04:50.000000000 +0200
+++ ippool-1.3/pppd/ippool.c   2012-05-06 22:30:42.000000000 +0200
@@ -1,6 +1,7 @@
/* ippool.c - pppd plugin to access IP address pool maintained externally.
  */

+#define _GNU_SOURCE
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
@@ -15,14 +16,40 @@
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <signal.h>

+#include <dlfcn.h>
+
#include <linux/types.h>

#include "ippool_rpc.h"

+/* I'd prefer to #include this from pppd install ... but alas, radiusclient.h isn't available */
+#ifndef _UINT4_T
+/* This works for all machines that Linux runs on... */
+typedef unsigned int UINT4;
+typedef int          INT4;
+#endif
+
+#define VENDOR_NONE         (-1)
+#define PW_FRAMED_POOL      88 /* string */
+#define NAME_LENGTH         32
+#define AUTH_STRING_LEN      128
+
+typedef struct value_pair
+{
+   char               name[NAME_LENGTH + 1];
+   int                attribute;
+   int                vendorcode;
+   int                type;
+   UINT4              lvalue;
+   u_char             strvalue[AUTH_STRING_LEN + 1];
+   struct value_pair *next;
+} VALUE_PAIR;
+
+
const char pppd_version[] = VERSION;

static int ippool_fd = -1;
@@ -30,7 +59,8 @@
static char *ippool_server = "localhost";
static int ippool_debug = 0;
static struct in_addr ippool_addr[2];
-
+static char *ippool_radius_name = NULL;
+static void (*old_rad_attr_hook)(VALUE_PAIR *) = NULL;

static option_t ippool_options[] = {
   { "ippool_name", o_string, &ippool_pool_name,
@@ -45,11 +75,33 @@
   { NULL }
};

+static void ippool_radius_attr_hook(VALUE_PAIR *vp)
+{
+   if (old_rad_attr_hook)
+      old_rad_attr_hook(vp);
+
+   for (; vp; vp = vp->next) {
+      if (vp->vendorcode == VENDOR_NONE && vp->attribute == PW_FRAMED_POOL) {
+         ippool_radius_name = strdup(vp->strvalue);
+         warn("Using '%s' for @radius ippool_name.", ippool_radius_name);
+         return;
+      }
+   }
+}
+
static int ippool_addr_alloc(CLIENT *cl, char *pool_name, u_int32_t *addr)
{
-   int result;
+   int result = -1;
   struct ippool_api_addr_alloc_msg_data clnt_res;

+   if (strcmp(pool_name, "@radius") == 0) {
+      pool_name = ippool_radius_name;
+      if (!pool_name) {
+         warn("IP address allocation from Radius failed (no Framed-Pool or radius not in use).");
+         goto out;
+      }
+   }
+
   result = ippool_addr_alloc_1(pool_name, &clnt_res, cl);
   if (result != RPC_SUCCESS) {
      fatal("ippool: %s", clnt_sperror(cl, ippool_server));
@@ -220,5 +269,13 @@

   /* brute force, just in case ip_down_hook doesn't get called */
   add_notifier(&exitnotify, ippool_cleanup, 0);
+
+   // If radius.so is loaded, attempt to hook it.
+   void (**rad_attr_hook)(VALUE_PAIR *) = dlsym(RTLD_DEFAULT, "radius_attributes_hook");
+   if (rad_attr_hook) {
+      warn("Hooking radius_attributes_hook");
+      old_rad_attr_hook = *rad_attr_hook;
+      *rad_attr_hook = ippool_radius_attr_hook;
+   }
}



There are a few points to note:

1. You need to add ATTRIBUTE Framed-Pool 88 string to /etc/pppd/radius/dictionary or radius.so will kick out something like: rc_avpair_gen: received unknown attribute 88 of length 4: 0xXXxxXXxx

2. The above relies on dlsym, for which you need -ldl linked, which on my installation is already linked into /usr/sbin/pppd so no need for explicit linking.

3. This must load after radius.so

4. If you also need radattr.so, ippool.so must load after that also, so do NOT set ippool_name in openl2tpd.conf, set it from your pppd options file, eg:

Code:
plugin radius.so
plugin radattr.so
plugin ippool.so

ippool_name @radius


5. The struct is copied/pasted from the pppd codebase since on my system at least the pppd radiusclient.h file is NOT included into the installation. If these structs goes out of sync bad things will happen.


Top
 Profile  
 
 Post subject: Re: multi-pool radius selection
PostPosted: Tue Nov 29, 2016 6:29 pm 

Joined: Mon Nov 28, 2016 1:46 pm
Posts: 2
Mr. jkroon

thanks for you post, it was very helpful.

but then I have a new problem

IPPOOL not releasing IPs after the ppp connection is down
and no error in SYSLOG or in debug mode

just when the pool is all allocated it gives:
"POOL: VIP_users: address allocation failed"

any help please?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group