Mikrotik Ubuntu L2TPv3 one server six mikrotik: Difference between revisions

From wiki karavi
Jump to navigation Jump to search
(Created page with "== L2TPv3 Tunnel: One Linux Server to Multiple MikroTik Routers == === Overview === This guide explains how to connect one Linux server to six MikroTik routers using static L2TPv3 tunnels via <code>ql2tpd</code>. {| class="wikitable" ! # !! MikroTik IP !! Server Tunnel IP !! Client Tunnel IP !! tid !! ptid !! sid !! psid |- | 0 (existing) || 78.157.42.222 || 10.0.0.1/30 || 10.0.0.2/30 || 100 || 200 || 1000 || 2000 |- | 1 || 85.57.4.221 || 10.0.1.1/30 || 10.0.1.2/30 ||...")
 
No edit summary
 
Line 1: Line 1:
== L2TPv3 Tunnel: One Linux Server to Multiple MikroTik Routers ==
== L2TPv3 Tunnel: One Linux Server to 6 MikroTik Routers (Template) ==


=== Overview ===
=== IP Address Plan ===
 
This guide explains how to connect one Linux server to six MikroTik routers using static L2TPv3 tunnels via <code>ql2tpd</code>.


{| class="wikitable"
{| class="wikitable"
! # !! MikroTik IP !! Server Tunnel IP !! Client Tunnel IP !! tid !! ptid !! sid !! psid
! # !! MikroTik IP !! Server Tunnel IP !! Client Tunnel IP !! tid !! ptid !! sid !! psid
|-
|-
| 0 (existing) || 78.157.42.222 || 10.0.0.1/30 || 10.0.0.2/30 || 100 || 200 || 1000 || 2000
| 1 || MIKROTIK_1_IP || 10.0.1.1/30 || 10.0.1.2/30 || 101 || 201 || 1001 || 2001
|-
|-
| 1 || 85.57.4.221 || 10.0.1.1/30 || 10.0.1.2/30 || 101 || 201 || 1001 || 2001
| 2 || MIKROTIK_2_IP || 10.0.2.1/30 || 10.0.2.2/30 || 102 || 202 || 1002 || 2002
|-
|-
| 2 || 85.57.4.222 || 10.0.2.1/30 || 10.0.2.2/30 || 102 || 202 || 1002 || 2002
| 3 || MIKROTIK_3_IP || 10.0.3.1/30 || 10.0.3.2/30 || 103 || 203 || 1003 || 2003
|-
|-
| 3 || 85.57.4.223 || 10.0.3.1/30 || 10.0.3.2/30 || 103 || 203 || 1003 || 2003
| 4 || MIKROTIK_4_IP || 10.0.4.1/30 || 10.0.4.2/30 || 104 || 204 || 1004 || 2004
|-
|-
| 4 || 85.57.4.224 || 10.0.4.1/30 || 10.0.4.2/30 || 104 || 204 || 1004 || 2004
| 5 || MIKROTIK_5_IP || 10.0.5.1/30 || 10.0.5.2/30 || 105 || 205 || 1005 || 2005
|-
|-
| 5 || 85.57.4.225 || 10.0.5.1/30 || 10.0.5.2/30 || 105 || 205 || 1005 || 2005
| 6 || MIKROTIK_6_IP || 10.0.6.1/30 || 10.0.6.2/30 || 106 || 206 || 1006 || 2006
|}
|}


---
---


=== Linux Server Setup (<code>157.90.26.4</code>) ===
=== Linux Server Setup ===
 
==== Step 1 — Install packages ====
 
<syntaxhighlight lang="bash">
apt install -y linux-modules-extra-$(uname -r) go-l2tp
</syntaxhighlight>


