IPsec tunnel between Ubuntu 20.04 and Mikrotik router using strongSwan

Here is how to establish an IPsec tunnel between an Ubuntu 20.04 host and a Mikrotik router using IKEv2.

The 2 endpoints of the tunnel are:

  • ubuntu.xentoo.info : the Ubuntu server. This server has a local private subnet and a fixed public IPv4 address . The hostname ubuntu.xentoo.info resolves to the public IP address.
  • mikrotik.xentoo.info : the Mikrotik router. This router has a local private subnet and a dynamic public IPv4 address.

I will use fqdn identifiers, pre-shared-key and both IKE and ESP will have the same parameters:

  • encryption: AES256
  • integrity: SHA256
  • Diffie-Hellman group: ECP384

Let’s first configure the Mikrotik router. Go straight into the configuration of IPSEC tunnels:

/ip ipsec profile
add dh-group=ecp384 dpd-interval=10s enc-algorithm=aes-256 hash-algorithm=sha256 name=ubuntu.xentoo.info <
/ip ipsec peer
add address=ubuntu.xentoo.info exchange-mode=ike2 name=ubuntu.xentoo.info profile=ubuntu.xentoo.info
/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-256-cbc,aes-256-ctr name=ubuntu.xentoo.info pfs-group=ecp384
/ip ipsec identity
add my-id=fqdn:mikrotik.xentoo.info peer=ubuntu.xentoo.info remote-id=ubuntu.xentoo.info secret=mysecretkey
/ip ipsec policy
add dst-address= peer=ubuntu.xentoo.info proposal=ubuntu.xentoo.info sa-dst-address= \
    sa-src-address= src-address= tunnel=yes

On Ubuntu side, first install the package:

apt-get install strongswan

The tunnels are configured in /etc/ipsec.conf . There are 2 members in a connection: a left one and a right one. I always use the left one for the local host and the right one for the remote host. I name the connection using the remote host name. Since the Mikrotik router has a dynamic public IP address, its IP address is configured with %any.

The configuration for this tunnel is the following:

conn mikrotik.xentoo.info

The secret keys are stored in /etc/ipsec.secrets . Each line is a different secret. The syntax I use is leftid rightid : PSK "psk" .

fqdn:ubuntu.xentoo.info fqdn:mikrotik.xentoo.info : PSK "mysecretkey"

Restart IPSEC service to apply the changes:

systemctl restart ipsec

After you restart the service, you should see the following in /var/log/syslog:

Mar  6 11:35:51 ubuntu charon: 00[CFG] loading secrets from '/etc/ipsec.secrets'
Mar  6 11:35:51 ubuntu charon: 00[CFG]   loaded IKE secret for fqdn:ubuntu.xentoo.info fqdn:mikrotik.xentoo.info
Mar  6 11:35:51 ubuntu charon: 05[CFG] added configuration 'mikrotik.xentoo.info'
Mar  6 11:35:57 ubuntu charon: 09[NET] received packet: from[4500] to[4500] (208 bytes)
Mar  6 11:35:57 ubuntu charon: 09[ENC] parsed IKE_SA_INIT request 0 [ No KE SA ]
Mar  6 11:35:57 ubuntu charon: 09[IKE] is initiating an IKE_SA
Mar  6 11:35:57 ubuntu charon: 09[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_384
Mar  6 11:35:57 ubuntu charon: 09[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(CHDLESS_SUP) N(MULT_AUTH) ]
Mar  6 11:35:57 ubuntu charon: 09[NET] sending packet: from[4500] to[4500] (232 bytes)
Mar  6 11:35:57 ubuntu charon: 10[NET] received packet: from[4500] to[4500] (448 bytes)
Mar  6 11:35:57 ubuntu charon: 10[ENC] parsed IKE_AUTH request 1 [ IDi AUTH IDr N(INIT_CONTACT) SA TSi TSr ]
Mar  6 11:35:57 ubuntu charon: 10[CFG] looking for peer configs matching[ubuntu.xentoo.info]...[mikrotik.xentoo.info]
Mar  6 11:35:57 ubuntu charon: 10[CFG] selected peer config 'mikrotik.xentoo.info'
Mar  6 11:35:57 ubuntu charon: 10[IKE] authentication of 'mikrotik.xentoo.info' with pre-shared key successful
Mar  6 11:35:57 ubuntu charon: 10[IKE] authentication of 'ubuntu.xentoo.info' (myself) with pre-shared key
Mar  6 11:35:57 ubuntu charon: 10[IKE] IKE_SA mikrotik.xentoo.info[2] established between[ubuntu.xentoo.info]...[mikrotik.xentoo.info]

You can see the secret was loaded correctly, both endpoints were detected correctly. Then the configuration for tunnel mikrotik.xentoo.info was loaded. When a first packet was received from the Mikrotik router, the correct proposal was chosen, the the authentication using pre-shared-key succeeded and the tunnel was established.

Posted in Computer, Linux, Mikrotik, Networking | Leave a comment

Install Firely III on Ubuntu 19.04

“Firefly III” is a (self-hosted) manager for your personal finances. You can find more about it on the following sites:

Install prerequisites

Let’s first install the requirements to run Firefly. Firefly documentation says it runs on PHP 7.2 but that’s wrong, it needs >=7.3 . Unfortunately, Ubuntu 19.04 comes with PHP 7.2 by default, so we need to use a PPA to have a more recent version.

ondrej/php PPA has version 7.4 at this time, that will be perfect.

Firefly needs a database, I have chosen to go with PostgreSQL.

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.4 php7.4-bcmath php7.4-curl php7.4-gd php7.4-intl php7.4-ldap php7.4-mbstring php7.4-xml php7.4-zip unzip postgresql php7.4-pgsql
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

Install Firefly

To retrieve Firefly, it’s quite simple. Go to version.firefly-iii.org/ , choose the version you want and mention it in the command below. For me, I have chosen the latest stable version at this time: 4.8.2 .

$ composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii 4.8.2
$ sudo chown -R www-data:www-data firefly-iii
$ sudo chmod -R 775 firefly-iii/storage/
$ mv firefly-iii /var/www

Configure PostgreSQL

su - postgres
postgres=# create database firefly;
postgres=# create role firefly with login encrypted password 'secret_firefly_password';
postgres=# exit

You can test the connection is working using the following command. It will prompt for your password.

psql -U firefly -W firefly

If all goes well, you should obtain the following prompt:


Configure Firefly

Edit the file .env at the root of firefly-iii directory. You may want to change the following variables:

SITE_OWNER=your email address
TZ=your timezone

You need to use a database for Firefly. I have chosen to use PostgreSQL.

# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq

If you want Firefly to send emails, you need to change the following variables:

# If you want Firefly III to mail you, update these settings
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
MAIL_HOST=your mail server here

Once you are done, you can initialize the database:

php artisan migrate:refresh --seed
php artisan firefly-iii:upgrade-database
php artisan passport:install

Configure Apache

I have chosen to stick with Apache2 to run Firefly, so let’s configure it.

By default, Apache2 serves files under /var/www/html but we have moved firefly-iii directory under /var/www . Moreover, we must only present public/ directory .

In addition, Firefly uses .htaccess file inside public/ directory, but default configuration of Apache2 denies it. So we need to allow this.

Let’s edit file /etc/apache2/sites-available/000-default.conf to configure all of the above. Put the following code inside block:

Alias /firefly-iii /var/www/firefly-iii-4.8.2/public
<Directory /var/www/firefly-iii/public>
    AllowOverride FileInfo Options=Indexes,MultiViews

In addition, Firefly rewrites URL so we need to enable Apache2 module.

sudo a2enmod rewrite

Then restart Apache2:

sudo systemctl restart apache2
Posted in Computer, Linux | Leave a comment

Using a Mikrotik router with Tango Fiber (Luxembourg)

Hi guys,

I moved to Luxembourg and I have opted for Tango Fiber. Their router is a Fritz!box which I do not like at all. I have a spare Mikrotik router, so here is how to configure.

Tango Fiber uses PPPoE over VLAN 35, MTU is 1480. You need to ask the PPP credentials via a contact form on the website, they will answer within a few days.

I have decided to use ether1 to connect the Fiber and create a VLAN interface named ether1.35 on it.

/interface vlan
add interface=ether1 name=ether1.35 vlan-id=35
/interface pppoe-client
add add-default-route=yes default-route-distance=0 disabled=no interface=ether1.35 max-mtu=1480 \
    name=TangoFibre password=xxx use-peer-dns=yes user=xxx@tango

Do not forget to adapt your NAT rules to allow exit through this interface.

Posted in Computer, Mikrotik, Networking | Tagged , , | 3 Comments

Compile pjsip with pjsua on Ubuntu 16.04

As a personal note to myself :-)

