Securing Plesk with Fail2Ban
It seems more and more Plesk customers are getting hit with bruteforce attacks. A large target is email services; pop3, pop3s, imap, imaps. I've put together the following guide to assist you in securing your Plesk server with Fail2Ban rules.
Courier IMAP
Step 1.) Create the filter
Edit the following Fail2Ban filter...
/etc/fail2ban/filter.d/courierlogin.conf
Change: LOGIN FAILED, .*, ip=\[< HOST >\]$ To: LOGIN FAILED, ip=\[<HOST>\]$ |
Step 2.) Create the action rule
Insert the following into your /etc/fail2ban/jail.local
[courierimap-iptables] enabled = true # yes, enable this jail filter = courierlogin # name of filter we use action = iptables-multiport[name=IMAP, port="110,995,143,993"] # this is a multiport jail as it handles; 110, 143, 993, 995 sendmail-whois[name=IMAP, dest=you@your-server.domain.net, sender=fail2ban@your-server.domain.net] # where to send the alert email logpath = /usr/local/psa/var/log/maillog # Plesk maillog standard location maxretry = 5 # Only allow 5 attempts |
Dovecot
Step 1.) Create the filter
Create the following Fail2Ban filter...
/etc/fail2ban/filter.d/dovecot-pop3imap.conf
[Definition] failregex = (?: pop3-login|imap-login): .*(?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed|Aborted login \(\d+ attempts).*rip=(?P<host>\S*),.* ignoreregex = |
Step 2.) Create the action rule
Insert the following into your /etc/fail2ban/jail.local
[dovecot-pop3imap] enabled = true filter = dovecot-pop3imap action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp] sendmail-whois[name=dovecot-pop3imap, dest=you@your-server.domain.net, sender=fail2ban@your-server.domain.net] # where to send the alert email logpath = /usr/local/psa/var/log/maillog # Plesk maillog standard location maxretry = 5 findtime = 1200 bantime = 1200 |
Testing
Now you can restart Fail2Ban and test it with the following script. Replace the line "REPLACE.YOUR.SERVERS.IP" with your server's IP that is protected by Fail2Ban. Run the script several times, and on the 6th attempt, you should not be able to make additional connections. Run 'iptables -L -v -n' to ensure Fail2Ban properly blocked the IP.
echo -e "01 login test test\n02 logout\n" | telnet REPLACE.YOUR.SERVERS.IP 143 |
Have Fun!
Report Qmail Queue Size
I recently had a unique request from a customer. "How do I have my Plesk system email me when my remote queue starts to fill up?". This is actually quite simple to script.
QmailQueueChecker.sh
#!/bin/bash # QmailQueueChecker.sh # Checks the size of the Qmail queue and sends an email if its too large QUEUE_LIMIT="250" NOTIFY_EMAIL="root@localhost" QUEUE_COUNT=`/usr/sbin/qmHandle -s | grep "remote recipients" | awk -F ":" '{print $2}' | sed 's/ //g'` if [ "$QUEUE_COUNT" -gt "$QUEUE_LIMIT" ]; then echo "The Qmail queue is currently over $QUEUE_LIMIT. Mail queue contains $QUEUE_COUNT messages." | mail -s "Mailqueue is Full" $NOTIFY_EMAIL fi exit 0 |
See quite easy! Simply alter QUEUE_LIMIT and NOTIFY_EMAIL to suit your needs. I would recommend adding this to a cronjob for automated notifications:
0 * * * * /root/bin/QmailQueueChecker.sh
Compile latest XBMC with GIT
I've been running XBMC-Live for some time now, and I've found it great, however its quite a pain waiting for new features for the base XBMC install.. I love to run the latest versions of software. If your like this as well, or you simply want to compile XBMC yourself feel free to copy/paste this tutorial. For your own reference, most of this guide was pulled from
http://forum.xbmc.org/showthread.php?tid=89817
My Build is as follows:
Ubuntu 10.04.2 LTS lucid - XBMCLive Dharma
INITIAL SETUP
Step 1. (Stop XBMC, and install the stable PPA)
stop xbmc-live apt-get install python-software-properties pkg-config -y add-apt-repository ppa:team-iquik/xbmc-stable apt-get update |
Step 2. (Install dependencies)
apt-get install libplist-dev python-support python-dev ccache libyajl-dev libvdpau-dev debhelper \ zip git-core make g++ gcc gawk pmount libtool yasm nasm automake cmake gperf gettext unzip \ bison libsdl-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libfribidi-dev \ liblzo2-dev libfreetype6-dev libsqlite3-dev libogg-dev libasound-dev python-sqlite libglew-dev \ libcurl3 libcurl4-openssl-dev x11proto-xinerama-dev libxinerama-dev libxrandr-dev \ libxrender-dev libmad0-dev libogg-dev libvorbisenc2 libsmbclient-dev libmysqlclient-dev \ libpcre3-dev libdbus-1-dev libhal-dev libhal-storage-dev libjasper-dev libfontconfig-dev \ libbz2-dev libboost-dev libfaac-dev libenca-dev libxt-dev libxtst-dev libxmu-dev libpng-dev \ libjpeg-dev libpulse-dev mesa-utils libcdio-dev libsamplerate-dev libmms-dev libmpeg3-dev \ libfaad-dev libflac-dev libiso9660-dev libass-dev libssl-dev fp-compiler gdc \ libwavpack-dev libmpeg2-4-dev libmicrohttpd-dev libmodplug-dev libboost-thread-dev -y -q apt-get build-dep xbmc -y |
Step 3. (Clone XBMC from its GIT repo)
mkdir ~/setup cd $HOME/setup git clone git://github.com/xbmc/xbmc.git |
Step 4. (Compile XBMC)
# Compile BluRay support cd $HOME/setup/xbmc/lib/libbluray make make install # Compile Airplay support cd $HOME/setup/xbmc/lib/libshairport make make install cd $HOME/setup/xbmc make -C lib/libnfs && sudo make -C lib/libnfs install ./bootstrap ; ./configure --prefix=/usr --enable-vdpau --disable-pulse --disable-crystalhd --enable-libbluray --enable-libshairport ; make -j4 make -C lib/addons/script.module.pil |
Step 5. (Install our newly compiled XBMC)
make install prefix=/usr |
Step 6. (Start XBMC back up)
start xbmc-live |
Once we have our initial repo setup, its quite easy to update from now on. Simply follow the steps below:
UPDATE STEPS
Step 1. (Stop XBMC)
stop xbmc-live |
Step 2. (Cleanup existing XBMC code, and update it)
cd $HOME/setup/xbmc make distclean git reset --hard git clean -xfd git pull --rebase |
Step 3. (Compile XBMC)
# Compile BluRay support cd $HOME/setup/xbmc/lib/libbluray make make install # Compile Airplay support cd $HOME/setup/xbmc/lib/libshairport make make install make -C lib/libnfs && sudo make -C lib/libnfs install ./bootstrap ; ./configure --prefix=/usr --enable-vdpau --disable-pulse --disable-crystalhd --enable-libbluray --enable-libshairport ; make -j4 make -C $HOME/setup/xbmc/lib/addons/script.module.pil |
Step 4. (Install our newly compiled XBMC)
make install prefix=/usr |
Step 5. (Start XBMC back up)
start xbmc-live |
Fail2Ban on RHEL 5/6
I've decided to put together this little howto on installing and configuring Fail2Ban on RedHat Enterprise Linux v5.x and v6.x.
The first step is to make to decide whether you want to install via repository or by source. I recommend installing by repository as you will receive packages that are guaranteed to work with the OS, and will receive updates along with your regular packages.
Installing Via Repo
If you have not already done so you will want to install the epel repository, choose a repository according to your OS. I prefer to use the EPEL repository: http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/fail2ban.html
RHEL 5
32 BIT SYSTEMS: sudo rpm -Uvh "http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-5-4.noarch.rpm" 64 BIT SYSTEMS: sudo rpm -Uvh "http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-5-4.noarch.rpm" |
RHEL 6
32 BIT SYSTEMS: sudo rpm -Uvh "http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm" 64 BIT SYSTEMS: sudo rpm -Uvh "http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm" |
Now that we have the repository installed, we can install Fail2Ban.
sudo yum install fail2ban |
First copy your jail.conf to jail.local. This protects your changes from getting wiped during package upgrades. Fail2Ban is setup to read jail.local after jail.conf automatically. From here on, when I say configuration file, I am referring to the jail.local file.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local |
Next you can add any administrative IP addresses to Fail2Ban's white-list, space separated.
sudo vi /etc/fail2ban/jail.local |
[DEFAULT] ignoreip = 127.0.0.1 192.168.1.0/24 192.168.2.5 192.168.5.3 |
Now you will want to configure Fail2Ban to your liking, mainly white-lists and active jails.
I like to ban my attackers for a good long time, you can alter the default ban time of 10 minutes. This is done by modifying the bantime variable, this can also be overridden on a per-jail basis.
bantime = 86400 # this is a much longer ban, 24 hours |
SSH jail is active by default, so only small tweaks are needed. Simply make sure enabled is true, and logpath is pointing to /var/log/secure.
[ssh-iptables] enabled = true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] sendmail-whois[name=SSH, dest=root@localhost, sender=fail2ban@localhost] logpath = /var/log/secure maxretry = 3 |
I find enabling an email jail is also a good idea as SMTP services are a common target.
[postfix] enabled = true filter = postfix action = iptables[name=Postfix, port=smtp, protocol=tcp] sendmail-whois[name=Postfix, dest=root@localhost, sender=fail2ban@localhost] logpath = /var/log/maillog maxretry = 5 |
Now we can make sure Fail2Ban starts when our server reboots, do this by using chkconfig to enable.
chkconfig fail2ban on sudo /etc/init.d/fail2ban start |
Installing Via GitHub
This is my preferred method of installing Fail2Ban, as it gets the absolute latest copy, there are a couple of additional packages that you will need to install first.
Ensure Python is upto date. >=python-2.3
python -V
Python 2.6.5 |
Now if we don't already have the git package, go ahead and install that now
sudo yum -y install git |
Now create a dev directory that will house the Fail2Ban git repo.
cd ~ mkdir fail2ban-dev cd fail2ban-dev git clone https://github.com/fail2ban/fail2ban.git |
Now we can install Fail2Ban using root privileges.
cd fail2ban sudo python setup.py install |
Now we should have our Fail2Ban installation in /usr/share/fail2ban, the configuration in /etc/fail2ban/, and the binaries in /usr/bin.
We should now install the startup script for RHEL:
sudo cp ~/fail2ban-dev/fail2ban/files/redhat-initd /etc/init.d/fail2ban sudo chmod 755 /etc/init.d/fail2ban |
First copy your jail.conf to jail.local. This protects your changes from getting wiped during package upgrades. Fail2Ban is setup to read jail.local after jail.conf automatically.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local |
The configuration is going to be quite similar to above, simply ensure your logpath is correct and enabled is true.
To update our github installation, run git pull from the repo directory, keep in mind that the setup.py script will overwrite /etc/fail2ban/jail.conf , so if you didn't create a jail.local, as I previously showed, I would now.
cd ~/fail2ban-dev/fail2ban git pull -u sudo python setup.py install |
Plesk and Dr. Web
I'm going to cover two issues here with Dr. Web and Plesk. They are both "fixes" of sorts, the first fixes an annoyance the second fixes a bug in a recent update to Dr. Web.
How do I configure Dr. Web on Plesk not to send notifications about infected messages?
This is quite easy. Simply create/edit the following file:
/etc/drweb/drweb_qmail.conf
Insert into the drweb_qmail.conf file:
[VirusNotifications] SenderNotify = no AdminNotify = no RcptsNotify = no |
Restart Dr. Web, and the annoying emails should cease.
/etc/init.d/drwebd restart |
NOTE: If this solution does not work for you, try creating the following file with the above contents instead:
/etc/drweb/drweb_handler.conf
Email messages addressed to the mailboxes protected by Dr. Web on Plesk are bouncing back
If you are experiencing bouncebacks with the following error messages:
Antivirus filter report: --- Antivirus report --- Detailed report: 127.0.0.1 [1636] drweb.tmp.0Ugml7 - archive MAIL 127.0.0.1 [1636] drweb.tmp.0Ugml7/[text:plain] - Ok 127.0.0.1 [1636] drweb.tmp.0Ugml7/test.zip - archive ZIP 127.0.0.1 [1636] >drweb.tmp.0Ugml7/test.zip/test.txt - Ok 127.0.0.1 [1636] >drweb.tmp.0Ugml7/test.zip/ - read error! |
This could be due to a recent (15 Dec 2011) upgrade for Dr. Web which broke some outgoing mail.
To resolve this issue, Plesk has released a patch PLESK 9, PLESK 10
If the Plesk patch does not resolve your issue, try the following:
cd /var/drweb/bases sudo wget http://update.drweb.com/unix/500/update.drl sudo –u drweb /opt/drweb/update.pl vi /etc/drweb/drweb_handler.conf |
In this file, find and replace the current values for ScanningErrors, and ProcessingErrors to say pass.
ScanningErrors = pass ProcessingErrors = pass |
Restart Dr. Web, and emails should start to flow again.
/etc/init.d/drwebd restart |
Remove OpenBaseDir Restrictions From Sub-Domains in Plesk
Its quite common to have subdomains setup in Plesk, its also more common to want to use scripts in the subdomain contained in the primary site's httpdocs directory. Below is a guide on howto perform this.
Create /var/www/vhosts/domain.com/subdomains/sub.domain/conf/vhost.conf
with the following content: (of course replace domain.com and sub.domain with your domain name and subdomain name)
1 2 3 4 5 6 7 8 9 10 11 12 | <Directory /var/www/vhosts/domain.com/subdomains/sub.domain/httpdocs> <IfModule sapi_apache2.c> php_admin_flag engine on php_admin_flag safe_mode off php_admin_value open_basedir "/var/www/vhosts/domain.com/httpdocs:/var/www/vhosts/domain.com/subdomains/sub.domain/httpdocs:/tmp" </IfModule> <IfModule mod_php5.c> php_admin_flag engine on php_admin_flag safe_mode off php_admin_value open_basedir "/var/www/vhosts/domain.com/httpdocs:/var/www/vhosts/domain.com/subdomains/sub.domain/httpdocs:/tmp" </IfModule> </Directory> |
After you've created your vhost.conf file, you will want to force Plesk to re-read its configuration files, so run: (replace domain.tld with your chosen domain name)
/usr/local/psa/admin/sbin/websrvmng -u --vhost-name=domain.tld |
Now you can restart Apache to have the changes take effect
/etc/init.d/httpd restart |
Disabling email service for a specific domain in Plesk
I have encountered several scenarios in which you want a site hosted via Plesk however without email services on the Plesk box. You can use the following to disable email for a specific domain in Plesk.
1. Correct the DNS entry for MX records in the DNS manager
Go to 'Websites & Domain' then click on 'DNS'
2. SSH login to the server and disable the mail service associated with that domain, replacing domain.tld with the domain in question.
/usr/local/psa/bin/domain -u domain.tld -mail_service false |
You should see the following output:
SUCCESS: Update of domain ‘domain.tld’ complete.
That is the jist of it, you can verify that mail is being routed correctly by sending a test email via the commandline
echo "Test" | mail -s "route test" user@domain.tld |
You should see it routed properly in Plesk's maillog (/usr/local/psa/var/log/maillog)
Access horde webmail via IP instead of by domain
This is an interesting workaround that I recently discovered. Normally when you access horde webmail its done via domain name ex: https://domain.tld/webmail, however you may desire to access this via IP address instead, ex: https://192.168.1.101/horde (obviously you wouldn't use a 192 address as its private, but you get the idea).
cd /etc/httpd/conf.d vi zz012_horde.conf |
Paste the following into the zz012_horde.conf file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <Directory /usr/share/psa-horde> <IfModule sapi_apache2.c> php_admin_flag engine on php_admin_flag safe_mode off php_admin_value open_basedir “/etc/psa:/usr/share/psa-horde:/usr/share/psa-horde/config:/tmp” php_admin_value include_path “/usr/share/psa-horde/lib:/usr/share/psa-horde/pear:.” </IfModule> <IfModule mod_php5.c> php_admin_flag engine on php_admin_flag safe_mode off php_admin_value open_basedir “/etc/psa:/usr/share/psa-horde:/usr/share/psa-horde/config:/tmp” php_admin_value include_path “/usr/share/psa-horde/lib:/usr/share/psa-horde/pear:.” </IfModule> </Directory> Alias /horde /usr/share/psa-horde |
Then restart Apache to re-read the vhost configuration you just created.
/etc/init.d/httpd restart |
Handy Plesk One-liners
In my everyday work, I commonly log into as many as 20 Plesk boxes a day. Here are some of my more commonly used Plesk commands.
Retrieve FTP Passwords From PLESK's Database:
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'select sys_users.home,sys_users.login,accounts.password FROM sys_users,accounts WHERE sys_users.account_id=accounts.id ORDER BY home;' |
Retrieve Email Passwords From PLESK's Database:
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'select CONCAT(mail_name,"@",name) AS email_address,accounts.password FROM mail left JOIN domains on domains.id=mail.dom_id left JOIN accounts on accounts.id=mail.account_id;' |
Retrieve Email Passwords that are made up of only letters:
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'SELECT CONCAT_WS('@',mail.mail_name,domains.name),accounts.password FROM domains,mail,accounts WHERE domains.id=mail.dom_id AND accounts.id=mail.account_id AND accounts.password RLIKE BINARY '^[a-z]+$' ORDER BY domains.name ASC,mail.mail_name ASC;' |
Retrieve Email Passwords that are made up of only letters
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'SELECT CONCAT_WS('@',mail.mail_name,domains.name),accounts.password FROM domains,mail,accounts WHERE domains.id=mail.dom_id AND accounts.id=mail.account_id AND accounts.password RLIKE '^[0-9]+$' ORDER BY domains.name ASC,mail.mail_name ASC;' |
Retrieve domains that are using catch-all accounts:
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'SELECT d.name AS domains, p.value AS catchall_address FROM Parameters p, DomainServices ds, domains d WHERE d.id = ds.dom_id AND ds.parameters_id = p.id AND p.parameter = 'catch_addr' ORDER BY d.name;' |
Retrieve Database Passwords From PLESK's Database:
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e 'SELECT domains.name AS domain_name, data_bases.name AS database_name, db_users.login, accounts.password FROM data_bases, db_users, domains, accounts WHERE data_bases.dom_id = domains.id AND db_users.db_id = data_bases.id AND db_users.account_id = accounts.id ORDER BY domain_name;' |
Retrieve PLESK Admin Password (Plesk 9 and below)
cat /etc/psa/.psa.shadow |
Retrieve PLESK Admin Password (Plesk 10)
/usr/local/psa/bin/admin --show-password |
Retrieve Domain's exceeding Plesk's quotas
mysql psa -uadmin -p`cat /etc/psa/.psa.shadow` -e "SELECT domains.name, domains.real_size, Limits.value FROM domains, Limits WHERE domains.limits_id = Limits.id AND domains.real_size > Limits.value AND limit_name = 'disk_space' AND Limits.value != -1 ORDER BY domains.name ASC;" |
SkyNet
I've been working, not very long, on a small c++ project I've titled SkyNet. The purpose of this application is to provide a turn based multiplayer game management server. It handles unit placement, scores, turn order, TCP connections. I've written a small SQLite3 wrapper that the application makes us of, and it relies on the boost ASIO library for network operations. You can check it out here: https://github.com/kotori/SkyNet