1193 lines
47 KiB
HTML
1193 lines
47 KiB
HTML
<h1 id="overview">Overview</h1>
|
||
<p><code>l2tpns</code> is half of a complete L2TP implementation. It
|
||
supports only the LNS side of the connection.</p>
|
||
<p>L2TP (Layer 2 Tunneling Protocol) is designed to allow any layer 2
|
||
protocol (e.g. Ethernet, PPP) to be tunneled over an IP connection.
|
||
<code>l2tpns</code> implements PPP over L2TP only.</p>
|
||
<p>There are a couple of other L2TP implementations, of which <a
|
||
href="http://sourceforge.net/projects/l2tpd">l2tpd</a> is probably the
|
||
most popular. l2tpd also will handle being either end of a tunnel, and
|
||
is a lot more configurable than <code>l2tpns</code>. However, due to the
|
||
way it works, it is nowhere near as scalable.</p>
|
||
<p><code>l2tpns</code> uses the TUN/TAP interface provided by the Linux
|
||
kernel to receive and send packets. Using some packet manipulation it
|
||
doesn't require a single interface per connection, as l2tpd does.</p>
|
||
<p>This allows it to scale extremely well to very high loads and very
|
||
high numbers of connections.</p>
|
||
<p>It also has a plugin architecture which allows custom code to be run
|
||
during processing. An example of this is in the walled garden module
|
||
included.</p>
|
||
<h1 id="installation">Installation</h1>
|
||
<h2 id="installation-requirements">Requirements</h2>
|
||
<ul>
|
||
<li><p>Linux kernel version 2.4 or above, with the Tun/Tap interface
|
||
either compiled in, or as a module.</p></li>
|
||
<li><p>libcli 1.8.5 or greater. You can get this from <a
|
||
href="http://sourceforge.net/projects/libcli">SourceForge</a></p></li>
|
||
</ul>
|
||
<h2 id="installation-compile">Compiling</h2>
|
||
<p>You can generally get away with just running <code>make</code> from
|
||
the source directory. This will compile the daemon, associated tools and
|
||
any modules shipped with the distribution.</p>
|
||
<h2 id="installation-install">Installing</h2>
|
||
<p>After you have successfully compiled everything, run
|
||
<code>make install</code> to install it. By default, the binaries are
|
||
installed into <code>/usr/sbin</code>, the configuration into
|
||
<code>/etc/l2tpns</code>, and the modules into
|
||
<code>/usr/lib/l2tpns</code>.</p>
|
||
<p>You will definately need to edit the configuration files before you
|
||
start. See <a href="#configuration">Configuration</a> for more
|
||
information.</p>
|
||
<h2 id="installation-run">Running</h2>
|
||
<p>You only need to run <code>/usr/sbin/l2tpns</code> as root to start
|
||
it. It does not normally detach to a daemon process (see the
|
||
<code>-d</code> option), so you should perhaps run it from
|
||
<code>init</code>.</p>
|
||
<p>By default there is no log destination set, so all log messages will
|
||
go to stdout.</p>
|
||
<h1 id="configuration">Configuration</h1>
|
||
<p>All configuration of the software is done from the files installed
|
||
into <code>/etc/l2tpns</code>.</p>
|
||
<h2 id="config-startup"><code>startup-config</code></h2>
|
||
<p>This is the main configuration file for <code>l2tpns</code>. The
|
||
format of the file is a list of commands that can be run through the
|
||
command-line interface. This file can also be written directly by the
|
||
<code>l2tpns</code> process if a user runs the <code>write memory</code>
|
||
command, so any comments will be lost. However if your policy is not to
|
||
write the config by the program, then feel free to comment the file with
|
||
a <code>#</code> or <code>!</code> at the beginning of the line.</p>
|
||
<p>A list of the possible configuration directives follows. Each of
|
||
these should be set by a line like: set configstring "value" set
|
||
ipaddress 192.168.1.1 set boolean true</p>
|
||
<dl>
|
||
<dt><code>debug</code> (int)</dt>
|
||
<dd>
|
||
<p>Sets the level of messages that will be written to the log file. The
|
||
value should be between 0 and 5, with 0 being no debugging, and 5 being
|
||
the highest. A rough description of the levels is:</p>
|
||
<dl>
|
||
<dt><code>0</code>: Critical Errors</dt>
|
||
<dd>
|
||
<p>Things are probably broken</p>
|
||
</dd>
|
||
<dt><code>1</code>: Errors</dt>
|
||
<dd>
|
||
<p>Things might have gone wrong, but probably will recover</p>
|
||
</dd>
|
||
<dt><code>2</code>: Warnings</dt>
|
||
<dd>
|
||
<p>Just in case you care what is not quite perfect</p>
|
||
</dd>
|
||
<dt><code>3</code>: Information</dt>
|
||
<dd>
|
||
<p>Parameters of control packets</p>
|
||
</dd>
|
||
<dt><code>4</code>: Calls</dt>
|
||
<dd>
|
||
<p>For tracing the execution of the code</p>
|
||
</dd>
|
||
<dt><code>5</code>: Packets</dt>
|
||
<dd>
|
||
<p>Everything, including a hex dump of all packets processed... probably
|
||
twice</p>
|
||
</dd>
|
||
</dl>
|
||
<p>Note that the higher you set the debugging level, the slower the
|
||
program will run. Also, at level 5 a <em>lot</em> of information will be
|
||
logged. This should only ever be used for working out why it doesn't
|
||
work at all.</p>
|
||
</dd>
|
||
<dt><code>log_file</code> (string)</dt>
|
||
<dd>
|
||
<p>This will be where all logging and debugging information is written
|
||
to. This may be either a filename, such as <code>/var/log/l2tpns</code>,
|
||
or the special magic string <code>syslog:</code>facility, where facility
|
||
is any one of the syslog logging facilities, such as
|
||
<code>local5</code>.</p>
|
||
</dd>
|
||
<dt><code>pid_file</code> (string)</dt>
|
||
<dd>
|
||
<p>If set, the process id will be written to the specified file. The
|
||
value must be an absolute path.</p>
|
||
</dd>
|
||
<dt><code>random_device</code> (string)</dt>
|
||
<dd>
|
||
<p>Path to random data source (default <code>/dev/urandom</code>). Use
|
||
"" to use the rand() library function.</p>
|
||
</dd>
|
||
<dt><code>l2tp_secret</code> (string)</dt>
|
||
<dd>
|
||
<p>The secret used by <code>l2tpns</code> for authenticating tunnel
|
||
request. Must be the same as the LAC, or authentication will fail. Only
|
||
actually be used if the LAC requests authentication.</p>
|
||
</dd>
|
||
<dt><code>l2tp_mtu</code> (int)</dt>
|
||
<dd>
|
||
<p>MTU of interface for L2TP traffic (default: <code>1500</code>). Used
|
||
to set link MRU and adjust TCP MSS.</p>
|
||
</dd>
|
||
<dt><code>mp_mrru</code> (int)</dt>
|
||
<dd>
|
||
<p>MRRU for MP traffic (default: <code>1614</code>). Can be set to 0 to
|
||
disable MP negociation.</p>
|
||
</dd>
|
||
<dt><code>ppp_restart_time</code> (int); <code>ppp_max_configure</code>
|
||
(int); <code>ppp_max_failure</code> (int)</dt>
|
||
<dd>
|
||
<p>PPP counter and timer values, as described in §4.1 of <a
|
||
href="ftp://ftp.rfc-editor.org/in-notes/rfc1661.txt">RFC1661</a>.</p>
|
||
</dd>
|
||
<dt><code>primary_dns</code> (ip address); <code>econdary_dns</code> (ip
|
||
address)</dt>
|
||
<dd>
|
||
<p>Whenever a PPP connection is established, DNS servers will be sent to
|
||
the user, both a primary and a secondary. If either is set to 0.0.0.0,
|
||
then that one will not be sent.</p>
|
||
</dd>
|
||
<dt><code>primary_radius</code> (ip address);
|
||
<code>secondary_radius</code> (ip address)</dt>
|
||
<dd>
|
||
<p>Sets the RADIUS servers used for both authentication and accounting.
|
||
If the primary server does not respond, then the secondary RADIUS server
|
||
will be tried.</p>
|
||
<div class="note">
|
||
<p>In addition to the source IP address and identifier, the RADIUS
|
||
server <em>must</em> include the source port when detecting duplicates
|
||
to suppress (in order to cope with a large number of sessions coming
|
||
on-line simultaneously <code>l2tpns</code> uses a set of udp sockets,
|
||
each with a separate identifier).</p>
|
||
</div>
|
||
</dd>
|
||
<dt><code>primary_radius_port</code> (short);
|
||
<code>secondary_radius_port</code> (short)</dt>
|
||
<dd>
|
||
<p>Sets the authentication ports for the primary and secondary RADIUS
|
||
servers. The accounting port is one more than the authentication port.
|
||
If no RADIUS ports are given, the authentication port defaults to 1812,
|
||
and the accounting port to 1813.</p>
|
||
</dd>
|
||
<dt><code>radius_accounting</code> (boolean)</dt>
|
||
<dd>
|
||
<p>If set to true, then RADIUS accounting packets will be sent. This
|
||
means that a Start record will be sent when the session is successfully
|
||
authenticated, and a Stop record will be sent when the session is
|
||
closed.</p>
|
||
</dd>
|
||
<dt><code>radius_interim</code> (int)</dt>
|
||
<dd>
|
||
<p>If <code>radius_accounting</code> is on, defines the interval between
|
||
sending of RADIUS interim accounting records (in seconds).</p>
|
||
</dd>
|
||
<dt><code>radius_secret</code> (string)</dt>
|
||
<dd>
|
||
<p>This secret will be used in all RADIUS queries. If this is not set
|
||
then RADIUS queries will fail.</p>
|
||
</dd>
|
||
<dt><code>radius_require_message_authenticator</code> (string)</dt>
|
||
<dd>
|
||
<p>If set to true, RADIUS answers to AccessRequests will have to contain
|
||
a valid MessageAuthenticator. If set to auto (default), if the first
|
||
RADIUS answer to AccessRequests contains a valid MessageAuthenticator,
|
||
subsequent answers will have to contain one. If set to no (not
|
||
recommended), RADIUS answers to AccessRequests do not have to contain a
|
||
valid MessageAuthenticator. It is advised to set this to true after
|
||
checking that your RADIUS server does send MessageAuthenticator.</p>
|
||
</dd>
|
||
<dt><code>radius_authtypes</code> (string)</dt>
|
||
<dd>
|
||
<p>A comma separated list of supported RADIUS authentication methods
|
||
(<code>pap</code> or <code>chap</code>), in order of preference (default
|
||
<code>pap</code>).</p>
|
||
</dd>
|
||
<dt><code>radius_bind_min</code> (short); <code>radius_bind_max</code>
|
||
(short)</dt>
|
||
<dd>
|
||
<p>Define a port range in which to bind sockets used to send and receive
|
||
RADIUS packets. Must be at least RADIUS_FDS (64) wide. Simplifies
|
||
firewalling of RADIUS ports (default: dynamically assigned).</p>
|
||
</dd>
|
||
<dt><code>radius_dae_port</code> (short)</dt>
|
||
<dd>
|
||
<p>Port for DAE RADIUS (Packet of Death/Disconnect, Change of
|
||
Authorization) requests (default: <code>3799</code>).</p>
|
||
</dd>
|
||
<dt><code>allow_duplicate_users</code> (boolean)</dt>
|
||
<dd>
|
||
<p>Allow multiple logins with the same username. If false (the default),
|
||
any prior session with the same username will be dropped when a new
|
||
session is established.</p>
|
||
</dd>
|
||
<dt><code>guest_account</code> (string)</dt>
|
||
<dd>
|
||
<p>Allow multiple logins matching this specific username.</p>
|
||
</dd>
|
||
<dt><code>bind_address</code> (ip address)</dt>
|
||
<dd>
|
||
<p>When the tun interface is created, it is assigned the address
|
||
specified here. If no address is given, 1.1.1.1 is used. Packets
|
||
containing user traffic should be routed via this address if given,
|
||
otherwise the primary address of the machine.</p>
|
||
</dd>
|
||
<dt><code>peer_address</code> (ip address)</dt>
|
||
<dd>
|
||
<p>Address to send to clients as the default gateway.</p>
|
||
</dd>
|
||
<dt><code>route_protocol</code> (short)</dt>
|
||
<dd>
|
||
<p>Protocol number to record when adding a route (see
|
||
<code>/usr/share/iproute2/rt_protos</code>). This allows to separate
|
||
routes added by several l2tpns instances. The default is 42.</p>
|
||
</dd>
|
||
<dt><code>ipv6_prefix</code> (ipv6 address)</dt>
|
||
<dd>
|
||
<p>Enable negotiation of IPv6. This forms the the first 64 bits of the
|
||
client allocated address. The remaining 64 come from the allocated IPv4
|
||
address and 4 bytes of 0s.</p>
|
||
</dd>
|
||
<dt><code>send_garp</code> (boolean)</dt>
|
||
<dd>
|
||
<p>Determines whether or not to send a gratuitous ARP for the
|
||
bind_address when the server is ready to handle traffic (default:
|
||
<code>true</code>). This value is ignored if BGP is configured.</p>
|
||
</dd>
|
||
<dt><code>throttle_speed</code> (int)</dt>
|
||
<dd>
|
||
<p>Sets the default speed (in kbits/s) which sessions will be limited
|
||
to. If this is set to 0, then throttling will not be used at all. Note:
|
||
You can set this by the CLI, but changes will not affect currently
|
||
connected users.</p>
|
||
</dd>
|
||
<dt><code>throttle_buckets</code> (int)</dt>
|
||
<dd>
|
||
<p>Number of token buckets to allocate for throttling. Each throttled
|
||
session requires two buckets (in and out).</p>
|
||
</dd>
|
||
<dt><code>accounting_dir</code> (string)</dt>
|
||
<dd>
|
||
<p>If set to a directory, then every 5 minutes the current usage for
|
||
every connected use will be dumped to a file in this directory. Each
|
||
file dumped begins with a header, where each line is prefixed by
|
||
<code>#</code>. Following the header is a single line for every
|
||
connected user, fields separated by a space.</p>
|
||
<p>The fields are username, ip, qos, uptxoctets, downrxoctets. The qos
|
||
field is 1 if a standard user, and 2 if the user is throttled.</p>
|
||
</dd>
|
||
<dt><code>dump_speed</code> (boolean)</dt>
|
||
<dd>
|
||
<p>If set to true, then the current bandwidth utilization will be logged
|
||
every second. Even if this is disabled, you can see this information by
|
||
running the <code>uptime</code> command on the CLI.</p>
|
||
</dd>
|
||
<dt><code>multi_read_count</code> (int)</dt>
|
||
<dd>
|
||
<p>Number of packets to read off each of the UDP and TUN fds when
|
||
returned as readable by select (default: 10). Avoids incurring the
|
||
unnecessary system call overhead of select on busy servers.</p>
|
||
</dd>
|
||
<dt><code>scheduler_fifo</code> (boolean)</dt>
|
||
<dd>
|
||
<p>Sets the scheduling policy for the <code>l2tpns</code> process to
|
||
<code>SCHED_FIFO</code>. This causes the kernel to immediately preempt
|
||
any currently running <code>SCHED_OTHER</code> (normal) process in
|
||
favour of <code>l2tpns</code> when it becomes runnable. Ignored on
|
||
uniprocessor systems.</p>
|
||
</dd>
|
||
<dt><code>lock_pages</code> (boolean)</dt>
|
||
<dd>
|
||
<p>Keep all pages mapped by the <code>l2tpns</code> process in
|
||
memory.</p>
|
||
</dd>
|
||
<dt><code>icmp_rate</code> (int)</dt>
|
||
<dd>
|
||
<p>Maximum number of host unreachable ICMP packets to send per
|
||
second.</p>
|
||
</dd>
|
||
<dt><code>packet_limit</code> (int)</dt>
|
||
<dd>
|
||
<p>Maximum number of packets of downstream traffic to be handled each
|
||
tenth of a second per session. If zero, no limit is applied (default:
|
||
0). Intended as a DoS prevention mechanism and not a general throttling
|
||
control (packets are dropped, not queued).</p>
|
||
</dd>
|
||
<dt><code>cluster_address</code> (ip address)</dt>
|
||
<dd>
|
||
<p>Multicast cluster address (default: 239.192.13.13). See <a
|
||
href="#clustering">Clustering</a> for more information.</p>
|
||
</dd>
|
||
<dt><code>cluster_port</code> (udp port)</dt>
|
||
<dd>
|
||
<p>UDP cluster port (default: 32792). See <a
|
||
href="#clustering">Clustering</a> for more information.</p>
|
||
</dd>
|
||
<dt><code>cluster_interface</code> (string)</dt>
|
||
<dd>
|
||
<p>Interface for cluster packets (default: eth0)</p>
|
||
</dd>
|
||
<dt><code>cluster_mcast_ttl</code> (int)</dt>
|
||
<dd>
|
||
<p>TTL for multicast packets (default: 1).</p>
|
||
</dd>
|
||
<dt><code>cluster_hb_interval</code> (int)</dt>
|
||
<dd>
|
||
<p>Interval in tenths of a second between cluster heartbeat/pings.</p>
|
||
</dd>
|
||
<dt><code>cluster_hb_timeout</code> (int)</dt>
|
||
<dd>
|
||
<p>Cluster heartbeat timeout in tenths of a second. A new master will be
|
||
elected when this interval has been passed without seeing a heartbeat
|
||
from the master.</p>
|
||
</dd>
|
||
<dt><code>cluster_master_min_adv</code> (int)</dt>
|
||
<dd>
|
||
<p>Determines the minimum number of up to date slaves required before
|
||
the master will drop routes (default: 1).</p>
|
||
</dd>
|
||
</dl>
|
||
<h3 id="config-startup-bgp">BGP</h3>
|
||
<p>BGP routing configuration is entered by the command: router bgp as
|
||
where as specifies the local AS number.</p>
|
||
<p>Subsequent lines prefixed with neighbour peer define the attributes
|
||
of BGP neighhbours. Valid commands are: neighbour peer remote-as as
|
||
neighbour peer timers keepalive hold</p>
|
||
<p>Where peer specifies the BGP neighbour as either a hostname or IP
|
||
address, as is the remote AS number and keepalive, hold are the timer
|
||
values in seconds.</p>
|
||
<h3 id="config-startup-acl">Access Lists</h3>
|
||
<p>Named access-lists are configured using one of the commands: ip
|
||
access-list standard name ip access-list extended name</p>
|
||
<p>Subsequent lines prefixed with <code>permit</code> or
|
||
<code>deny</code> define the body of the access-list. Standard
|
||
access-list syntax:</p>
|
||
<p>{<code>permit</code>|<code>deny</code>} {host|source
|
||
source-wildcard|<code>any</code>} [{host|destination
|
||
destination-wildcard|<code>any</code>}]</p>
|
||
<p>Extended access-lists:</p>
|
||
<p>{<code>permit</code>|<code>deny</code>} <code>ip</code> {host|source
|
||
source-wildcard|<code>any</code>} {host|destination
|
||
destination-wildcard|<code>any</code>} [<code>fragments</code>]</p>
|
||
<p>{<code>permit</code>|<code>deny</code>} <code>udp</code> {host|source
|
||
source-wildcard|<code>any</code>}
|
||
[{<code>eq</code>|<code>neq</code>|<code>gt</code>|<code>lt</code>}
|
||
port|<code>range</code> from to] {host|destination
|
||
destination-wildcard|<code>any</code>}
|
||
[{<code>eq</code>|<code>neq</code>|<code>gt</code>|<code>lt</code>}
|
||
port|<code>range</code> from to] [<code>fragments</code>]</p>
|
||
<p>{<code>permit</code>|<code>deny</code>} <code>tcp</code> {host|source
|
||
source-wildcard|<code>any</code>}
|
||
[{<code>eq</code>|<code>neq</code>|<code>gt</code>|<code>lt</code>}
|
||
port|<code>range</code> from to] {host|destination
|
||
destination-wildcard|<code>any</code>}
|
||
[{<code>eq</code>|<code>neq</code>|<code>gt</code>|<code>lt</code>}
|
||
port|<code>range</code> from to]
|
||
[{<code>established</code>|{<code>match-any</code>|<code>match-all</code>}
|
||
{<code>+</code>|<code>-</code>}{<code>fin</code>|<code>syn</code>|<code>rst</code>|<code>psh</code>|<code>ack</code>|<code>urg</code>}
|
||
...|<code>fragments</code>]</p>
|
||
<h2 id="config-users"><code>users</code></h2>
|
||
<p>Usernames and passwords for the command-line interface are stored in
|
||
this file. The format is username:password where password may either by
|
||
plain text, an MD5 digest (prefixed by
|
||
<code>$1</code>salt<code>$</code>) or a DES password, distinguished from
|
||
plain text by the prefix <code>{crypt}</code>.</p>
|
||
<p>The username <code>enable</code> has a special meaning and is used to
|
||
set the enable password.</p>
|
||
<div class="important">
|
||
<p>If this file doesn't exist, then anyone who can get to port 23 will
|
||
be allowed access without a username or password.</p>
|
||
</div>
|
||
<h2 id="config-ip-pool"><code>ip_pool</code></h2>
|
||
<p>This file is used to configure the IP address pool which user
|
||
addresses are assigned from. This file should contain either an IP
|
||
address or a CIDR network per line. e.g.:</p>
|
||
<pre><code>192.168.1.1
|
||
192.168.1.2
|
||
192.168.1.3
|
||
192.168.4.0/24
|
||
172.16.0.0/16
|
||
10.0.0.0/8</code></pre>
|
||
<p>Keep in mind that <code>l2tpns</code> can only handle 65535
|
||
connections per process, so don't put more than 65535 IP addresses in
|
||
the configuration file. They will be wasted.</p>
|
||
<h2 id="config-build-garden"><code>build-garden</code></h2>
|
||
<p>The garden plugin on startup creates a NAT table called "garden" then
|
||
sources the <code>build-garden</code> script to populate that table. All
|
||
packets from gardened users will be sent through this table.
|
||
Example:</p>
|
||
<pre><code>iptables -t nat -A garden -p tcp -m tcp --dport 25 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p udp -m udp --dport 53 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p tcp -m tcp --dport 53 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p tcp -m tcp --dport 80 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p tcp -m tcp --dport 110 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p tcp -m tcp --dport 443 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p icmp -m icmp --icmp-type echo-request -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p icmp -j ACCEPT
|
||
iptables -t nat -A garden -j DROP</code></pre>
|
||
<h1 id="operation">Operation</h1>
|
||
<p>A running l2tpns process can be controlled in a number of ways. The
|
||
primary method of control is by the Command-Line Interface (CLI).</p>
|
||
<p>You can also remotely send commands to modules via the
|
||
<code>nsctl</code> client provided.</p>
|
||
<p>There are also a number of signals that l2tpns understands and takes
|
||
action when it receives them.</p>
|
||
<h2 id="operation-cli">Command-Line Interface</h2>
|
||
<p>You can access the command line interface by telneting to port 23.
|
||
There is no IP address restriction, so it's a good idea to firewall this
|
||
port off from anyone who doesn't need access to it. See <a
|
||
href="#config-users"></a> for information on restricting access based on
|
||
a username and password.</p>
|
||
<p>The CLI gives you real-time control over almost everything in the
|
||
process. The interface is designed to look like a Cisco device, and
|
||
supports things like command history, line editing and context sensitive
|
||
help. This is provided by linking with the <a
|
||
href="http://sourceforge.net/projects/libcli">libcli</a> library. Some
|
||
general documentation of the interface is <a
|
||
href="http://sourceforge.net/docman/display_doc.php?docid=20501&group_id=79019">here</a>.</p>
|
||
<p>After you have connected to the telnet port (and perhaps logged in),
|
||
you will be presented with a <code>hostname></code> prompt.</p>
|
||
<p>Enter <code>help</code> to get a list of possible commands, or press
|
||
<code>?</code> for context-specific help.</p>
|
||
<p>A brief overview of the more important commands follows:</p>
|
||
<p><code>show session [ID]</code></p>
|
||
<p>: Detailed information for a specific session is presented if you
|
||
specify a session ID argument.</p>
|
||
<pre><code>If no ID is given, a summary of all connected sessions is produced.
|
||
Note that this summary list can be around 185 columns wide, so you
|
||
should probably use a wide terminal.
|
||
|
||
The columns listed in the summary are:
|
||
|
||
-------------- -------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------
|
||
`SID` Session ID
|
||
`TID` Tunnel ID See also the [show tunnel](#operation-cli-show-tunnel) CLI command.
|
||
`Username` The username given in the PPP authentication. If this is \*, then LCP authentication has not completed.
|
||
`IP` The IP address given to the session. If this is 0.0.0.0, IPCP negotiation has not completed
|
||
`I` Intercept Y or N: indicates whether the session is being snooped. See also the [snoop](#operation-cli-snoop) CLI command.
|
||
`T` Throttled Y or N: indicates whether the session is currently throttled. See also the [throttle](#operation-cli-throttle) CLI command.
|
||
`G` Walled Garden Y or N: indicates whether the user is trapped in the walled garden. This field is present even if the garden module is not loaded.
|
||
`6` IPv6 Y or N: indicates whether the session has IPv6 active (IPV6CP open)
|
||
`opened` The number of seconds since the session started
|
||
`downloaded` Number of bytes downloaded by the user
|
||
`uploaded` Number of bytes uploaded by the user
|
||
`idle` The number of seconds since traffic was detected on the session
|
||
`LAC` The IP address of the LAC the session is connected to.
|
||
`CLI` The Calling-Line-Identification field provided during the session setup. This field is generated by the LAC.
|
||
-------------- -------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------</code></pre>
|
||
<p><code>show users</code>; <code>show user username</code></p>
|
||
<p>: With no arguments, display a list of currently connected users. If
|
||
an argument is given, the session details for the given username are
|
||
displayed.</p>
|
||
<dl>
|
||
<dt><code>show tunnel [ID]</code></dt>
|
||
<dd>
|
||
<p>Produce a summary list of all open tunnels, or detail on a specific
|
||
tunnel ID.</p>
|
||
<p>The columns listed in the summary are:</p>
|
||
<table>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">TID</td>
|
||
<td style="text-align: left;">Tunnel ID</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">Hostname</td>
|
||
<td style="text-align: left;">The hostname for the tunnel as provided by
|
||
the LAC. This has no relation to DNS, it is just a text field.</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">IP</td>
|
||
<td style="text-align: left;">The IP address of the LAC</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">State</td>
|
||
<td style="text-align: left;">Tunnel state: Free, Open, Dieing,
|
||
Opening</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">Sessions</td>
|
||
<td style="text-align: left;">The number of open sessions on the
|
||
tunnel</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</dd>
|
||
<dt><code>show pool</code></dt>
|
||
<dd>
|
||
<p>Displays the current IP address pool allocation. This will only
|
||
display addresses that are in use, or are reserved for re-allocation to
|
||
a disconnected user.</p>
|
||
<p>If an address is not currently in use, but has been used, then in the
|
||
User column the username will be shown in square brackets, followed by
|
||
the time since the address was used:</p>
|
||
<pre><code>IP Address Used Session User
|
||
192.168.100.6 N [joe.user] 1548s</code></pre>
|
||
</dd>
|
||
<dt><code>show radius</code></dt>
|
||
<dd>
|
||
<p>Show a summary of the in-use RADIUS sessions. This list should not be
|
||
very long, as RADIUS sessions should be cleaned up as soon as they are
|
||
used. The columns listed are:</p>
|
||
<table>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">Radius</td>
|
||
<td style="text-align: left;">The ID of the RADIUS request. This is sent
|
||
in the packet to the RADIUS server for identification</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">State</td>
|
||
<td style="text-align: left;">The state of the request: WAIT, CHAP,
|
||
AUTH, IPCP, START, STOP or NULL</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">Session</td>
|
||
<td style="text-align: left;">The session ID that this RADIUS request is
|
||
associated with</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">Retry</td>
|
||
<td style="text-align: left;">If a response does not appear to the
|
||
request, it will retry at this time. This is a Unix timestamp</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">Try</td>
|
||
<td style="text-align: left;">Retry count. The RADIUS request is
|
||
discarded after 3 retries</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</dd>
|
||
<dt><code>show running-config</code></dt>
|
||
<dd>
|
||
<p>This will list the current running configuration. This is in a format
|
||
that can either be pasted into the configuration file, or run directly
|
||
at the command line.</p>
|
||
</dd>
|
||
<dt><code>show counters</code></dt>
|
||
<dd>
|
||
<p>Internally, counters are kept of key values, such as bytes and
|
||
packets transferred, as well as function call counters. This function
|
||
displays all these counters, and is probably only useful for
|
||
debugging.</p>
|
||
<p>You can reset these counters by running
|
||
<code>clear counters</code>.</p>
|
||
</dd>
|
||
<dt><code>show cluster</code></dt>
|
||
<dd>
|
||
<p>Show cluster status. Shows the cluster state for this server
|
||
(Master/Slave), information about known peers and (for slaves) the
|
||
master IP address, last packet seen and up-to-date status. See <a
|
||
href="#clustering">Clustering</a> for more information.</p>
|
||
</dd>
|
||
<dt><code>write memory</code></dt>
|
||
<dd>
|
||
<p>This will write the current running configuration to the config file
|
||
<code>startup-config</code>, which will be run on a restart.</p>
|
||
</dd>
|
||
</dl>
|
||
<p><code>snoop user IP port</code></p>
|
||
<p>: You must specify a username, IP address and port. All packets for
|
||
the current session for that username will be forwarded to the given
|
||
host/port. Specify <code>no snoop username</code> to disable
|
||
interception for the session.</p>
|
||
<pre><code>If you want interception to be permanent, you will have to modify
|
||
the RADIUS response for the user. See [Interception](#interception).</code></pre>
|
||
<p><code>throttle user [in|out] rate</code></p>
|
||
<p>: You must specify a username, which will be throttled for the
|
||
current session to rate Kbps. Prefix rate with <code>in</code> or
|
||
<code>out</code> to set different upstream and downstream rates.</p>
|
||
<pre><code>Specify `no throttle
|
||
username` to disable throttling for the current session.
|
||
|
||
If you want throttling to be permanent, you will have to modify the
|
||
RADIUS response for the user. See [Throttling](#throttling).</code></pre>
|
||
<dl>
|
||
<dt><code>drop session</code></dt>
|
||
<dd>
|
||
<p>This will cleanly disconnect the session specified by session ID.</p>
|
||
</dd>
|
||
<dt><code>drop tunnel</code></dt>
|
||
<dd>
|
||
<p>This will cleanly disconnect the tunnel specified by tunnel ID, as
|
||
well as all sessions on that tunnel.</p>
|
||
</dd>
|
||
<dt><code>uptime</code></dt>
|
||
<dd>
|
||
<p>This will show how long the <code>l2tpns</code> process has been
|
||
running, and the current bandwidth utilization:</p>
|
||
<pre><code>17:10:35 up 8 days, 2212 users, load average: 0.21, 0.17, 0.16
|
||
Bandwidth: UDP-ETH:6/6 ETH-UDP:13/13 TOTAL:37.6 IN:3033 OUT:2569</code></pre>
|
||
<p>The bandwidth line contains 4 sets of values:</p>
|
||
<table>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">UDP-ETH</td>
|
||
<td style="text-align: left;">The current bandwidth going from the LAC
|
||
to the ethernet (user uploads), in mbits/sec.</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">ETH-UDP</td>
|
||
<td style="text-align: left;">The current bandwidth going from ethernet
|
||
to the LAC (user downloads).</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">TOTAL</td>
|
||
<td style="text-align: left;">The total aggregate bandwidth in
|
||
mbits/s.</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">IN and OUT</td>
|
||
<td style="text-align: left;">Packets/per-second going between UDP-ETH
|
||
and ETH-UDP.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>These counters are updated every second.</p>
|
||
</dd>
|
||
<dt><code>configure terminal</code></dt>
|
||
<dd>
|
||
<p>Enter configuration mode. Use <code>exit</code> or <code>^Z</code> to
|
||
exit this mode.</p>
|
||
<p>The following commands are valid in this mode:</p>
|
||
<p><code>load plugin name</code></p>
|
||
<p>: Load a plugin. You must specify the plugin name, and it will search
|
||
in <code>/usr/lib/l2tpns</code> for <code>name.so</code>. You can unload
|
||
a loaded plugin with
|
||
<code>remove plugin name</code>.</p>
|
||
<dl>
|
||
<dt><code>set</code> ...</dt>
|
||
<dd>
|
||
<p>Set a configuration variable. You must specify the variable name, and
|
||
the value. If the value contains any spaces, you should quote the value
|
||
with double (") or single (') quotes.</p>
|
||
<p>You can set any configuration value in this way, although some may
|
||
require a restart to take effect. See <a
|
||
href="#config-startup"></a>.</p>
|
||
</dd>
|
||
<dt><code>router bgp</code> ...</dt>
|
||
<dd>
|
||
<p>Configure BGP. See <a href="#config-startup-bgp">BGP</a>.</p>
|
||
</dd>
|
||
<dt><code>ip access-list</code> ...</dt>
|
||
<dd>
|
||
<p>Configure a named access list. See <a
|
||
href="#config-startup-acl">Access Lists</a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</dd>
|
||
</dl>
|
||
<h2 id="operation-nsctl">nsctl</h2>
|
||
<p><code>nsctl</code> sends messages to a running <code>l2tpns</code>
|
||
instance to be control plugins.</p>
|
||
<p>Arguments are <code>command</code> and optional args. See
|
||
<code>nsctl(8)</code>.</p>
|
||
<p>Built-in command are <code>load_plugin</code>,
|
||
<code>unload_plugin</code> and <code>help</code>. Any other commands are
|
||
passed to plugins for processing by the <code>plugin_control</code>
|
||
function.</p>
|
||
<h2 id="operation-signals">Signals</h2>
|
||
<p>While the process is running, you can send it a few different
|
||
signals, using the <code>kill</code> command.</p>
|
||
<pre><code>killall -HUP l2tpns</code></pre>
|
||
<p>The signals understood are:</p>
|
||
<dl>
|
||
<dt>SIGHUP</dt>
|
||
<dd>
|
||
<p>Reload the config from disk and re-open log file.</p>
|
||
</dd>
|
||
<dt>SIGTERM; SIGINT</dt>
|
||
<dd>
|
||
<p>Stop process. Tunnels and sessions are not terminated. This signal
|
||
should be used to stop <code>l2tpns</code> on a cluster node where there
|
||
are other machines to continue handling traffic. See <a
|
||
href="#clustering">Clustering</a></p>
|
||
</dd>
|
||
<dt>SIGQUIT</dt>
|
||
<dd>
|
||
<p>Shut down tunnels and sessions, exit process when complete.</p>
|
||
</dd>
|
||
</dl>
|
||
<h1 id="throttling">Throttling</h1>
|
||
<p><code>l2tpns</code> contains support for slowing down user sessions
|
||
to whatever speed you desire. The global setting
|
||
<code>throttle_speed</code> defines the default throttle rate.</p>
|
||
<p>To throttle a sesion permanently, add a <code>Cisco-AVPair</code>
|
||
RADIUS attribute. The <code>autothrotle</code> module interprets the
|
||
following attributes:</p>
|
||
<table>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td style="text-align: left;"><code>throttle=yes</code></td>
|
||
<td style="text-align: left;">Throttle upstream/downstream traffic to
|
||
the configured <code>throttle_speed</code>.</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;"><code>throttle=rate</code></td>
|
||
<td style="text-align: left;">Throttle upstream/downstream traffic to
|
||
the specified rate Kbps.</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">`lcp:interface-config#1=service-policy
|
||
input</td>
|
||
<td style="text-align: left;">Alternate (Cisco) format: throttle
|
||
upstream/downstream to specified rate Kbps.</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">rate`</td>
|
||
<td style="text-align: left;"></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td style="text-align: left;">`lcp:interface-config#2=service-policy
|
||
output</td>
|
||
<td style="text-align: left;"></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td style="text-align: left;">rate`</td>
|
||
<td style="text-align: left;"></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>You can also enable and disable throttling an active session using
|
||
the <a href="#operation-cli-throttle">throttle</a> CLI command.</p>
|
||
<h1 id="interception">Interception</h1>
|
||
<p>You may have to deal with legal requirements to be able to intercept
|
||
a user's traffic at any time. <code>l2tpns</code> allows you to begin
|
||
and end interception on the fly, as well as at authentication time.</p>
|
||
<p>When a user is being intercepted, a copy of every packet they send
|
||
and receive will be sent wrapped in a UDP packet to a specified
|
||
host.</p>
|
||
<p>The UDP packet contains just the raw IP frame, with no extra headers.
|
||
The script <code>scripts/l2tpns-capture</code> may be used as the
|
||
end-point for such intercepts, writing the data in PCAP format (suitable
|
||
for inspection with <code>tcpdump</code>).</p>
|
||
<p>To enable or disable interception of a connected user, use the <a
|
||
href="#operation-cli-snoop">snoop</a> and <code>no snoop</code>
|
||
CLI commands. These will enable interception immediately.</p>
|
||
<p>If you wish the user to be intercepted whenever they reconnect, you
|
||
will need to modify the RADIUS response to include the Vendor-Specific
|
||
value <code>Cisco-AVPair="intercept=ip:port"</code>. For this feature to
|
||
be enabled, you need to have the <code>autosnoop</code> module
|
||
loaded.</p>
|
||
<h1 id="plugins">Plugins</h1>
|
||
<p>So as to make <code>l2tpns</code> as flexible as possible, a plugin
|
||
API is include which you can use to hook into certain events.</p>
|
||
<p>There are a some standard modules included which may be used as
|
||
examples: <code>autosnoop</code>, <code>autothrottle</code>,
|
||
<code>garden</code>, <code>sessionctl</code>, <code>setrxspeed</code>,
|
||
<code>snoopctl</code>, <code>stripdomain</code> and
|
||
<code>throttlectl</code>.</p>
|
||
<p>When an event occurs that has a hook, <code>l2tpns</code> looks for a
|
||
predefined function name in every loaded module, and runs them in the
|
||
order the modules were loaded.</p>
|
||
<p>The function should return <code>PLUGIN_RET_OK</code> if it is all
|
||
OK. If it returns <code>PLUGIN_RET_STOP</code>, then it is assumed to
|
||
have worked, but that no further modules should be run for this
|
||
event.</p>
|
||
<p>A return of <code>PLUGIN_RET_ERROR</code> means that this module
|
||
failed, and no further processing should be done for this event.</p>
|
||
<div class="note">
|
||
<p>Use this with care.</p>
|
||
</div>
|
||
<p>Most event functions take a specific structure named
|
||
<code>param_event</code>, which varies in content with each event. The
|
||
function name for each event will be <code>plugin_event</code>, so for
|
||
the event timer, the function declaration should look like:</p>
|
||
<pre><code>int plugin_timer(struct param_timer *data);</code></pre>
|
||
<p>A list of the available events follows, with a list of all the fields
|
||
in the supplied structure:</p>
|
||
<table style="width:97%;">
|
||
<colgroup>
|
||
<col style="width: 29%" />
|
||
<col style="width: 29%" />
|
||
<col style="width: 29%" />
|
||
<col style="width: 8%" />
|
||
</colgroup>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td rowspan="2"><h1 id="event">Event</h1>
|
||
<p><code>plugin_init</code></p></td>
|
||
<td rowspan="2"><h1 id="description">Description</h1>
|
||
<p>Called when the plugin is loaded. A pointer to a struct containing
|
||
function pointers is passed as the only argument, allowing the plugin to
|
||
call back into the main code.</p>
|
||
<p>Prior to loading the plugin, <code>l2tpns</code> checks the API
|
||
version the plugin was compiled against. All plugins should contain:</p>
|
||
<pre><code> int</code></pre>
|
||
<p>plugin_api_version = PLUGIN_API_VERSION;</p></td>
|
||
<td rowspan="2"><h1 id="arguments">Arguments</h1>
|
||
<p><code>s truct pluginfuncs *</code></p></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td>See <code>pluginfuncs</code> structure in <code>plugin.h</code> for
|
||
available functions.</td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>plugin_done</code></td>
|
||
<td>Called when the plugin is unloaded or <code>l2tpns</code> is
|
||
shutdown.</td>
|
||
<td><code>void</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td>No arguments.</td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>plugin_pre_auth</code></td>
|
||
<td>Called after a RADIUS response has been received, but before it has
|
||
been processed by the code. This will allow you to modify the response
|
||
in some way.</td>
|
||
<td><code>struct plug in param_pre_auth *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>char *username</code></td>
|
||
<td>User name.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>char *password</code></td>
|
||
<td>Password.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>int protocol</code></td>
|
||
<td>Authentication protocol: <code>0xC023</code> for PAP,
|
||
<code>0xC223</code> for CHAP.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>int continue_auth</code></td>
|
||
<td>Set to 0 to stop processing authentication modules.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>plugin_post_auth</code></td>
|
||
<td>Called after a RADIUS response has been received, and the basic
|
||
checks have been performed. This is what the <code>garden</code> module
|
||
uses to force authentication to be accepted.</td>
|
||
<td><code>struct plugi n param_post_auth *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>char *username</code></td>
|
||
<td>User name.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>short auth_allowed</code></td>
|
||
<td>Initially true or false depending on whether authentication has been
|
||
allowed so far. You can set this to 1 or 0 to force authentication to be
|
||
accepted or rejected.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>int protocol</code></td>
|
||
<td>Authentication protocol: <code>0xC023</code> for PAP,
|
||
<code>0xC223</code> for CHAP.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>plugin_timer</code></td>
|
||
<td>Run once per second.</td>
|
||
<td><code>struct p lugin param_timer *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>time_t time_now</code></td>
|
||
<td>The current unix timestamp.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>plugin_new_session</code></td>
|
||
<td>Called after a session is fully set up. The session is now ready to
|
||
handle traffic.</td>
|
||
<td><code>struct plugin param_new_session *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>plugin_kill_session</code></td>
|
||
<td>Called when a session is about to be shut down. This may be called
|
||
multiple times for the same session.</td>
|
||
<td><code>struct plugin p aram_kill_session *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>plugin_control</code></td>
|
||
<td><p>Called in whenever a <code>nsctl</code> packet is received. This
|
||
should handle the packet and form a response if required.</p>
|
||
<p>Plugin-specific help strings may be included in the output of
|
||
<code>nsctl help</code> by defining a <code>NULL</code> terminated list
|
||
of strings as follows:</p>
|
||
<pre><code>char</code></pre>
|
||
<p>*plugin_control_hel p[] = { …, NULL };</p></td>
|
||
<td><code>struct plu gin param_control *</code></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>int iam_master</code></td>
|
||
<td>If true, this node is the cluster master.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>int argc</code></td>
|
||
<td><code>nsctl</code> arguments.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>char **argc</code></td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>int response</code></td>
|
||
<td>Response from control message (if handled): should be either
|
||
<code>NSCTL_RES_OK</code> or <code>NSCTL_RES_ERR</code>.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>char *additional</code></td>
|
||
<td>Additional information, output by <code>nsctl</code> on receiving
|
||
the response.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td colspan="4"><code>plugin_radius_response</code> | Called whenever a
|
||
|
|
||
<code>struct plugin para | | RADIUS response | m_radius_response *</code>
|
||
| | includes a | | | <code>Cisco-AVPair</code> | | | value. The value is
|
||
| | | split into | | | key<code>=</code>value pairs. | | | Will be
|
||
called once | | | for each pair in the | | | response. | |</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>char *key</code></td>
|
||
<td>Key and value.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>char *value</code></td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td colspan="4"><code>plugin_radius_reset</code> | Called whenever a |
|
||
<code>struct p | | RADIUS CoA request | aram_radius_reset *</code>
|
||
| | is received to reset | | | any options to | | | default values | | |
|
||
before the new | | | values are applied. | |</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td colspan="4"><code>plugin_radius_account</code> | Called when |
|
||
<code>struct par | | preparing a RADIUS | am_radius_account *</code>
|
||
| | accounting record to | | | allow additional | | | data to be added
|
||
to | | | the packet. | |</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>tunnelt *t</code></td>
|
||
<td>Tunnel.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>sessiont *s</code></td>
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>uint8_t **packet</code></td>
|
||
<td>Pointer to the end of the currently assembled packet buffer. The
|
||
value should be incremented by the length of any data added.</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td colspan="4"><code>plugin_become_master</code> | Called when a node |
|
||
<code>void</code> | | elects itself | | | cluster master. | |</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td>No arguments.</td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td colspan="4"><code>plugin_new_session_master</code> | Called once for
|
||
each | <code>sessiont *</code> | open session on | | | becoming cluster
|
||
| | | master. | |</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td>Session.</td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h1 id="walled-garden">Walled Garden</h1>
|
||
<p>A "Walled Garden" is implemented so that you can provide perhaps
|
||
limited service to sessions that incorrectly authenticate.</p>
|
||
<p>Whenever a session provides incorrect authentication, and the RADIUS
|
||
server responds with Auth-Reject, the walled garden module (if loaded)
|
||
will force authentication to succeed, but set the
|
||
<code>walled_garden</code> flag in the session structure, and adds an
|
||
<code>iptables</code> rule to the <code>garden_users</code> chain to
|
||
cause all packets for the session to traverse the <code>garden</code>
|
||
chain.</p>
|
||
<p>This doesn't <em>just work</em>. To set this all up, you will to
|
||
setup the <code>garden</code> nat table with the <a
|
||
href="#config-build-garden">build-garden</a> script with rules to limit
|
||
user's traffic.</p>
|
||
<p>For example, to force all traffic except DNS to be forwarded to
|
||
192.168.1.1, add these entries to your <code>build-garden</code>
|
||
script:</p>
|
||
<pre><code>iptables -t nat -A garden -p tcp --dport ! 53 -j DNAT --to 192.168.1.1
|
||
iptables -t nat -A garden -p udp --dport ! 53 -j DNAT --to 192.168.1.1</code></pre>
|
||
<p><code>l2tpns</code> will add entries to the <code>garden_users</code>
|
||
chain as appropriate.</p>
|
||
<p>You can check the amount of traffic being captured using the
|
||
following command:</p>
|
||
<pre><code>iptables -t nat -L garden -nvx</code></pre>
|
||
<h1 id="filtering">Filtering</h1>
|
||
<p>Sessions may be filtered by specifying <code>Filter-Id</code>
|
||
attributes in the RADIUS reply. filter.<code>in</code> specifies that
|
||
the named access-list filter should be applied to traffic from the
|
||
customer, filter.<code>out</code> specifies a list for traffic to the
|
||
customer.</p>
|
||
<h1 id="clustering">Clustering</h1>
|
||
<p>An <code>l2tpns</code> cluster consists of one* or more servers
|
||
configured with the same configuration, notably the multicast
|
||
<code>cluster_address</code> and the <code>cluster_port</code></p>
|
||
<p>*A stand-alone server is simply a degraded cluster.</p>
|
||
<p>Initially servers come up as cluster slaves, and periodically (every
|
||
<code>cluster_hb_interval</code>/10 seconds) send out ping packets
|
||
containing the start time of the process to the multicast
|
||
<code>cluster_address</code> on <code>cluster_port</code>.</p>
|
||
<p>A cluster master sends heartbeat rather than ping packets, which
|
||
contain those session and tunnel changes since the last heartbeat.</p>
|
||
<p>When a slave has not seen a heartbeat within
|
||
<code>cluster_hb_timeout</code>/10 seconds it "elects" a new master by
|
||
examining the list of peers it has seen pings from and determines which
|
||
of these and itself is the "best" candidate to be master. "Best" in this
|
||
context means the server with the highest uptime (the highest IP address
|
||
is used as a tie-breaker in the case of equal uptimes).</p>
|
||
<p>After discovering a master, and determining that it is up-to-date
|
||
(has seen an update for all in-use sessions and tunnels from heartbeat
|
||
packets) will raise a route (see <a href="#routing">Routing</a>) for the
|
||
<code>bind_address</code> and for all addresses/networks in
|
||
<code>ip_pool</code>.</p>
|
||
<p>Any packets received by the slave which would alter the session
|
||
state, as well as packets for throttled or gardened sessions are
|
||
forwarded to the master for handling. In addition, byte counters for
|
||
session traffic are periodically forwarded.</p>
|
||
<p>The master, when determining that it has at least one* up-to-date
|
||
slave will drop all routes (raising them again if all slaves disappear)
|
||
and subsequently handle only packets forwarded to it by the slaves.</p>
|
||
<p>*Configurable with <code>cluster_master_min_adv</code></p>
|
||
<p>Multiple clusters can be run on the same network by just using
|
||
different multicast <code>cluster_address</code>. However, for a given
|
||
host to be part of multiple clusters without mixing the clusters,
|
||
<code>cluster_port</code> must be different for each cluster.</p>
|
||
<h1 id="routing">Routing</h1>
|
||
<p>If you are running a single instance, you may simply statically route
|
||
the IP pools to the <code>bind_address</code> (<code>l2tpns</code> will
|
||
send a gratuitous arp).</p>
|
||
<p>For a cluster, configure the members as BGP neighbours on your router
|
||
and configure multi-path load-balancing. Cisco uses
|
||
<code>maximum-paths ibgp</code> for IBGP. If this is not supported by
|
||
your IOS revision, you can use <code>maximum-paths</code> (which works
|
||
for EBGP) and set <code>as_number</code> to a private value such as
|
||
64512.</p>
|