Author Archives: James Coyle

Set up Fail2ban for Proxmox Web GUI

Get Social!

fail2ban_logoFail2ban is an application that scans log files in real time and bans malicious IP addresses based on a set of rules and filters you can set.

For this blog post, we’re going to look at capturing invalid login attempts to the Proxmox Web GUI and ban any IP addresses from accessing the Web GUI if they fail to authenticate 3 times from the same IP address.

Fail2ban is made up of three main component parts:

  • Filter – a Filter is a pattern or regular expression that we wish to search for in the log files. In our case, we want to search for the words ‘authentication failure’ in the log because that’s what the pvedaemon writes when a failed login attempt occurs.
  • Action – an Action is what we’ll do if the filter is found. What we need to do is ban any IP address where the filter is triggered 3 times.
  • Jail – a Jail in Fail2ban is the glue that holds it all together – this ties a Filter, together with an Action and the relevant log file.

Install Fail2ban

Installing Fail2ban on Debian/ Proxmox is as easy as it gets – just use the apt package manager.

apt-get install fail2ban

Fail2ban is mostly Python, so it’ll need to be installed on the system or apt-get  will install it as a dependency.

Note: by default Fail2ban will enable itself on SSH connections, blocking invalid IPs after 6 invalid attempts. 

Configure Fail2ban for the Proxmox Web GUI

There are several steps to setting up Fail2ban. As mentioned earlier in the post, we want to ban any users IP address from accessing the Proxmox Web GUI if they have failed to authenticate 3 times. We shouldn’t block them indefinitely because it may be a simple password issue that they can resolve with the account administrator. We’ll configure Fail2ban to ban failed attempts for an hour.

Because banning a user after 3 invalid attempts is a fairly basic thing in the world of Fail2ban, we won’t need to create an Action as listed above. We’ll need to create a Jail and a Filter.

The Jail

A Jail in Fail2ban is the core configuration that  combines a Filter, an Action (although this may be default Fail2ban behaviour) and a log file.

The default configuration for Fail2ban is found in /etc/fail2ban/jail.conf and contains many predefined entries for common processes such as FTP and Apache. We shouldn’t edit this file directly when adding new entries, instead, we should create the below file which will be used to override the default jail.conf.

vi /etc/fail2ban/jail.local

Add the following (this file may not already exist):

[proxmox-web-gui]
enabled  = true
port     = http,https,8006
filter   = proxmox-web-gui
logpath  = /var/log/daemon.log
maxretry = 3
bantime = 3600