==== 1. Update ql2tpd configuration ====
==== Step 2 — Load kernel modules ====


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
modprobe l2tp_eth l2tp_ip l2tp_netlink
echo -e "l2tp_eth\nl2tp_ip\nl2tp_netlink" > /etc/modules-load.d/l2tp.conf
</syntaxhighlight>
==== Step 3 — Verify modules loaded ====
<syntaxhighlight lang="bash">
lsmod | grep l2tp
</syntaxhighlight>
Expected output:
<syntaxhighlight lang="text">
l2tp_eth
l2tp_ip
l2tp_netlink
l2tp_core
</syntaxhighlight>
==== Step 4 — Create ql2tpd configuration ====
<syntaxhighlight lang="bash">
mkdir -p /etc/ql2tpd
cat > /etc/ql2tpd/ql2tpd.toml << 'EOF'
cat > /etc/ql2tpd/ql2tpd.toml << 'EOF'
[tunnel.t1]
[tunnel.t1]
   version = "l2tpv3"
   version = "l2tpv3"
   encap = "ip"
   encap = "ip"
   local = "157.90.26.4:0"
   local = "SERVER_IP:0"
   peer = "78.157.42.222:0"
   peer = "MIKROTIK_1_IP:0"
  tid = 100
  ptid = 200
  [tunnel.t1.session.s1]
    pseudowire = "eth"
    sid = 1000
    psid = 2000
    interface_name = "l2tpeth0"
 
[tunnel.t2]
  version = "l2tpv3"
  encap = "ip"
  local = "157.90.26.4:0"
  peer = "85.57.4.221:0"
   tid = 101
   tid = 101
   ptid = 201
   ptid = 201
   [tunnel.t2.session.s1]
   [tunnel.t1.session.s1]
     pseudowire = "eth"
     pseudowire = "eth"
     sid = 1001
     sid = 1001
Line 55: Line 68:
     interface_name = "l2tpeth1"
     interface_name = "l2tpeth1"


[tunnel.t3]
[tunnel.t2]
   version = "l2tpv3"
   version = "l2tpv3"
   encap = "ip"
   encap = "ip"
   local = "157.90.26.4:0"
   local = "SERVER_IP:0"
   peer = "85.57.4.222:0"
   peer = "MIKROTIK_2_IP:0"
   tid = 102
   tid = 102
   ptid = 202
   ptid = 202
   [tunnel.t3.session.s1]
   [tunnel.t2.session.s1]
     pseudowire = "eth"
     pseudowire = "eth"
     sid = 1002
     sid = 1002
Line 68: Line 81:
     interface_name = "l2tpeth2"
     interface_name = "l2tpeth2"


[tunnel.t4]
[tunnel.t3]
   version = "l2tpv3"
   version = "l2tpv3"
   encap = "ip"
   encap = "ip"
   local = "157.90.26.4:0"
   local = "SERVER_IP:0"
   peer = "85.57.4.223:0"
   peer = "MIKROTIK_3_IP:0"
   tid = 103
   tid = 103
   ptid = 203
   ptid = 203
   [tunnel.t4.session.s1]
   [tunnel.t3.session.s1]
     pseudowire = "eth"
     pseudowire = "eth"
     sid = 1003
     sid = 1003
Line 81: Line 94:
     interface_name = "l2tpeth3"
     interface_name = "l2tpeth3"


[tunnel.t5]
[tunnel.t4]
   version = "l2tpv3"
   version = "l2tpv3"
   encap = "ip"
   encap = "ip"
   local = "157.90.26.4:0"
   local = "SERVER_IP:0"
   peer = "85.57.4.224:0"
   peer = "MIKROTIK_4_IP:0"
   tid = 104
   tid = 104
   ptid = 204
   ptid = 204
   [tunnel.t5.session.s1]
   [tunnel.t4.session.s1]
     pseudowire = "eth"
     pseudowire = "eth"
     sid = 1004
     sid = 1004
Line 94: Line 107:
     interface_name = "l2tpeth4"
     interface_name = "l2tpeth4"


[tunnel.t6]
[tunnel.t5]
   version = "l2tpv3"
   version = "l2tpv3"
   encap = "ip"
   encap = "ip"
   local = "157.90.26.4:0"
   local = "SERVER_IP:0"
   peer = "85.57.4.225:0"
   peer = "MIKROTIK_5_IP:0"
   tid = 105
   tid = 105
   ptid = 205
   ptid = 205
   [tunnel.t6.session.s1]
   [tunnel.t5.session.s1]
     pseudowire = "eth"
     pseudowire = "eth"
     sid = 1005
     sid = 1005
     psid = 2005
     psid = 2005
     interface_name = "l2tpeth5"
     interface_name = "l2tpeth5"