apt-get install make gcc pkg-config libasound2-dev
wget http://www.pjsip.org/release/2.6/pjproject-2.6.tar.bz2
tar -xjf pjproject-2.6.tar.bz2
cd pjproject
./configure && make dep && make
sudo make install
sudo cp pjsip-apps/bin/pjsua-x86_64-unknown-linux-gnu /usr/local/bin/pjsua

That’s it!

Posted in Computer, Linux, VoIP | Leave a comment

Extend snmpd to add detailed CPU statistics, per CPU (again)

For easier use with Cacti, it is easier to group statistics per type instead of per CPU. So you would have a parent OID for CPU time spent by user with many values (one per CPU).

Put the following in /etc/snmp/percpudetail:

case "$1" in
    grep ^cpu /proc/stat | awk '{print 2}' ;;
    grep ^cpu /proc/stat | awk '{print 3}' ;;
    grep ^cpu /proc/stat | awk '{print 4}' ;;
    grep ^cpu /proc/stat | awk '{print 5}' ;;
    grep ^cpu /proc/stat | awk '{print 6}' ;;
    grep ^cpu /proc/stat | awk '{print 7}' ;;
    grep ^cpu /proc/stat | awk '{print 8}' ;;

Make it executable:

chmod +x /etc/snmp/percpudetail

Then in your /etc/snmp/snmpd.conf file, put the following lines:

extend cpuuser /etc/snmp/percpudetail user
extend cpunice /etc/snmp/percpudetail nice
extend cpusystem /etc/snmp/percpudetail system
extend cpuidle /etc/snmp/percpudetail idle
extend cpuiowait /etc/snmp/percpudetail iowait
extend cpuirq /etc/snmp/percpudetail irq
extend cpusoftirq /etc/snmp/percpudetail softirq

Restart snmpd and you can poll those new OIDs.

Posted in Computer, Linux, Networking | Leave a comment

Extend snmpd to add detailed CPU statistics, per cpu

I needed to export detailed CPU statistics from Linux servers using SNMP. While UCD-SNMP-MIB export some detailed stats, it only does it for the whole system. I may have missed something easier though :-)

So here is a BASH script, put it in /etc/snmp/percpustats:

/bin/grep "^$1 " /proc/stat | sed -e 's/^cpu[0-9]* *//' | tr ' ' '\n'

Make it executable:

chmod +x /etc/snmp/percpustats

This simple script takes a single argument, which is the cpu id you want to look at. By “cpu id”, I mean the first word of cpu* lines in /proc/stat . So cpu, cpu0, cpu1, etc. Here is a sample content of my /proc/stat file:

# cat /proc/stat
cpu  190769457 225375 18212019 746796473 443933 1361 1240780 0 346283 0
cpu0 98979159 94876 9197600 368299173 282702 1361 1240721 0 164117 0
cpu1 91790298 130498 9014419 378497299 161231 0 58 0 182166 0

In your snmpd config file, you will need to add one extra config line per CPU you want to look at. Let’s say you have 3 CPU in your computer, you would need to add the following lines to get stats for the system in general (cpu) and details for each cpu (cpu0,cpu1,cpu2):

extend cpu /etc/snmp/percpustats cpu
extend cpu0 /etc/snmp/percpustats cpu0
extend cpu1 /etc/snmp/percpustats cpu1
extend cpu2 /etc/snmp/percpustats cpu2

Restart snmpd .

You can check the output using snmpwalk:

snmpwalk -v 2c -c yourcommunity yourip NET-SNMP-EXTEND-MIB::nsExtendObjects

You should get something like this:

NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".1 = STRING: 52183124
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".2 = STRING: 2487538
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".3 = STRING: 64930047
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".4 = STRING: 13880645861
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".5 = STRING: 1503768
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".6 = STRING: 5350929
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".7 = STRING: 57971310
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu".8 = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".1 = STRING: 3557627
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".2 = STRING: 42604
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".3 = STRING: 4803282
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".4 = STRING: 1749637588
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".5 = STRING: 27945
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".6 = STRING: 1
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".7 = STRING: 65021
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu0".8 = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".1 = STRING: 5861096
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".2 = STRING: 472784
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".3 = STRING: 6472817
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".4 = STRING: 1733427227
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".5 = STRING: 426662
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".6 = STRING: 918093
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".7 = STRING: 10555401
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cpu1".8 = STRING: 0

