Giter Club home page Giter Club logo

go-l2tp's Introduction

go-l2tp

go-l2tp is suite of Go libraries for building L2TP applications on Linux systems.

Features

  • L2TPv2 (RFC2661) and L2TPv3 (RFC3931) data plane via. Linux L2TP subsystem
  • AF_INET and AF_INET6 tunnel addresses
  • UDP and L2TPIP tunnel encapsulation
  • L2TPv2 control plane in client/LAC mode
  • PPPoE (RFC2561) control and data plane via. Linux L2TP subsystem.

Installation

If you're familiar with Go, you can skip this section.

Prior to installing go-l2tp, install the Go language distribution which includes the compiler and other tooling required to install Go programs. Please follow the instructions from the Go project to get your installation up and running.

You can now install go-l2tp as follows:

go install github.com/katalix/go-l2tp/...@latest

Read on for instructions on coding using the library.

Import

import (
    "github.com/katalix/go-l2tp/l2tp"
    "github.com/katalix/go-l2tp/pppoe"
    "github.com/katalix/go-l2tp/config"
)

Usage

# Note we're ignoring errors for brevity.

# Read configuration using the config package.
# This is optional: you can build your own configuration
# structures if you prefer.
config, _ := config.LoadFile("./my-l2tp-config.toml")

# Creation of L2TP instances requires an L2TP context.
# We're disabling logging and using the default Linux data plane.
l2tpctx, _ := l2tp.NewContext(l2tp.LinuxNetlinkDataPlane, nil)

# Create tunnel and session instances based on the config
for _, tcfg := range config.Tunnels {
    tunl, _ := l2tpctx.NewStaticTunnel(tcfg.Name, tcfg.Config)
        for _, scfg := range tcfg.Sessions {
            _, _, := tunl.NewSession(scfg.Name, scfg.Config)
        }
}

Tools

go-l2tp includes three tools which build on the library.

ql2tpd

ql2tpd is a minimal daemon for creating static L2TPv3 sessions.

This tool requires root permissions to run, and is driven by a configuration file which details the tunnel and session instances to create.

Each tunnel may run as a purely static instance. In this mode ql2tpd represents a more convenient way to bring up static sessions than ip l2tp commands.

If a tunnel has a hello_timeout set, the tunnel will send a periodic keep-alive packet over a minimal implementation of the RFC3931 reliable control message transport. This allows for the detection of tunnel failure, which will then tear down the sessions running in that tunnel. hello_timeout should only be enabled if the peer is also running ql2tpd.

kl2tpd

kl2tpd is a client/LAC-mode daemon for creating L2TPv2 sessions. It spawns the standard Linux pppd for PPP protocol support.

Similar to ql2tpd, kl2tpd requires root permissions to run, and is driven by a configuration file which details the tunnel and session instances to create.

In addition to the configuration parameters documented by package config, kl2tpd supports an extra session parameter, pppd_args which calls out an argument file for extra pppd command line arguments. Here is an example configuration for establishing a single tunnel containing a single session:

[tunnel.t1]
peer = "42.102.77.204:1701"
version = "l2tpv2"
encap = "udp"

[tunnel.t1.session.s1]
pseudowire = "ppp"
pppd_args = "/home/bob/pppd.args"

kpppoed

kpppoed is a PPPoE daemon for creating L2TPv2 Access Concentrator sessions in response to PPPoE requests. It spawns kl2tpd for L2TP protocol support.

kpppoed uses a minimal configuration file format which calls out the interface to listen on for PPPoE packets, the list of PPPoE services to offer, and the IP address of the LNS to use for establishing L2TPv2 sessions. Here is an example configuration:

ac_name = "kpppoed-1.0"
interface_name = "eth0"
services = [ "myservice" ]
lns_ipaddr = "192.168.1.69:1701"

Documentation

The go-l2tp library and tools are documented using Go's documentation tool. A top-level description of the various libraries can be viewed as follows:

go doc l2tp
go doc pppoe
go doc config

This top level document provides a summary of the main APIs the library exposes.

You can view documentation of a particular API or type like this:

go doc l2tp.Context

Finally, documentation of various commands like this:

go doc cmd/ql2tpd
go doc cmd/kl2tpd
go doc cmd/kpppoed

Testing

go-l2tp has unit tests which can be run using go test:

go test ./...

Some tests instantiate tunnels and sessions in the Linux kernel's L2TP subsystem, and hence require root permissions to run. By default these tests are skipped if run as a normal user.

The tests requiring root can be run as follows:

go test -exec sudo -run TestRequiresRoot ./...

The tests are run using sudo, which will need to be set up for your user, and require the Linux kernel L2TP modules to be loaded.

For the l2tp library tests:

modprobe l2tp_core l2tp_netlink l2tp_eth l2tp_ip l2tp_ip6

And for the pppoe library tests:

modprobe l2tp_ac_pppoe

Depending on your Linux distribution it may be necessary to install an extra package to get the L2TP subsystem modules. For example on Ubuntu:

sudo apt-get install linux-modules-extra-$(uname -r)

The script runtests.sh automates running all the tests (both those requiring root and not) and generates a html test coverage report:

./runtests.sh && firefox ./coverage.html

go-l2tp's People

Contributors

tomparkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-l2tp's Issues

L2TPv3 dynamic tunnels

This is my first time working with L2TP and I was really happy to find a well document library. I need dynamic L2TPv3 tunnels for my use case (as far as I know at least :D) and I stumbled upon the following error:

return nil, fmt.Errorf("L2TPv3 dynamic tunnels are not (yet) supported")

Why exactly does this library not support dynamic L2TPv3 tunnels?
Is this hard to achieve, because it is complex to implement or is it just a lot of work but relatively easy to implement and therefore doable for a L2TP noob like me? :)

If the latter applies, I would think about opening a PR, because my life would be a lot simpler, if this library would cover my use case.

"Malformed header" error terminates connection

Hi, I am running into #4. My current solution is to use xl2tpd vs go-l2tp/kl2tp.

As noted there, it can be observed in the logs that the length reported matches the tunnel ID:

The issue is definitely the following in the kl2tpd logs:

level=error tunnel_name=t1 function=transport message="frame receive failed" error="malformed header: length 17024 exceeds buffer bounds of 30"

You'll also notice elsewhere that tunnel_id=17024, so it would appear that the malformed header received from the VPN server for the AVP ICCN response has the length field mixed up somehow with the tunnel_id.

level=debug tunnel_name=t1 function=transport message=recv message_type=avpMsgTypeSli
level=error tunnel_name=t1 message="bad control message" message_type=avpMsgTypeSli error="no specification for v2 message avpMsgTypeSli"

Interestingly, xl2tpd debug logs state:

message_type_avp: message type 16 (Set-Link-Info)
ignore_avp : Ignoring AVP

Particularly, this is supposedly some Cisco Meraki gear:

xl2tpd[132243]: vendor_avp: peer reports vendor 'Katalix Systems Ltd. Linux-4.4.177-meraki (x86_64)'

I haven't compared with xl2tpd's implementation yet, but it would be nice if go-l2tpd/kl2tpd supported this equipment/setup. Presumably, it simply needs to ignore the Set-Link-Info AVP message type in this case.


