Set up strongMan on Ubuntu 22.04 — a Web UI for strongSwan VPN solution
Recently, I explored the WireGuard VPN solution and was pleasantly surprised by its user-friendly setup. Setting up a VPN server with a sleek graphical interface took just a few commands. Given that I use strongSwan at my workplace, I envisioned having a similar graphical interface for it. A quick Google search revealed that such a project already exists: StrongMan-a graphical web UI designed for StrongSwan. Excited to try it out, I encountered some difficulties getting it to run smoothly on my Ubuntu 22.04 host. In this write-up, I’ll share with you the process I went through to get it up and running.
Install strongSwan
First, update your local package cache using apt
:
sudo apt update
Then install the software by typing:
sudo apt install strongswan strongswan-pki strongswan-swanctl -y
strongswan-pki
package comes with a utility calledpki
to generate a Certificate Authority and server certificates.strongswan-swanctl
package comes with the Versatile IKE Control Interface (VICI) plugin
strongMan connects to the IKE daemon via VICI protocol, so you need to make sure that the VICI plugin is loaded:
sudo ipsec listplugins | grep -i vici
You should have an output as below:
vici:
CUSTOM:vici
Install the dependencies
Install python:
sudo apt install python3-pip -y
Install virtualenv:
sudo python3 -m pip install virtualenv
Make alias for python:
sudo ln -s /usr/bin/python3 /usr/bin/python
Install strongMan
Run the following commands to install strongMan:
git clone https://github.com/strongswan/strongMan.git
cd strongMan
sudo ./setup.py install
If things went smoothly, you will get an output as below:
Start strongMan installation
- Virtualenv
- Requirements
- Database migration
Delete strongMan/db.sqlite3
[Errno 2] No such file or directory: '/root/strongMan/strongMan/db.sqlite3'
- Static files
Please be aware that the [Errno 2] No such file or directory: '/home/ubuntu/strongMan/strongMan/db.sqlite3'
message in the preceding output is not a critical error; think of it more like a log entry. There's no need to worry. Initially, it might seem confusing-I fell for it myself the first time, thinking there was an issue. However, it's just a benign notification, and everything is actually functioning properly.
Set the environment to production
Replace strongMan.settings.local
by strongMan.settings.production
in the run.py
file. Otherwise, you might get a Invalid HTTP_POST header
error.
You can use your fav code editor or simply do it from the command line using:
sed -i 's/strongMan.settings.local/strongMan.settings.production/g' run.py
Configuration loader
To guarantee data consistency between strongMan and strongSwan, we need to make sure that the configuration loader script will be executed on the startup of strongSwan.
Put the following line into “strongswan-starter.service”. Replace “pathTostrongMan” with the path, where you installed strongMan.
ExecStartPost=/pathTostrongMan/configloader.py
Sample of the /lib/systemd/system/strongswan-starter.service
file:
[Unit]
Description=strongSwan IPsec IKEv1/IKEv2 daemon using ipsec.conf
After=network-online.target
[Service]
ExecStart=/usr/sbin/ipsec start --nofork
ExecReload=/usr/sbin/ipsec reload
Restart=on-abnormal
ExecStartPost=/root/strongMan/configloader.py
[Install]
WantedBy=multi-user.target
Reload for changes to take effect:
sudo systemctl daemon-reload
sudo systemctl restart strongswan-starter.service
Add a systemd service
If you want to run strongMan permanently in the background, you can install strongMan as a systemd service.
sudo ./setup.py add-service
Check if it’s working:
sudo systemctl status strongMan
You might get an output as below:
● strongMan.service - strongMan gunicorn service
Loaded: loaded (/etc/systemd/system/strongMan.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2023-11-18 11:29:54 UTC; 8s ago
Main PID: 28150 (python)
Tasks: 8 (limit: 2309)
Memory: 211.1M
CPU: 2.680s
CGroup: /system.slice/strongMan.service
├─28150 /root/strongMan/env/bin/python run.py
├─28152 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
├─28153 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
├─28154 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
├─28155 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
├─28156 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
├─28157 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
└─28158 /root/strongMan/env/bin/python /root/strongMan/env/bin/gunicorn --workers 6 --bind 0.0.0.0:1515 --env DJANGO_SETTINGS_MODULE=strongMan.s>
Nov 18 11:29:54 strongman systemd[1]: Started strongMan gunicorn service.
Nov 18 11:29:55 strongman python[28152]: [2023-11-18 11:29:55 +0000] [28152] [INFO] Starting gunicorn 20.0.4
Nov 18 11:29:55 strongman python[28152]: [2023-11-18 11:29:55 +0000] [28152] [INFO] Listening at: http://0.0.0.0:1515 (28152)
Nov 18 11:29:55 strongman python[28152]: [2023-11-18 11:29:55 +0000] [28152] [INFO] Using worker: sync
Nov 18 11:29:55 strongman python[28153]: [2023-11-18 11:29:55 +0000] [28153] [INFO] Booting worker with pid: 28153
Nov 18 11:29:55 strongman python[28154]: [2023-11-18 11:29:55 +0000] [28154] [INFO] Booting worker with pid: 28154
Nov 18 11:29:55 strongman python[28155]: [2023-11-18 11:29:55 +0000] [28155] [INFO] Booting worker with pid: 28155
Nov 18 11:29:55 strongman python[28156]: [2023-11-18 11:29:55 +0000] [28156] [INFO] Booting worker with pid: 28156
Nov 18 11:29:55 strongman python[28157]: [2023-11-18 11:29:55 +0000] [28157] [INFO] Booting worker with pid: 28157
Nov 18 11:29:55 strongman python[28158]: [2023-11-18 11:29:55 +0000] [28158] [INFO] Booting worker with pid: 28158
You now have strongMan service listening on http://your-server-IP:1515. Likewise, you can now log in to the web UI with:
- Username: John
- Password: Lennon@1940
That’s it!
Bonus
If you’re a fan of Ansible and embrace the concept of Infrastructure as Code, I have a playbook ready to effortlessly automate the entire installation process for you.
- name: Install strongMan
hosts: all
tasks:
- name: Update cache
become: true
ansible.builtin.apt:
update_cache: true
- name: Install strongswan
become: true
ansible.builtin.apt:
name:
- strongswan
- strongswan-pki
- strongswan-swanctl
state: present
- name: Install python3 and virtualenv
become: true
ansible.builtin.apt:
name:
- python3
- python3-virtualenv
- python3-pip
state: present
- name: Create a symbolic link
become: true
ansible.builtin.file:
src: /usr/bin/python3
dest: /usr/bin/python
state: link
- name: Clone strongMan repo
ansible.builtin.git:
repo: 'https://github.com/strongswan/strongMan.git'
dest: "{{ ansible_env.HOME }}/strongMan"
force: true
- name: Install strongMan
become: true
ansible.builtin.command:
cmd: sudo ./setup.py install
chdir: "{{ ansible_env.HOME }}/strongMan"
- name: Set the environment to production
ansible.builtin.replace:
path: "{{ ansible_env.HOME }}/strongMan/run.py"
regexp: 'strongMan\.settings\.local'
replace: 'strongMan.settings.production'
- name: Configuration loader
become: true
ansible.builtin.lineinfile:
path: /lib/systemd/system/strongswan-starter.service
insertafter: '^Restart=on-abnormal\n'
line: 'ExecStartPost={{ ansible_env.HOME }}/strongMan/configloader.py'
notify: Restart strongswan-starter service
- name: Add strongMan service
become: true
ansible.builtin.command:
cmd: sudo ./setup.py add-service
chdir: "{{ ansible_env.HOME }}/strongMan"
notify: Restart strongMan service
handlers:
- name: Restart strongswan-starter service
become: true
ansible.builtin.systemd_service:
state: restarted
daemon_reload: true
name: strongswan-starter.service
- name: Restart strongMan service
become: true
ansible.builtin.systemd_service:
state: restarted
daemon_reload: true
name: strongMan.service
What’s next?
Now that you have strongMan installed, take a look at this article of mine to learn how to set up an IKEv2 Point-to-Site VPN with it.
Thank you for reading this article all the way to the end! I hope you found the information and insights shared here to be valuable and interesting. Get in touch with me on LinkedIn
I appreciate your support and look forward to sharing more content with you in the future. Until next time!
References
Originally published at https://theko2fi.github.io on November 18, 2023.