[LINUX] Simple VPN construction of IPsec gateway with Ubuntu 20.04 and Raspberry Pi ―― 1. StrongSwan introduced

Assumptions and preparations

Linux server building article

-Building a file server with Samba (CentOS 8.1 / openSUSE 15.1 / Ubuntu 20.04) -Source compilation of Apache2.4 + PHP7.4 on Linux-- 1. Apache introduction / [Raspberry Pi] / items / 67686eccaaec73251458) -Source compilation of Apache2.4 + PHP7.4 on Linux-- 2. PHP introduction / [[Raspberry Pi]](https://qiita.com/kazumi75kitty / items / 50f1a447f6ebc2ee2b61) -Source compilation of Apache2.4 + PHP7.4 on Linux-- 3. MySQL introduction/[[Raspberry Pi]](https://qiita.com/kazumi75kitty / items / 4212dacc45944f27ca94) -Apache2.4 + PHP7.4 on Linux --4 Security (chown and firewalld) -Build an IPsec gateway on Linux VPN-- 1. Introduce StrongSwan / [Ubuntu 20.04 + Raspberry Pi: This article] -Build an IPsec gateway on Linux for VPN-- 2. Check connection to VPN / [[Ubuntu 20.04 + Raspberry Pi]](https://qiita.com / kazumi75kitty / items / c83f920f052d83d62457)

Last time, I built an IPsec gateway with StrongSwan source compilation with CentOS 8 + Raspberry openSUSE. I tried to do this with Ubuntu 20.04 and Raspberry Pi OS (˶ ・ ᴗ ・) ੭⚐⚑

environment

Premise

--Minimal installation of OS. Also, the OS must be updated in the latest state. --User installed as root (in my verification, it is an administrator account called admin, and it is processed by sudo from there) --In all distributions, the firewall uses ufw (In Raspberry Pi OS of Raspberry Pi, for firewalld, since the linkage around IPv6 was a waste, I decided to use the Debian standard ufw)

Server conditions

IP address and network construction diagram

--Network segment: --Internet connection possible: 192.168.1.0/24 --Raspberry Pi (negotiation receiving side on the left of the figure) Secure segment: 192.168.2.0/24 --Ubuntu 20.04 (Negotiation originator on the right of the figure) Secure segment: 192.168.5.0/24

Ability and version to download and install individual packages (as of September 2020)

Other required packages are installed with the distribution's standard package commands (dnf, apt, etc.) and do not need to be downloaded individually.

For download, you can access the official website, download from there and transfer it by FTP, or you can get it with wget if you know the URL of the download file, but the acquisition method is omitted.

Work procedure

Preparation

Install make, cmake, package decompression function

Install per distribution on Hyper-V virtual machine and Raspberry Pi (source compilation is the same for both)

Ubuntu20.04(Hyper-V/x64)


# apt-get -y install make cmake tar bzip2

RaspberryPiOS(2020.08)


# apt-get -y install make cmake tar bzip2

Install GCC and C ++ compiler

Ubuntu20.04(Hyper-V/x64)


# apt-get -y install gcc build-essential

RaspberryPiOS(2020.08)


# apt-get -y install gcc build-essential

zlib source installation

I installed zlib without changing the default location. Source compilation is the same for Hyper-V virtual machines and Raspberry Pi

# cd [The directory where the zlib archive files are located]
# tar zxvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11/
# ./configure
# make
# make install

Enable IP forwarding

IP forwarding must be enabled in order to operate as an IPsec gateway, so enable it. It seems that it is necessary to add it to the sysctl.d configuration file and load it if it is a command (openSUSE is kindly easy to set with YaST even from SSH)

# cat /proc/sys/net/ipv4/ip_forward
0
# vi /etc/sysctl.d/01-ipv4fwd.conf

conf:/etc/sysctl.d/01-ipv4fwd.conf


# Controls IP packet forwarding
net.ipv4.ip_forward = 1

Expansion of network adapters in the VPN area

For both Hyper-V virtual machine and Raspberry Pi, ** turn off the power once ** to enable IP transfer + add a network adapter. In my case, Raspberry Pi added a wired LAN adapter for VPN via USB, and Hyper-V added a network adapter in the settings.

After the expansion, check if "eth1" is added, but of course the IP address has not been assigned yet.

# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [MAC address of the network adapter from the beginning] brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.18/24 brd 192.168.1.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 [IPv6 address of the network adapter from the beginning] scope global temporary dynamic
       valid_lft 14043sec preferred_lft 12243sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [MAC address of the extension network adapter] brd ff:ff:ff:ff:ff:ff
    inet6 [IPv6 address of extension network adapter] scope link noprefixroute
       valid_lft forever preferred_lft forever

# ip route

default via 192.168.1.1 dev eth0 proto static metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.18 metric 100

After restarting, the command is used to enable IP forwarding, so check if it is enabled (ip_forward is 1).

# cat /proc/sys/net/ipv4/ip_forward
1

# sysctl --system
…(Omission)
* Applying /etc/sysctl.d/01-ipv4fwd.conf ...
net.ipv4.ip_forward = 1
…(Omission)

Install the packages required to compile StrongSwan with the distribution standard package command

Note: If you do not execute it even if it is troublesome, you will get an error saying that there is no package and the compilation will be stopped (´ • ω • ̥`)

Ubuntu20.04(Hyper-V/x64)


# apt-get -y install libgmp-dev libssl-dev

RaspberryPiOS(2020.08)


# apt-get -y install libgmp-dev libssl-dev

Installation of source compilation for StrongSwan 5.9.0

Common to Hyper-V virtual machines and Raspberry Pi. This process took quite a while (especially for the Raspberry Pi, it took 20-30 minutes)

configure and make

# cd [strongswan-5.9.0.tar.Directory where gz is located]
# tar xvzf strongswan-5.9.0.tar.gz
# cd strongswan-5.9.0/
# ./configure --prefix=/usr --sysconfdir=/etc --enable-openssl
# make
# make install

If you can compile without error, the installation is complete ♪ (\ * ˘︶˘ \ *) ...: \ * ♡

StrongSwan Preferences

When StrongSwan is installed by source compilation, the configuration file is stored in /etc/ipsec.conf, and the IPsec connection settings are set in it.

[Apache basic settings]
# vi /etc/ipsec.conf

The side that establishes IPsec (the one that originates the establishment), yes, first, set up Ubuntu 20.04 of Hyper-V. As described in the "Server conditions" section, from the Hyper-V machine side, your IP address will be 192.168.1.18 and the Raspberry Pi of the establishment partner will be 192.168.1.22, so write the pair to the configuration file.

"Left" writes the information of the person who negotiates the establishment, and "right" writes the information of the person to establish (from StrongSwan official manual. / ConnSection)))

Ubuntu20.04(Hyper-V/x64)


…
#Add the following
conn [Distinguished name Example: linux-2-linux]
      authby=secret
      auto=start				#Send IPsec negotiations
      closeaction=restart
      dpdaction=restart
      left=192.168.1.18			#left is your own IPsec gateway
      leftid=192.168.1.18		#ID that identifies you to negotiate IPsec
      leftsubnet=192.168.5.0/24
      right=192.168.1.22		#right is the other IPsec gateway
      rightid=192.168.1.22		#ID that identifies the IPsec negotiating partner
      rightsubnet=192.168.2.0/24
…

By the way, for the ID, I used the IP address for simplicity in my case, but a character string is also OK. And since leftsubnet and rightsubnet are VPN areas that you and the other party are in charge of, leftsubnet is your own VPN area, so 192.168.5.0/24, and rightsubnet is your partner's Raspberry Pi VPN area, so 192.168.2.0/ I put in 24.

Next, set the Raspberry Pi. As described in the "Server conditions" section, the IP address to be established is 192.168.1.22, and the Hyper-V Ubuntu 20.04 on the other side to be established is 192.168.1.18, so Hyper-V (Ubuntu 20.04) ) Is written to the configuration file.

RaspberryPiOS(2020.08)


#Add the following
conn [Distinguished name Example: linux-2-linux]
      authby=secret
      auto=add				#Receive IPsec negotiations
      closeaction=clear
      dpdaction=clear
      left=192.168.1.22
      leftid=192.168.1.22
      leftsubnet=192.168.2.0/24
      right=192.168.1.18
      rightid=192.168.1.18
      rightsubnet=192.168.5.0/24

The point is that by setting auto = add, it is set on the receiving side of the IPsec establishment negotiation, and the contents of left and right are reversed. That way, if the distinguished names (the string after conn) match, you can establish an IPsec connection.

StrongSwan's default is PSK, which uses AES / SHA encryption as standard. If it is necessary to set other encryption methods, set them separately, but omit them here.

As an aside, StrongSwan at this point supports NAT-T, and IPsec can be applied to NAT (in the past, IPsec could not be applied to NAT), so NAT is used on the Internet. It seems that even the space that is being used can communicate VPN built with StrongSwan over the Internet (although I have never experimented with it ...).

[StrongSwan key setting]
# vi /etc/ipsec.secrets

/etc/ipsec.secrets


…
: PSK "[Appropriate string: Example ... kazumi75kitty]"
…

Since we are using the default PSK method, we will make it the same for both Hyper-V virtual machines and Raspberry Pi.

Launch StrongSwan

Service startup script creation & activation

Now that you have the necessary environment settings for StrongSwan, I would like to be able to start it. Since the startup script is Systemd, create it in / etc / systemd / system

# cd /etc/systemd/system
# vi strongswan.service

strongswan.service


[Unit]
Description=strongSwan

[Service]
Type=forking
ExecStart=/usr/sbin/ipsec start
ExecStop=/usr/sbin/ipsec stop

[Install]
WantedBy=multi-user.target

The Systemd script is not explained in detail here, but since the start and stop are executed in the background from the parent process, the Type of [Service] is forking in strongSwan.

ufw settings

ufw accepts IPsec as well as firewalld. The ports used by ipsec are 500/4500 TCP / UDP port numbers and the AH / ESP protocol. However, with the settings here, tunneling is not specified. 192.168.1.0/24 Internal limitation is not specified, and IPsec packets can be received from other network segments if they can pass. However, if you take measures up to this point, it will be complicated, so for the sake of simplicity, we will only allow IPsec.

# ufw allow 500
# ufw allow 4500
# ufw allow to any proto ah
# ufw allow to any proto esp
# ufw status numbered

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 30303/tcp                  ALLOW IN    192.168.1.0/24
[ 2] 5900:5999/tcp              ALLOW IN    192.168.1.0/24
[ 3] 500                        ALLOW IN    Anywhere
[ 4] 4500                       ALLOW IN    Anywhere
[ 5] Anywhere/esp               ALLOW IN    Anywhere/esp
[ 6] Anywhere/ah                ALLOW IN    Anywhere/ah
[ 7] 500 (v6)                   ALLOW IN    Anywhere (v6)
[ 8] 4500 (v6)                  ALLOW IN    Anywhere (v6)
[ 9] Anywhere/esp (v6)          ALLOW IN    Anywhere/esp (v6)
[10] Anywhere/ah (v6)           ALLOW IN    Anywhere/ah (v6)

This command is common to both Hyper-V virtual machines and Raspberry Pi.

Start up and check operation

Let's start it. Always start with enable Enable & confirm that status is "Active" and "Running".

** First, StrongSwan is started from the side that receives the IPsec establishment negotiation, and then it is started in the order of the side that sends the IPsec establishment **. Here, after starting StrongSwan of Raspberry Pi, StrongSwan of Hyper-V virtual machine is started.

# systemctl start strongswan
# systemctl enable strongswan
# systemctl status strongswan

Check that the Hyper-V virtual machine and Raspberry Pi are set to "Active" and "Running", and finally check if IPsec tunneling is established.

Ubuntu20.04(Hyper-V/x64)


# /usr/sbin/ipsec status
Security Associations (1 up, 0 connecting):
linux-2-linux[1]: ESTABLISHED 2 minutes ago, 192.168.1.18[192.168.1.18]...192.168.1.22[192.168.1.22]
linux-2-linux{1}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: ********_i ********_o
linux-2-linux{1}:   192.168.5.0/24 === 192.168.2.0/24

# ip xfrm policy
src 192.168.5.0/24 dst 192.168.2.0/24
        dir out priority 375423 ptype main
        tmpl src 192.168.1.18 dst 192.168.1.22
                proto esp spi 0x******** reqid 1 mode tunnel
src 192.168.2.0/24 dst 192.168.5.0/24
        dir fwd priority 375423 ptype main
        tmpl src 192.168.1.22 dst 192.168.1.18
                proto esp reqid 1 mode tunnel
src 192.168.2.0/24 dst 192.168.5.0/24
        dir in priority 375423 ptype main
        tmpl src 192.168.1.22 dst 192.168.1.18
                proto esp reqid 1 mode tunnel

RaspberryPiOS(2020.08)


# /usr/sbin/ipsec status
Security Associations (1 up, 0 connecting):
linux-2-linux[1]: ESTABLISHED 2 minutes ago, 192.168.1.22[192.168.1.22]...192.168.1.18[192.168.1.18]
linux-2-linux{1}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: ********_i ********_o
linux-2-linux{1}:   192.168.2.0/24 === 192.168.5.0/24

# ip xfrm policy
src 192.168.2.0/24 dst 192.168.5.0/24
        dir out priority 375423 ptype main
        tmpl src 192.168.1.22 dst 192.168.1.18
                proto esp spi 0x******** reqid 1 mode tunnel
src 192.168.5.0/24 dst 192.168.2.0/24
        dir fwd priority 375423 ptype main
        tmpl src 192.168.1.18 dst 192.168.1.22
                proto esp reqid 1 mode tunnel
src 192.168.5.0/24 dst 192.168.2.0/24
        dir in priority 375423 ptype main
        tmpl src 192.168.1.18 dst 192.168.1.22
                proto esp reqid 1 mode tunnel

IPsec tunneling has been successfully established with Hyper-V virtual machines and Raspberry Pi (˶ ・ ᴗ ・) ੭⚐⚑

Bonus (specify a character string such as domain for the ID of ipsec.conf)

In the StrongSwan configuration file /etc/ipsec.conf, even if you use a character string instead of an IP address with leftid or rightid, the capture screen will be posted (\ * ´꒳` \ *)

Maybe this one is easier to understand. The screen is CentOS + openSUSE, but I think that the operation is the same on Ubuntu etc. In the example, "raspberry pi" and "test only @ kazumi-jam" are distinguished. ipsec.confのIDに文字列やドメインを指定する

Supplement (when IPsec tunneling goes through NAT)

I don't have an easy-to-understand image yet, but for the left and right IP addresses in ipsec.conf, enter your own IP address and the IP address of the other party after NAT conversion as seen from you. At that time, it is necessary that the left id and the right id match each other in pairs.

Example: 192.168.1.0/24 → When 192.168.120.0/28 is partitioned by NAT

IPsecGW-1 (within 192.168.1.0/24)  left=192.168.1.22  leftid="gw1"  right=192.168.1.18  rightid="gw2" IPsecGW-2 (within 192.168.120.0/28)  left=192.168.120.1  leftid="gw2"  right=192.168.120.3  rightid="gw1"

In this way, IPsec can be established by entering an IP address that takes NAT into consideration, but I will post more details later.

next time

With the introduction of StrongSwan, the construction of the IPsec gateway has been completed on Ubuntu 20.04 on Raspberry Pi and Hyper-V as well as on CentOS. Next, even under Ubuntu, connect the client and server to the VPN connected to the IPsec gateway and try to connect to each other (˶˙ᵕ˙˶).

Recommended Posts

Simple VPN construction of IPsec gateway with Ubuntu 20.04 and Raspberry Pi ―― 1. StrongSwan introduced
Simple VPN construction of IPsec gateway with CentOS 8 and openSUSE (Raspberry Pi) ―― 1. StrongSwan introduced
Simple VPN construction of IPsec gateway with Ubuntu 20.04 and Raspberry Pi --2 StrongSwan VPN connection confirmation
IPsec gateway VPN construction with CentOS 8 and openSUSE (Raspberry Pi) --2 StrongSwan VPN connection confirmation
VPN server construction with Raspberry Pi
Ubuntu 20.04 on raspberry pi 4 with OpenCV and use with python
Production of temperature control system with Raspberry Pi and ESP32 (1)
Graph display of household power consumption with 3GPI and Raspberry Pi
Pet monitoring with Rekognition and Raspberry pi
Make a wireless LAN Ethernet converter and simple router with Raspberry Pi
Production of temperature control system with Raspberry Pi and ESP32 (2) Production of transmission device
I tweeted the illuminance of the room with Raspberry Pi, Arduino and optical sensor
I tried to build an environment of Ubuntu 20.04 LTS + ROS2 with Raspberry Pi 4
MQTT RC car with Arduino and Raspberry Pi
CSV output of pulse data with Raspberry Pi (CSV output)
Get CPU information of Raspberry Pi with Python
Play with your Ubuntu desktop on your Raspberry Pi 4
Get temperature and humidity with DHT11 and Raspberry Pi
Measure CPU temperature of Raspberry Pi with Python
Key points of creating LiveUSB of Ubuntu "with VPN and remmina connection settings" (provisional version)
Distributed environment construction with Raspberry PI series (Part 4: NFS server construction and client OS import)
Record temperature and humidity with systemd on Raspberry Pi
Machine learning with Raspberry Pi 4 and Coral USB Accelerator
Easy IoT to start with Raspberry Pi and MESH
Detect mask wearing status with OpenCV and Raspberry Pi
Take the value of SwitchBot thermo-hygrometer with Raspberry Pi
Measure temperature and humidity with Raspberry Pi3 and visualize with Ambient
Log the value of SwitchBot thermo-hygrometer with Raspberry Pi
Installation of Docker on Raspberry Pi and L Chika
Getting Started with Yocto Project with Raspberry Pi 4 and WSL2
Troubleshoot with installing OpenCV on Raspberry Pi and capturing
Let's operate GPIO of Raspberry Pi with Python CGI
Easily make a TweetBot that notifies you of temperature and humidity with Raspberry Pi + DHT11.
Distributed environment construction with Raspberry PI series (7: tftp route setting and startup test for each Raspberry Pi)
GPGPU with Raspberry Pi
DigitalSignage with Raspberry Pi
Easy introduction to home hack with Raspberry Pi and discord.py
Create a web surveillance camera with Raspberry Pi and OpenCV
Python beginner opens and closes interlocking camera with Raspberry Pi
I tried running Movidius NCS with python of Raspberry Pi3
Create an LCD (16x2) game with Raspberry Pi and Python
I tried connecting Raspberry Pi and conect + with Web API
Measure and compare temperature with Raspberry Pi and automatically generate graph
Construction of Cortex-M development environment for TOPPERS using Raspberry Pi
Image recognition of garbage with Edge (Raspberry Pi) from zero knowledge using AutoML Vsion and TPU