The above entry has set a ruleset name of proxmox-web-gui, and the following:

  • enabled – this simply states that this ruleset is active.
  • port – set sthe port that any bans should act on
  • filter – this sets the file name of the filter that we’ll use to detect any login failures. More about this in the next section.
  • logpath – the name or pattern (for example /var/log/apache/*.log) of the log to monitor for the failed logins. This is the file that the above filter will work on.
  • maxretry – this is how many times should the filter detect a problem before starting the ban.
  • bantime – this is how long, in minutes, that the ban be in effect for.

The Filter

Now that we have specified the log file to look in we need to specify how to find the event we need to look for. For our example, Proxmox writes a specific string each time a failed login occurs which looks like the belew:

authentication failure; rhost=10.10.10.10 [email protected] msg=no such user ('[email protected]')

Our Filter, therefore, needs to look for this text and pull out the IP address.

Create a Filter file called proxmox-web-gui.conf in /etc/fail2ban/filter.d/.

vi /etc/fail2ban/filter.d/proxmox-web-gui.conf

Add the following:

[Definition]
failregex = pvedaemon\[[0-9]+\]: authentication failure; rhost=<HOST> user=.* msg=.*

This will match the text that Proxmox writes to the daemon.log file when a failed login is detected. It’s got a Fail2ban specific keyword <HOST> which is what’s used to indicate to Fail2ban where the offending IP address is in the log entry. Fail2ban can then block this IP address as indicated in our Jail file.

Testing Fail2ban Filters

Fail2ban provides a nice little utility to test your Filter definitions to make sure they are working as you intend. First things first – we need an entry in our log file for an invalid login attempt. Go to your Proxmox Web GUI and enter some invalid login credentials.

The command to use is fail2ban-regex which has two parameters; the log file location and the Filter location.

fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox-web-gui.conf

An example of the output is below. The text Success, the total number of match is 1 states that there is one match in the log for our pattern in the proxmox-web-gui.conf file.

fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox-web-gui.conf

Running tests
=============

Use regex file : /etc/fail2ban/filter.d/proxmox-web-gui.conf
Use log file   : /var/log/daemon.log


Results
=======

Failregex
|- Regular expressions:
|  [1] pvedaemon\[[0-9]+\]: authentication failure; rhost=<HOST> user=.* msg=.*
|
`- Number of matches:
   [1] 1 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
    10.27.4.98 (Fri May 29 12:31:14 2015)

Date template hits:
770 hit(s): MONTH Day Hour:Minute:Second
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second
0 hit(s): Year/Month/Day Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/MONTH/Year:Hour:Minute:Second
0 hit(s): Month/Day/Year:Hour:Minute:Second
0 hit(s): Year-Month-Day Hour:Minute:Second
0 hit(s): Year.Month.Day Hour:Minute:Second
0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond]
0 hit(s): Day-Month-Year Hour:Minute:Second
0 hit(s): TAI64N
0 hit(s): Epoch
0 hit(s): ISO 8601
0 hit(s): Hour:Minute:Second
0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 1

However, look at the above section 'Running tests' which could contain important
information.

Restart fail2ban for the new Jail to be loaded.

service fail2ban restart

To check your new Jail has been loaded, run the following command and look for the proxmox-web-gui Jail name next to Jail List.

fail2ban-client -v status
INFO   Using socket file /var/run/fail2ban/fail2ban.sock
Status
|- Number of jail:      2
`- Jail list:           ssh, proxmox-web-gui

Try to log into the Proxmox Web GUI with an incorrect user 3 and see your IP address appear in the Currently banned section.

fail2ban-client -v status proxmox-web-gui
INFO   Using socket file /var/run/fail2ban/fail2ban.sock
Status for the jail: proxmox-web-gui
|- filter
|  |- File list:        /var/log/daemon.log
|  |- Currently failed: 0
|  `- Total failed:     3
`- action
   |- Currently banned: 1
   |  `- IP list:       10.10.10.10
   `- Total banned:     1

 


Upload OVA to Proxmox/ KVM

Get Social!

Proxmox does not have native support for an OVA template which is surprising considering it’s the open format for creating packaged virtual machines, or virtual appliances as they are often referred.

We can still get an OVA template running in Proxmox but it will take a little bit of work to transform it into a functional VM.

ovf-upload

First off, lets get the OVA file uploaded to the Proxmox server; you can do this using SCP or the Proxmox web GUI. If you use the Proxmox web GUI you will need to rename the OVA to end in a iso extension and upload it as a ISO image content. Depending on the size of the OVA file and the bandwidth you have available, it may take a while to upload the file. The file will then be available in the dump folder in the selected storage.

SSH onto your Proxmox server and locate the OVA file. An OVA file is simply a tar file containing an image file and some configuration for things like CPU, RAM, etc. Run the tar command to extract the components of the OVA file onto your file system.

tar - my.ovf

The output will be two or more files – one will be an OVF file which contains the settings and configuration of the virtual machine and one or more files will be VMDKs which are the disk images of the virtual machine.

Although you can run a VMDK file in Proxmox, it’s recommended to use qcow2 which is the default file format for Proxmox virtual machines. Run the VMDK file through the converter – note this can take a while with large files.

qemu-img convert -f vmdk myvm-disk1.vmdk -O qcow2 myvm-disk1.qcow2

We now need to get the image into a VM with some hardware so that we can begin to use it. This is where things get tricky – the OVF file is not compatible with Proxmox and needs to be manually understood. The principle here is we are going to use the Proxmox web GUI to create a VM and replace the empty disk image which is created with our recently converted qcow2 image.

You can use vi to open the OVF file and understand some of the basic settings which are required for the VM. Open the OVF file and look for the following XML tags:

  • OperatingSystemSection
  • VirtualHardwareSection
  • Network
  • StorageControllers

You should be able to get a rough idea of the requirements for the KVM. In the Proxmox web GUI, click on Create VM and create a VM which meets the requirements of the image you converted. Make sure that you select qcow2 for the disk format. After clicking Finish an empty VM will be created – in this example I used local storage and VMID 101 so the disk images are stored in /var/lib/vz/images/101.

proxmox-complete-create-vm

Copy the previously converted qcow2 image over the existing image – be sure to overwrite the existing image otherwise your image will not be used and KVM will try to start with a blank, empty image.

mv /tmp/myvm-disk1.qcow2 /var/lib/vz/image/101/vm-101-disk-1.qcow2

Thats it – you can now start up the image from the Proxmox web GUI.


Create SSH Key Authentication Between Nodes

Category : How-to

Get Social!

Secure key authentication is one of the more secure ways to grant users access to a Linux server. The standard password authentication which is usually used to login to a server is replaced with an SSH key which is presented when authenticating. This increases security as passwords can eventually be cracked using brute force or even guessed in some circumstances. SSH keys are impossible to guess and almost impossible to to hack using brute force due to their length and complexity.

A SSH key is actually two strings of characters – one which is private and is used to connect to the server and another which is public which sits on the server itself.

Run the below command to create the key pair on the client machine.

ssh-keygen -t rsa

Accept the default location to save the key which will be inside the current users home directory:

Enter file in which to save the key (/home/james/.ssh/id_rsa):

For additional security, you can add a passhrase to the private key. This means the key cannot be used without the passphrase which increases the security of the key itself. Simply press return if you do not wish to use a passphrase.

Note: if you are using the key for applications to gain access to other servers, it’s unlikely that a passphrase will be supported.  

Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/james/.ssh/id_rsa
Your public key has been saved in /home/james/.ssh/id_rsa.pub. 
The key fingerprint is:
46:ba:02:fd:2f:9c:b9:39:ec:6c:90:50:d8:ec:7b:00 james@testpc
The key's randomart image is:
+--[ RSA 2048]----+
|   +             |
|  E +            |
|   +    .        |
|  ..o  o         |
|  ...+. S        |
|   .+..o         |
|    .=oo         |
|     oOo         |
|     o=+.        |
+-----------------+

The two keys have been created;

  • Private: /home/james/.ssh/id_rsa
  • Public: /home/james/.ssh/id_rsa.pub

The final step is to copy the public key to the machine which you are going to connect to. In Debian or Ubuntu you can use the ssh-copy-id – you will need to change [USER] for the user who you will connect to the remote machine as and [SERVER] to the hostname or IP address of the remote server you will connect to.

ssh-copy-id [USER]@[SERVER]

Not all Linux distributions will contain the required ssh-copy-id utility, many CentOS/ Red Hat distributions do not for example, so you will need to use the manual method. Again, you will need to substitute the [USER] and [SERVER] attributes to the details of your remote machine.

cat /home/james/.ssh/id_rsa.pub | ssh [USER]@[SERVER] "cat >> ~/.ssh/authorized_keys"

It is not always recommended for security reasons but you can copy this public key to multiple machines so that you can use the same private key to connect to multiple remote machines.


How to use PowerShell to (grep) Recursively Search for Text Within Files on Windows

Category : How-to

Get Social!

powershellThe thing I find most annoying with Windows is that it isn’t Linux. Let’s forget the argument of free software, the interchangeable GUIs, the security and everything else which constitutes the usual Linux vs. Windows argument and focus on things I use everyday in Linux which are missing in Windows. Two major things come to mind; tail for monitoring logs and grep which is the easiest way to find something in a file.

Not having grep, more specifically grep -r, is challenging at best and almost reason enough to avoid the platform entirely.

With the introduction of PowerShell, Windows has given us the grep functionality albeit with a much less finesse than the Linux equivalent. You have to pipe multiple commands together; one command to transverse the directories, and one command to look for the pattern within each file found.

Use the below command inside the directory you would like to perform the ‘grep’ and change [SEARCH_PATTERN] to match what you would like to match.

dir -Recurse | Select-String -pattern [SEARCH_PATTERN]

For example:

dir -Recurse | Select-String -pattern "Find Me"

As you can see, its nowhere near the memorable Linux command grep -r but at least its now possible go get similar behaviour in a Windows environment.

Other Windows grep Binaries

There are also various Windows binaries which can be used from a standard command prompt however I had limited luck with each one. The biggest issue was that they require dependencies such as .NET which are not usually installed in server environments.


Install Grails from Git on Windows

Category : How-to

Get Social!

grails-core-gradlew.bat-installGood news: installing Grails from source is easy-peasey on Windows! Before you get started, you’ll need to have git and a JDK installed.

You can download both git and the JDK from the following locations:

Once these are both installed, set the JAVA_HOME variable from a command prompt. You’ll need to locate the exact java version which is in your Program Files\Java folder as it changes with each version.

set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_25

Move to the folder where you would like to deploy Grails.

cd c:\apps\

And run the git clone command to start downloading the source.

git clone git://github.com/grails/grails-core.git

Move into the folder which was created with the git clone command.

cd grails-core

Finally run the install command which will download any further dependencies and compile the application.

gradlew.bat install

And that’s it! I told you it was easy.


Export MySQL Database into Separate Files per Table

Category : How-to

Get Social!

mysql-logoI have recently been using git to check in an applications database. The database has many tables, some of which are populated with test data and created a fairly large file when exported. I noticed a few issues issues when checking these into git, namely that the large file was uploaded and saved in git as a single large file containing my changes and the other stuff which had not changed.

Instead of using this large file as one and checking it into git, breaking the file into several smaller files means that only the table which changed would be added to the git commit resulting in much smaller uploads.

The below code is a bash script which let’s you export, using mysqldump, all tables in a MySQL database to individual files. This will result in one file per MySQL table in the database. You will need to modify the following attributes:

  • [USER] – the username to use when connecting to the MySQL instance.
  • [PASSWORD] – the password for the above MySQL user.
  • [DATABASE] – the name of the MySQL database to export.
  • [BACKUP_LOCATION] – the location on the MySQL server where the SQL files will be created.
#!/bin/bash
GIT_MYSQL=/[BACKUP_LOCATION]
for T in `mysql -u [USER] -p[PASSWORD] -N -B -e 'show tables from [DATABASE]'`;
do
    echo "Backing up $T"
    mysqldump --skip-comments --compact -u [USER] -p[PASSWORD] [DATABASE] $T > $GIT_MYSQL/$T.sql
done;

Visit our advertisers

Quick Poll

How many Proxmox servers do you work with?

Visit our advertisers