katalix / go-l2tp

Go library for building L2TP applications on Linux systems
MIT License
45 stars 15 forks source link

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

Closed rashied-r closed 2 months ago

rashied-r commented 2 months ago

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!

tomparkin commented 2 months ago

Thanks for the suggestion!

Are you asking about using go-l2tp as a library in the context of another application? Or configuring the kl2tpd daemon?

rashied-r commented 2 months ago

I need to configuring the kl2tpd deamon

rashied-r commented 2 months ago

I can use it without PSK but authorization is necessary for me, where can I pass user and pass?

tomparkin commented 2 months ago

On the ipsec side, this is something which is managed separately to the L2TP protocol -- you could look into libreswan or strongswan for that.

The PPP connection is managed by kl2tpd using pppd, so any PPP-specifics can be configured in the pppd options file which is called out in the kl2tpd configuration:

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

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

For username and password the pppd command line arguments are user and password respectively.

rashied-r commented 2 months ago

Hi,

I'm encountering an error when trying to configure an L2TP session using pppd_args. The error message is:

failed to parse tunnels: tunnel t1: failed to process session: session s1: failed to process pppd_args: unrecognised parameter pppd_args

Here is my configuration file (my-l2tp-config.toml):

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

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

PPPD file is:

name "test"
password "test"
remotename l2tp
refuse-eap
require-chap
nobsdcomp
nodeflate
noauth
persist
usepeerdns

And here is my Go code:

package main

import (
    "fmt"
    "github.com/katalix/go-l2tp/config"
    "github.com/katalix/go-l2tp/l2tp"
    _ "github.com/katalix/go-l2tp/pppoe"
    "log"
    "os/exec"
)

func main() {
    fmt.Println("start L2TP")
    // 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.
    cfg, err := config.LoadFile("./my-l2tp-config.toml")
    if err != nil {
        fmt.Println("error is ", err.Error())
        log.Fatal(err)
    }

    // Creation of L2TP instances requires an L2TP context.
    // We're disabling logging and using the default Linux data plane.
    l2tpctx, err := l2tp.NewContext(l2tp.LinuxNetlinkDataPlane, nil)
    if err != nil {
        fmt.Println("error is ", err.Error())
        log.Fatal(err)
    }

    // Create tunnel and session instances based on the config
    for _, tcfg := range cfg.Tunnels {
        tunl, err := l2tpctx.NewStaticTunnel(tcfg.Name, tcfg.Config)
        if err != nil {
            fmt.Println("error is ", err.Error())
            log.Fatal(err)
        }
        for _, scfg := range tcfg.Sessions {
            session, err := tunl.NewSession(scfg.Name, scfg.Config)
            if err != nil {
                fmt.Println("error is ", err.Error())
                log.Fatal(err)
            }
            session.Close()
        }
    }
}

The version of package => github.com/katalix/go-l2tp v0.1.8

Could you please help me resolve this issue?

Thanks for your support

tomparkin commented 2 months ago

I think we've got slightly crossed wires here, apologies for any confusion!

go-l2tp effectively offers two options for bringing up L2TP connections:

  1. Use one of the commands included in the tree (e.g. kl2tpd). These are complete working tools which use the go-l2tp library under the hood. You don't need to write any Go code to use these tools, just configure them using .toml files, etc.
  2. Write your own application, using the go-l2tp library. This gives you more flexibility over what the application does and how it does it, but its a bit more involved. If you want to go down this route you'll need to read the API documentation and refer to the commands to see concrete examples of how to interface with the library.

I'm not entirely sure whether you're wanting option 1 or option 2 at the moment :-)

If you're looking to simply establish an L2TP connection, the easier approach is option 1.

You can use kl2tpd with configuration similar to what I pasted earlier. If you are building go-l2tp yourself using the Go toolchain, it should install kl2tpd to $HOME/go, e.g.

tom@jackdaw:~/src/go-l2tp$ go install ./...
tom@jackdaw:~/src/go-l2tp$ ~/go/bin/kl2tpd -h
Usage of /home/tom/go/bin/kl2tpd:
  -config string
        specify configuration file path (default "/etc/kl2tpd/kl2tpd.toml")
  -null
        toggle null data plane
  -verbose
        toggle verbose log output
tom@jackdaw:~/src/go-l2tp$ 

You can use the _pppdargs parameter in the .toml configuration file as you have shown in https://github.com/katalix/go-l2tp/issues/7#issuecomment-2177854716. Your pppd arguments look reasonable to me: they may need some tweaking depending upon the PPP configuration of your peer (you may want to add the debug argument to pppd to aid with debugging) but it looks good as a starting point at least.

If you want to go for option 2, writing your own Go application, pppd_args will indeed be rejected by the configuration parser. This is is because pppd_args is handled by kl2tpd command code (here https://github.com/katalix/go-l2tp/blob/master/cmd/kl2tpd/kl2tpd.go#L119) rather than go-l2tp/config. If you wanted to have your application spawn pppd you'd need some sort of similar handling.

I hope this helps clarify the different approaches. I suspect you want option 1 -- just make an L2TP connection with kl2tpd, in which case no Go code of your own is required.

However if not and you're working on your own Go application I'd be happy to give you some more pointers if the above isn't sufficient.

rashied-r commented 2 months ago

@tomparkin , This message is clear and concise, expressing your gratitude and your specific intention to use option 2.

Thanks again for your help. This information is very useful to me. Thank you so much.