Category: ubuntu

Initial Setup of a Ubuntu 20.04 VM with Compiled Python 3.10

Assuming you have logged in as root with a password

Creating a non-root User

adduser ubuntu
usermod -aG sudo ubuntu

Add your SSH key to the new User

ssh-copy-id ubuntu@
ssh ubuntu@

Enabling Firewall

sudo ufw app list
sudo ufw status

Disable root login and password based login

sudo vim /etc/ssh/sshd_config

Uncomment and set:

PasswordAuthentication no
PermitRootLogin no

Restart ssh:

sudo systemctl restart ssh.service

Set Timezone

sudo timedatectl list-timezones
sudo timedatectl set-timezone Africa/Johannesburg
sudo apt install ntp

Install nginx

sudo apt install -y nginx

Install required OS packages for Python 3.10

sudo apt install -y build-essential checkinstall
sudo apt install -y libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev lzma

Get Python

cd /opt
sudo wget
sudo tar xzf Python-3.10.2.tgz
cd Python-3.10.2


sudo ./configure --enable-optimizations

Install alongside default system python3.8:

sudo make altinstall
python3.10 --version
Python 3.10.2

Install MySQL

sudo apt install -y mysql-server
sudo mysql_secure_installation

Python Mysqlclient

The mysqlclient python package requires

sudo apt install libmysqlclient-dev


Installing python3.9 on ubuntu 20.04 from source

I've found installing python from source on ubuntu just makes your life easier. Python depends on a few system binaries and linked libraries so you need to ensure they are present first.

sudo apt install software-properties-common build-essential \
libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev \
tk-dev libgdbm-dev libc6-dev libbz2-dev libncurses-dev libgdbm-dev \
libpcap-dev libexpat1-dev libffi-dev liblzma-dev libgdbm-compat-dev

Get the latest tarball link from Linux/Unix

cd /opt
sudo wget
sudo tar xzf Python-3.9.1.tgz
#read the readme
cat README.rst

It will tell you what to do:

make test
sudo make install

Python3.8 is installed by to create a virtual environment use:

python3.9 -m venv env

Fail2Ban Custom filters and Testing Regex’s against existing Logs

Fail2ban is a tool that can automatically ban malicious bots trying to get into your server. Provided you set up filters and the ip address is logged you can use fail2ban with any application.

fail2ban is built with python2.7

Create a filter, using a regular expression:

In /etc/fail2ban/filter.d/my-custom-filter.conf:


failregex = ^  -.* "POST \/user\/register HTTP\/1.0" 200

ignoreregex =

Now you want to test this for matches against a log file. Ensure that the log file has existing matches.

Make use of the command line tool fail2ban-regex:

fail2ban-regex /var/log/apache2/example-access.log /etc/fail2ban/filter.d/my-custom-filter.conf

You will get summary data like this:

Running tests

Use   failregex file : /etc/fail2ban/filter.d/my-custom-filter.conf
Use         log file : /var/log/apache2/example-access.log


Failregex: 1 total
|-  #) [# of hits] regular expression
|   1) [1] ^  -.* "POST \/user\/register HTTP\/1.0" 200

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [23636] Day/MONTH/Year:Hour:Minute:Second

Lines: 23636 lines, 0 ignored, 1 matched, 23635 missed
Missed line(s): too many to print.  Use --print-all-missed to print all 23635 lines

Which lets you debug your filter regular expression to ensure it is matching the malicious log entries.


Finally, add the new filter to your jail.local by appending the following:

enabled  = true
filter   = my-custom-filter
action   = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath  = /var/log/apache2/example-access.log
banTime  = 864000
findtime = 1800
maxRetry = 3

You can read more about the configuration of jails in the manual