Now you can use these in your favourite monitoring/graph tools.

Posted in Computer, Linux, Networking | Leave a comment

Unetlab: create a QEMU image

So you have your Unified Networking Lab (UNL) server running and you want to use arbitrary QEMU images with it. Here is how to create one.

All UNL data is stored under /opt/unetlab , images are stored under /opt/unetlab/addons and QEMU images are a folder deeper under /opt/unetlab/addons/qemu .

UNL expects to find images within directories named according to some scheme. The directory names must start with some keywords followed by anything you want. For Linux images, you need to name the directory linux-something, e.g. linux-ubuntu-14.04.5-amd64. You can find the list of supported image “types” in /opt/unetlab/html/templates. The names of the files are the prefixes needed for directory names. If you want to, you can edit those files to change the default parameters of the images (make a backup before you change anything).

UNL expects the disk image file to be named hda.qcow2 . You do not have any choice here.

Now, let’s create a Debian image.

Log on UNL server using ssh (username=root password=unl).

Let’s create a new directory for our image:

cd /opt/unetlab/addons/qemu
mkdir linux-debian-8.3.0-i386
cd linux-debian-8.3.0-i386

Now you have two options, either you create an image on another computer and copy its disk image on UNL server, either you create the image on the UNL server itself. I’ll explain how to do the latter.

Download a Debian ISO file from your favorite mirror:

wget http://cdimage.debian.org/debian-cd/8.3.0/i386/iso-cd/debian-8.3.0-i386-netinst.iso

Create a disk image for the virtual machine:

/opt/qemu/bin/qemu-img create -f qcow2 hda.qcow2 4G

Start the virtual machine manually with a ISO file as virtual CDROM, booting on that ISO file and with a network interface:

/opt/qemu-2.0.2/bin/qemu-system-i386 -m 256 -smp 1 \
-cdrom debian-8.3.0-i386-netinst.iso -boot d \
-hda hda.qcow2 -monitor stdio -vnc -k fr-be \
-device e1000,netdev=net0,mac=50:02:12:34:00:00 \
-netdev tap,id=net0,ifname=debian0,script=no -S