** Message: 06:40:03.504: strongSwan IPsec connection is up.
** Message: 06:40:03.506: xl2tpd started with pid 132243
xl2tpd[132243]: Not looking for kernel SAref support.
xl2tpd[132243]: Using l2tp kernel support.
xl2tpd[132243]: xl2tpd version xl2tpd-1.3.18 started on xxxxxxxx PID:132243
xl2tpd[132243]: Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.
xl2tpd[132243]: Forked by Scott Balmos and David Stipp, (C) 2001
xl2tpd[132243]: Inherited by Jeff McAdams, (C) 2002
xl2tpd[132243]: Forked again by Xelerance (www.xelerance.com) (C) 2006-2016
xl2tpd[132243]: Listening on IP address 0.0.0.0, port 33177
xl2tpd[132243]: get_call: allocating new tunnel for host xxx.xxx.xxx.xxx, port xxxx.
xl2tpd[132243]: Connecting to host xxx.xxx.xxx.xxx, port xxxxx
xl2tpd[132243]: control_finish: message type is (null)(0).  Tunnel is 0, call is 0.
xl2tpd[132243]: control_finish: sending SCCRQ
xl2tpd[132243]: message_type_avp: message type 2 (Start-Control-Connection-Reply)
xl2tpd[132243]: protocol_version_avp: peer is using version 1, revision 0.
xl2tpd[132243]: framing_caps_avp: supported peer frames: async sync
xl2tpd[132243]: bearer_caps_avp: supported peer bearers: analog digital
xl2tpd[132243]: firmware_rev_avp: peer reports firmware version 264 (0x0108)
xl2tpd[132243]: hostname_avp: peer reports hostname 'xxxxxxxx'
xl2tpd[132243]: vendor_avp: peer reports vendor 'Katalix Systems Ltd. Linux-4.4.177-meraki (x86_64)'
xl2tpd[132243]: assigned_tunnel_avp: using peer's tunnel 37327
xl2tpd[132243]: receive_window_size_avp: peer wants RWS of 10.  Will use flow control.
xl2tpd[132243]: control_finish: message type is Start-Control-Connection-Reply(2).  Tunnel is 37327, call is 0.
xl2tpd[132243]: control_finish: sending SCCCN
xl2tpd[132243]: Connection established to xxx.xxx.xxx.xxx, xxxxx.  Local: 51958, Remote: 37327 (ref=0/0).
xl2tpd[132243]: Calling on tunnel 51958
xl2tpd[132243]: control_finish: message type is (null)(0).  Tunnel is 37327, call is 0.
xl2tpd[132243]: control_finish: sending ICRQ
xl2tpd[132243]: message_type_avp: message type 11 (Incoming-Call-Reply)
xl2tpd[132243]: assigned_call_avp: using peer's call 19668
xl2tpd[132243]: control_finish: message type is Incoming-Call-Reply(11).  Tunnel is 37327, call is 19668.
xl2tpd[132243]: control_finish: Sending ICCN
xl2tpd[132243]: Call established with xxx.xxx.xxx.xxx, Local: 5484, Remote: 19668, Serial: 1 (ref=0/0)
xl2tpd[132243]: start_pppd: I'm running: 
xl2tpd[132243]: "/usr/sbin/pppd" 
xl2tpd[132243]: "plugin" 
xl2tpd[132243]: "pppol2tp.so" 
xl2tpd[132243]: "pppol2tp" 
xl2tpd[132243]: "7" 
xl2tpd[132243]: "passive" 
xl2tpd[132243]: "nodetach" 
xl2tpd[132243]: ":" 
xl2tpd[132243]: "debug" 
xl2tpd[132243]: "file" 
xl2tpd[132243]: "/run/nm-l2tp-57d65599-cccb-4d86-ba83-15914e8cf86f/ppp-options" 
xl2tpd[132243]: message_type_avp: message type 16 (Set-Link-Info)
xl2tpd[132243]: ignore_avp : Ignoring AVP
xl2tpd[132243]: control_finish: message type is Set-Link-Info(16).  Tunnel is 37327, call is 19668.

Make kl2tpd the default NetworkManager-l2tp L2TP daemon

I'm the current NetworkManager-l2tp maintainer and would like to make kl2tpd its default L2TP daemon and fallback to xl2tpd if it can't find it.

The source code changes would be based heavily on https://github.com/katalix/NetworkManager-l2tp . I would need to add some conditionals to the generated ipsec configuration tweak to also work with libreswan where left|rightprotoport haven't been deprecated.

Is there an option to not use an ephemeral port? I've had lots of users report issues with not being able to connect if an ephemeral port is used with xl2tp, e.g. issue nm-l2tp/NetworkManager-l2tp#38 . I guess I might need to make an ephemeral port GUI option.

Malformed header: length 17024 exceeds buffer bounds of 30

Hey, thanks for the great library! Since recently https://github.com/nm-l2tp/NetworkManager-l2tp allowed using kl2tpd for creating a connection to the server. With the error that I have, I would assume and that's what I've been told here https://bbs.archlinux.org/viewtopic.php?pid=1970197#p1970197 that this is probably a server error.

But I wonder if we somehow can handle this on a client-side?

Here are my logs for nm-l2tp-service --debug and if you need anything else or if somehow I can collaborate on this -- I would be really glad.

https://pastebin.com/KiE5ZN5H

How to Create an L2TP Client Connection with Credentials and Pre-Shared Key Using go-l2tp?

Hi,

I am trying to create an L2TP client connection using the go-l2tp package. My setup requires using both username/password credentials and a pre-shared key (PSK) for IPsec. I couldn't find clear documentation or examples on how to achieve this.

Could you provide guidance or an example of how to set up an L2TP client connection with:

  1. Username and password authentication.
  2. A pre-shared key (PSK) for IPsec.

Could you please provide the correct way to set up the PPP authentication and include the pre-shared key for IPsec?

Thank you!

README.md installation instructions

The README.md installation instructions say to do go get github.com/katalix/go-l2tp, but that results in the following error:

$ go get github.com/katalix/go-l2tp
package github.com/katalix/go-l2tp: no Go files in /home/foo/go/src/github.com/katalix/go-l2tp

I believe the instructions should actually be go get github.com/katalix/go-l2tp/...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.