[tunnel.t6]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_6_IP:0"
  tid = 106
  ptid = 206
  [tunnel.t6.session.s1]
    pseudowire = "eth"
    sid = 1006
    psid = 2006
    interface_name = "l2tpeth6"
EOF
EOF
</syntaxhighlight>
</syntaxhighlight>


==== 2. Restart service ====
==== Step 5 — Create systemd service ====


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
systemctl restart ql2tpd
cat > /etc/systemd/system/ql2tpd.service << 'EOF'
sleep 2
[Unit]
Description=L2TPv3 Static Tunnel
After=network.target
 
[Service]
ExecStart=/usr/sbin/ql2tpd -config /etc/ql2tpd/ql2tpd.toml
Restart=always
 
[Install]
WantedBy=multi-user.target
EOF
 
systemctl daemon-reload
systemctl enable --now ql2tpd
</syntaxhighlight>
</syntaxhighlight>


==== 3. Assign tunnel IPs ====
==== Step 6 — Assign tunnel IPs ====


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sleep 2
ip addr add 10.0.1.1/30 dev l2tpeth1 && ip link set l2tpeth1 up
ip addr add 10.0.1.1/30 dev l2tpeth1 && ip link set l2tpeth1 up
ip addr add 10.0.2.1/30 dev l2tpeth2 && ip link set l2tpeth2 up
ip addr add 10.0.2.1/30 dev l2tpeth2 && ip link set l2tpeth2 up
Line 124: Line 164:
ip addr add 10.0.4.1/30 dev l2tpeth4 && ip link set l2tpeth4 up
ip addr add 10.0.4.1/30 dev l2tpeth4 && ip link set l2tpeth4 up
ip addr add 10.0.5.1/30 dev l2tpeth5 && ip link set l2tpeth5 up
ip addr add 10.0.5.1/30 dev l2tpeth5 && ip link set l2tpeth5 up
ip addr add 10.0.6.1/30 dev l2tpeth6 && ip link set l2tpeth6 up
</syntaxhighlight>
</syntaxhighlight>


==== 4. Persist IPs after reboot ====
==== Step 7 — Persist IPs after reboot ====


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 132: Line 173:
#!/bin/bash
#!/bin/bash
sleep 3
sleep 3
ip addr add 10.0.0.1/30 dev l2tpeth0 2>/dev/null && ip link set l2tpeth0 up 2>/dev/null
ip addr add 10.0.1.1/30 dev l2tpeth1 2>/dev/null && ip link set l2tpeth1 up 2>/dev/null
ip addr add 10.0.1.1/30 dev l2tpeth1 2>/dev/null && ip link set l2tpeth1 up 2>/dev/null
ip addr add 10.0.2.1/30 dev l2tpeth2 2>/dev/null && ip link set l2tpeth2 up 2>/dev/null
ip addr add 10.0.2.1/30 dev l2tpeth2 2>/dev/null && ip link set l2tpeth2 up 2>/dev/null
Line 138: Line 178:
ip addr add 10.0.4.1/30 dev l2tpeth4 2>/dev/null && ip link set l2tpeth4 up 2>/dev/null
ip addr add 10.0.4.1/30 dev l2tpeth4 2>/dev/null && ip link set l2tpeth4 up 2>/dev/null
ip addr add 10.0.5.1/30 dev l2tpeth5 2>/dev/null && ip link set l2tpeth5 up 2>/dev/null
ip addr add 10.0.5.1/30 dev l2tpeth5 2>/dev/null && ip link set l2tpeth5 up 2>/dev/null
ip addr add 10.0.6.1/30 dev l2tpeth6 2>/dev/null && ip link set l2tpeth6 up 2>/dev/null
EOF
EOF
chmod +x /etc/networkd-dispatcher/routable.d/l2tp-ip.sh
chmod +x /etc/networkd-dispatcher/routable.d/l2tp-ip.sh
</syntaxhighlight>
==== Step 8 — Verify interfaces ====
<syntaxhighlight lang="bash">
ip addr show | grep l2tpeth
</syntaxhighlight>
</syntaxhighlight>


---
---