You can now attach to the console (virtual screen) of the virtual machine using VNC (use the IP address of the UNL server and the screen number 10, e.g. You are going to get a black screen, that is normal because the last parameter of the qemu-system-i386 command is -S which means freeze CPU at startup (basically pause). To unpause the virtual machine, type cont in the QEMU console you got.

QEMU 2.0.2 monitor - type 'help' for more information
(qemu) cont

You should see the Debian install menu.

With the netinst image, the virtual machine will need Internet access. You have multiple options to achieve this: * connect the virtual machine network directly to your physical network * route the traffic between your physical network and the virtual machine * NAT the traffic of the virtual machine on the UNL server

I am going to go with the third option.

You can use one of the default bridge interfaces that UNL creates or use a new one. Let’s use a new one, we will call it brdebian and assign it the IP address

brctl addbr brdebian
ip link set brdebian up
ip address add dev brdebian

UNL does not come with iptables installed but we need it to enable NAT.

apt-get install iptables

Let’s tell the kernel we want it to NAT everything that comes from the subnet we chose:

iptables -t nat -A POSTROUTING -s -j MASQUERADE

and let’s tell the kernel it can forward IP packets:

echo 1 | tee /proc/sys/net/ipv4/ip_forward

Finally, let’s attach the virtual machine network interface to this network

brctl addif brdebian debian0
ip link set debian0 up

Assign an IP address from subnet to the virtual machine, set its gateway to and it will get Internet access.

Customize your image as you wish. When you are done, power it off, make a backup of the hda.qcow2 file (just in case).

You can now use that image in UNL.

Note that all the network changes we did are temporary and will disappear when you reboot the UNL server.

Posted in Computer, Linux, Networking | Leave a comment

Cisco IOS PPTP server : PPP: Packet throttled, Dropping packet

If you get the following message on your Cisco router when you connect a VPN client using PPTP

*Mar 17 16:43:02.371: Vi5 PPP: Control packet rate limit 10 reached
*Mar 17 16:43:02.371: Vi5 PPP: Entering block state for 30 seconds
*Mar 17 16:43:02.371: Vi5 PPP: Packet throttled, Dropping packet

Then it means you have an IOS version which greatly reduced the allowed rate of PPP control packets before it triggers a block.

Unfortunately, Windows 7 client sends packets at a rate that exceeds Cisco new default value. The result is that it takes 30 seconds (the default block duration) for the client to connect (yes, it connects successfully).

To fix this, you can change the rate threshold on the Cisco router by adding this line to your config:

ppp packet throttle 20 1 30

It tells the router to accept up to 20 packets per 1 second, and block for 30 seconds if this rate is exceeded.

Posted in Cisco, Networking | Leave a comment

Microsoft Windows 7 PPTP issues: spurious ICMP protocol-unreachable sent

I was recently confronted to a strange issue with a PPTP VPN connection to a central site. Some users could connect and some others could not. They all used Windows 7 with SP1, configured the same way, and all computers were behind NAT/PAT routers but not necessarily on the same site.

On the VPN server, the only information I could get was this log stating the GRE protocol was unreachable:
Feb 23 09:12:29 pppd[9712]: pppd 2.4.4 started by root, uid 0
Feb 23 09:12:29 zebra[2422]: interface ppp2 index 359 <POINTOPOINT,NOARP,MULTICAST> added.
Feb 23 09:12:29 pppd[9712]: Connect: ppp2 <--> /dev/pts/8
Feb 23 09:12:29 pptpd[9711]: GRE: read(fd=7,buffer=608c80,len=8260) from network failed: status = -1 error = Protocol not available
Feb 23 09:12:29 pptpd[9711]: CTRL: GRE read or PTY write failed (gre,pty)=(7,6)
Feb 23 09:12:29 pppd[9712]: Modem hangup
Feb 23 09:12:29 pppd[9712]: Connection terminated: no multilink.

I saw that I was getting ICMP protocol-unreachable packets from the WAN IP of the client. Using wireshark on the client, I saw that the packets were sent from it.

After Googling a bit, I found this post and that post.
They described exactly what was happening: some computers sent the ICMP protocol-unreachable and some others did not. The common point between computers that did send the packets was the Windows firewall was turned off.

Where applicable, I turned on the Windows firewall and it blocked those packets, and then the VPN connection was stable and working well.

To fix the issue for computers where turing the firewall on was not possible, I blocked the packets on the NAT/PAT router itself.
With a Linux router, you can do it by dropping the packets in the FORWARD rule of the FILTER table: iptables -I FORWARD -p icmp --icmp-type protocol-unreachable -d x.x.x.x -j DROP.
With a Cisco router, you need to add an ACL entry on the LAN interface: deny icmp any x.x.x.x y.y.y.y protocol-unreachable . If you had no ACL on the interface before, don’t forget to add a permit ip any any after the deny rule and before you apply the ACL on the interface, or you’ll deny all the traffic (Cisco has an implicit deny at the end of ACLs).

Stupid bugs…

Posted in Computer, Microsoft, Networking | Tagged , , , , , , , | Leave a comment

Ubuntu 14.04 and USB to Serial ch341 (chinese device from Ebay)

You can find pretty cheap USB to Serial devices on Ebay. I bought one and received a device using a chip ch341.

Unfortunately, the drive is bugged in Ubuntu 12.04 and 14.04. Fortunately, there is patch to fix it.

Here is how to recompile the module to enjoy these devices.

$ sudo apt-get source linux-source-3.13.0 linux-headers-$(uname -r)
$ cd /tmp
$ tar -xjf /usr/src/linux-source-3.13.0.tar.bz2
$ cd linux-source-3.13.0/
$ make oldconfig
$ make prepare
$ make scripts
$ cp -v /usr/src/linux-headers-$(uname -r)/Module.symvers .
$ cp /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ch341.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ch341.ko.orig
$ cd drivers/usb/serial
$ cp ch341.c ch341.c.orig
$ wget https://github.com/karlp/ch341-linux/raw/master/0001-usb-serial-ch341-Add-parity-support.patch
$ cat 0001-usb-serial-ch341-Add-parity-support.patch | patch -p4
patching file ch341.c
Hunk #1 succeeded at 349 (offset 3 lines).
Hunk #2 succeeded at 370 (offset 3 lines).
$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
$ sudo cp ch341.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ch341.ko
$ sudo rmmod ch341
$ sudo modprobe ch341

Source for instructions: askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module

Posted in Computer, Linux | 6 Comments