=== MikroTik 1 — <code>85.57.4.221</code> ===
=== MikroTik Setup (Run on each router) ===
 
Replace the placeholder values from the table above for each MikroTik.
 
==== MikroTik 1 — <code>MIKROTIK_1_IP</code> ====


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=157.90.26.4 local-address=85.57.4.221 local-tunnel-id=201 remote-tunnel-id=101 local-session-id=2001 remote-session-id=1001 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_1_IP local-tunnel-id=201 remote-tunnel-id=101 local-session-id=2001 remote-session-id=1001 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.1.2/30 interface=l2tpv3
/ip address add address=10.0.1.2/30 interface=l2tpv3
</syntaxhighlight>
</syntaxhighlight>


---
==== MikroTik 2 — <code>MIKROTIK_2_IP</code> ====
 
=== MikroTik 2 — <code>85.57.4.222</code> ===


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=157.90.26.4 local-address=85.57.4.222 local-tunnel-id=202 remote-tunnel-id=102 local-session-id=2002 remote-session-id=1002 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_2_IP local-tunnel-id=202 remote-tunnel-id=102 local-session-id=2002 remote-session-id=1002 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.2.2/30 interface=l2tpv3
/ip address add address=10.0.2.2/30 interface=l2tpv3
</syntaxhighlight>
</syntaxhighlight>


---
==== MikroTik 3 — <code>MIKROTIK_3_IP</code> ====
 
=== MikroTik 3 — <code>85.57.4.223</code> ===


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=157.90.26.4 local-address=85.57.4.223 local-tunnel-id=203 remote-tunnel-id=103 local-session-id=2003 remote-session-id=1003 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_3_IP local-tunnel-id=203 remote-tunnel-id=103 local-session-id=2003 remote-session-id=1003 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.3.2/30 interface=l2tpv3
/ip address add address=10.0.3.2/30 interface=l2tpv3
</syntaxhighlight>
</syntaxhighlight>


---
==== MikroTik 4 — <code>MIKROTIK_4_IP</code> ====
 
=== MikroTik 4 — <code>85.57.4.224</code> ===


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=157.90.26.4 local-address=85.57.4.224 local-tunnel-id=204 remote-tunnel-id=104 local-session-id=2004 remote-session-id=1004 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_4_IP local-tunnel-id=204 remote-tunnel-id=104 local-session-id=2004 remote-session-id=1004 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.4.2/30 interface=l2tpv3
/ip address add address=10.0.4.2/30 interface=l2tpv3
</syntaxhighlight>
</syntaxhighlight>


---
==== MikroTik 5 — <code>MIKROTIK_5_IP</code> ====
 
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_5_IP local-tunnel-id=205 remote-tunnel-id=105 local-session-id=2005 remote-session-id=1005 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.5.2/30 interface=l2tpv3
</syntaxhighlight>


=== MikroTik 5 — <code>85.57.4.225</code> ===
==== MikroTik 6 — <code>MIKROTIK_6_IP</code> ====


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/interface l2tp-ether add name=l2tpv3 connect-to=157.90.26.4 local-address=85.57.4.225 local-tunnel-id=205 remote-tunnel-id=105 local-session-id=2005 remote-session-id=1005 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_6_IP local-tunnel-id=206 remote-tunnel-id=106 local-session-id=2006 remote-session-id=1006 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.5.2/30 interface=l2tpv3
/ip address add address=10.0.6.2/30 interface=l2tpv3
</syntaxhighlight>
</syntaxhighlight>


Line 191: Line 241:
=== Verification ===
=== Verification ===


'''From Linux server:'''
'''From Linux server — ping all clients:'''


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 199: Line 249:
ping 10.0.4.2 -c 2
ping 10.0.4.2 -c 2
ping 10.0.5.2 -c 2
ping 10.0.5.2 -c 2
ping 10.0.6.2 -c 2
</syntaxhighlight>
</syntaxhighlight>


'''From each MikroTik:'''
'''From each MikroTik — ping server:'''


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/ping 10.0.X.1 count=4
/ping 10.0.X.1 count=4
</syntaxhighlight>
---
=== Cleanup ===
'''Linux server:'''
<syntaxhighlight lang="bash">
systemctl stop ql2tpd
systemctl disable ql2tpd
rm /etc/systemd/system/ql2tpd.service
rm -rf /etc/ql2tpd
rm -f /etc/networkd-dispatcher/routable.d/l2tp-ip.sh
rm -f /etc/modules-load.d/l2tp.conf
systemctl daemon-reload
for i in 1 2 3 4 5 6; do ip link del l2tpeth$i 2>/dev/null; done
modprobe -r l2tp_eth l2tp_ip l2tp_netlink 2>/dev/null
apt remove -y go-l2tp
</syntaxhighlight>
'''Each MikroTik:'''
<syntaxhighlight lang="text">
/ip address remove [find interface=l2tpv3]
/interface l2tp-ether remove l2tpv3
</syntaxhighlight>
</syntaxhighlight>


Line 214: Line 291:
! Symptom !! Cause !! Fix
! Symptom !! Cause !! Fix
|-
|-
| Interface not created || <code>ql2tpd</code> not restarted || <code>systemctl restart ql2tpd</code>
| <code>Module l2tp_eth not found</code> || Missing extra modules || <code>apt install linux-modules-extra-$(uname -r)</code>
|-
| Interface not created || <code>ql2tpd</code> not running || <code>systemctl restart ql2tpd && sleep 2</code>
|-
|-
| Link stays DOWN || MikroTik sending control messages || Verify <code>unmanaged-mode=yes</code>
| Link stays DOWN || MikroTik sending control messages || Verify <code>unmanaged-mode=yes</code> is set
|-
|-
| No packets arriving || Firewall blocking proto 115 || Allow IP protocol 115 on both sides
| No packets arriving || Firewall blocking proto 115 || Allow IP protocol 115 on both sides
|-
|-
| IP lost after reboot || persistence script not updated || Re-run step 4
| IP lost after reboot || Persistence script missing || Re-run Step 7
|-
|-
| Wrong tunnel match || Duplicate tid/ptid/sid/psid || Verify IDs are unique per tunnel
| Wrong tunnel match || Duplicate or swapped IDs || Verify tid/ptid/sid/psid per table above
|}
|}


Line 229: Line 308:
=== Notes ===
=== Notes ===


* Replace all <code>SERVER_IP</code> and <code>MIKROTIK_X_IP</code> placeholders with real IP addresses before running.
* Each tunnel must have unique <code>tid</code>, <code>ptid</code>, <code>sid</code>, and <code>psid</code> values.
* Each tunnel must have unique <code>tid</code>, <code>ptid</code>, <code>sid</code>, and <code>psid</code> values.
* Each MikroTik's <code>local-tunnel-id</code> must match the server's <code>ptid</code> for that tunnel, and vice versa.
* MikroTik <code>local-tunnel-id</code> = server <code>ptid</code> and <code>remote-tunnel-id</code> = server <code>tid</code>.
* All tunnels share the same Linux server public IP (<code>157.90.26.4</code>) — this is supported since each tunnel is differentiated by its tunnel ID.
* <code>unmanaged-mode=yes</code> is mandatory on MikroTik — without it the control protocol runs and the tunnel will not connect to <code>ql2tpd</code>.
* No encryption is applied by default. For production use, consider wrapping tunnels with IPsec.
* Tested on Ubuntu 24.04 (kernel 6.8) and RouterOS 7.20.
* No encryption by default — wrap with IPsec for production use.


---
---

Latest revision as of 19:48, 21 June 2026

L2TPv3 Tunnel: One Linux Server to 6 MikroTik Routers (Template)

IP Address Plan

# MikroTik IP Server Tunnel IP Client Tunnel IP tid ptid sid psid
1 MIKROTIK_1_IP 10.0.1.1/30 10.0.1.2/30 101 201 1001 2001
2 MIKROTIK_2_IP 10.0.2.1/30 10.0.2.2/30 102 202 1002 2002
3 MIKROTIK_3_IP 10.0.3.1/30 10.0.3.2/30 103 203 1003 2003
4 MIKROTIK_4_IP 10.0.4.1/30 10.0.4.2/30 104 204 1004 2004
5 MIKROTIK_5_IP 10.0.5.1/30 10.0.5.2/30 105 205 1005 2005
6 MIKROTIK_6_IP 10.0.6.1/30 10.0.6.2/30 106 206 1006 2006

---

Linux Server Setup

Step 1 — Install packages

apt install -y linux-modules-extra-$(uname -r) go-l2tp

Step 2 — Load kernel modules

modprobe l2tp_eth l2tp_ip l2tp_netlink
echo -e "l2tp_eth\nl2tp_ip\nl2tp_netlink" > /etc/modules-load.d/l2tp.conf

Step 3 — Verify modules loaded

lsmod | grep l2tp

Expected output:

l2tp_eth
l2tp_ip
l2tp_netlink
l2tp_core

Step 4 — Create ql2tpd configuration

mkdir -p /etc/ql2tpd
cat > /etc/ql2tpd/ql2tpd.toml << 'EOF'
[tunnel.t1]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_1_IP:0"
  tid = 101
  ptid = 201
  [tunnel.t1.session.s1]
    pseudowire = "eth"
    sid = 1001
    psid = 2001
    interface_name = "l2tpeth1"

[tunnel.t2]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_2_IP:0"
  tid = 102
  ptid = 202
  [tunnel.t2.session.s1]
    pseudowire = "eth"
    sid = 1002
    psid = 2002
    interface_name = "l2tpeth2"

[tunnel.t3]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_3_IP:0"
  tid = 103
  ptid = 203
  [tunnel.t3.session.s1]
    pseudowire = "eth"
    sid = 1003
    psid = 2003
    interface_name = "l2tpeth3"

[tunnel.t4]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_4_IP:0"
  tid = 104
  ptid = 204
  [tunnel.t4.session.s1]
    pseudowire = "eth"
    sid = 1004
    psid = 2004
    interface_name = "l2tpeth4"

[tunnel.t5]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_5_IP:0"
  tid = 105
  ptid = 205
  [tunnel.t5.session.s1]
    pseudowire = "eth"
    sid = 1005
    psid = 2005
    interface_name = "l2tpeth5"

[tunnel.t6]
  version = "l2tpv3"
  encap = "ip"
  local = "SERVER_IP:0"
  peer = "MIKROTIK_6_IP:0"
  tid = 106
  ptid = 206
  [tunnel.t6.session.s1]
    pseudowire = "eth"
    sid = 1006
    psid = 2006
    interface_name = "l2tpeth6"
EOF

Step 5 — Create systemd service

cat > /etc/systemd/system/ql2tpd.service << 'EOF'
[Unit]
Description=L2TPv3 Static Tunnel
After=network.target

[Service]
ExecStart=/usr/sbin/ql2tpd -config /etc/ql2tpd/ql2tpd.toml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now ql2tpd

Step 6 — Assign tunnel IPs

sleep 2
ip addr add 10.0.1.1/30 dev l2tpeth1 && ip link set l2tpeth1 up
ip addr add 10.0.2.1/30 dev l2tpeth2 && ip link set l2tpeth2 up
ip addr add 10.0.3.1/30 dev l2tpeth3 && ip link set l2tpeth3 up
ip addr add 10.0.4.1/30 dev l2tpeth4 && ip link set l2tpeth4 up
ip addr add 10.0.5.1/30 dev l2tpeth5 && ip link set l2tpeth5 up
ip addr add 10.0.6.1/30 dev l2tpeth6 && ip link set l2tpeth6 up

Step 7 — Persist IPs after reboot

cat > /etc/networkd-dispatcher/routable.d/l2tp-ip.sh << 'EOF'
#!/bin/bash
sleep 3
ip addr add 10.0.1.1/30 dev l2tpeth1 2>/dev/null && ip link set l2tpeth1 up 2>/dev/null
ip addr add 10.0.2.1/30 dev l2tpeth2 2>/dev/null && ip link set l2tpeth2 up 2>/dev/null
ip addr add 10.0.3.1/30 dev l2tpeth3 2>/dev/null && ip link set l2tpeth3 up 2>/dev/null
ip addr add 10.0.4.1/30 dev l2tpeth4 2>/dev/null && ip link set l2tpeth4 up 2>/dev/null
ip addr add 10.0.5.1/30 dev l2tpeth5 2>/dev/null && ip link set l2tpeth5 up 2>/dev/null
ip addr add 10.0.6.1/30 dev l2tpeth6 2>/dev/null && ip link set l2tpeth6 up 2>/dev/null
EOF
chmod +x /etc/networkd-dispatcher/routable.d/l2tp-ip.sh

Step 8 — Verify interfaces

ip addr show | grep l2tpeth

---

MikroTik Setup (Run on each router)

Replace the placeholder values from the table above for each MikroTik.

MikroTik 1 — MIKROTIK_1_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_1_IP local-tunnel-id=201 remote-tunnel-id=101 local-session-id=2001 remote-session-id=1001 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.1.2/30 interface=l2tpv3

MikroTik 2 — MIKROTIK_2_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_2_IP local-tunnel-id=202 remote-tunnel-id=102 local-session-id=2002 remote-session-id=1002 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.2.2/30 interface=l2tpv3

MikroTik 3 — MIKROTIK_3_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_3_IP local-tunnel-id=203 remote-tunnel-id=103 local-session-id=2003 remote-session-id=1003 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.3.2/30 interface=l2tpv3

MikroTik 4 — MIKROTIK_4_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_4_IP local-tunnel-id=204 remote-tunnel-id=104 local-session-id=2004 remote-session-id=1004 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.4.2/30 interface=l2tpv3

MikroTik 5 — MIKROTIK_5_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_5_IP local-tunnel-id=205 remote-tunnel-id=105 local-session-id=2005 remote-session-id=1005 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.5.2/30 interface=l2tpv3

MikroTik 6 — MIKROTIK_6_IP

/interface l2tp-ether add name=l2tpv3 connect-to=SERVER_IP local-address=MIKROTIK_6_IP local-tunnel-id=206 remote-tunnel-id=106 local-session-id=2006 remote-session-id=1006 l2tp-proto-version=l2tpv3-ip unmanaged-mode=yes disabled=no
/ip address add address=10.0.6.2/30 interface=l2tpv3

---

Verification

From Linux server — ping all clients:

ping 10.0.1.2 -c 2
ping 10.0.2.2 -c 2
ping 10.0.3.2 -c 2
ping 10.0.4.2 -c 2
ping 10.0.5.2 -c 2
ping 10.0.6.2 -c 2

From each MikroTik — ping server:

/ping 10.0.X.1 count=4

---

Cleanup

Linux server:

systemctl stop ql2tpd
systemctl disable ql2tpd
rm /etc/systemd/system/ql2tpd.service
rm -rf /etc/ql2tpd
rm -f /etc/networkd-dispatcher/routable.d/l2tp-ip.sh
rm -f /etc/modules-load.d/l2tp.conf
systemctl daemon-reload
for i in 1 2 3 4 5 6; do ip link del l2tpeth$i 2>/dev/null; done
modprobe -r l2tp_eth l2tp_ip l2tp_netlink 2>/dev/null
apt remove -y go-l2tp

Each MikroTik:

/ip address remove [find interface=l2tpv3]
/interface l2tp-ether remove l2tpv3

---

Troubleshooting

Symptom Cause Fix
Module l2tp_eth not found Missing extra modules apt install linux-modules-extra-$(uname -r)
Interface not created ql2tpd not running systemctl restart ql2tpd && sleep 2
Link stays DOWN MikroTik sending control messages Verify unmanaged-mode=yes is set
No packets arriving Firewall blocking proto 115 Allow IP protocol 115 on both sides
IP lost after reboot Persistence script missing Re-run Step 7
Wrong tunnel match Duplicate or swapped IDs Verify tid/ptid/sid/psid per table above

---

Notes

  • Replace all SERVER_IP and MIKROTIK_X_IP placeholders with real IP addresses before running.
  • Each tunnel must have unique tid, ptid, sid, and psid values.
  • MikroTik local-tunnel-id = server ptid and remote-tunnel-id = server tid.
  • unmanaged-mode=yes is mandatory on MikroTik — without it the control protocol runs and the tunnel will not connect to ql2tpd.
  • Tested on Ubuntu 24.04 (kernel 6.8) and RouterOS 7.20.
  • No encryption by default — wrap with IPsec for production use.

---

References