Entries from July 2008 ↓

pleskbackup – Unable to parse options

If you are trying to backup your server to a ftp location don’t forget to specify destination file on the remote server, or you’ll receive this error:

[root@apollo ~]# export FTP_PASSWORD="secret"
[root@apollo ~]# /usr/local/psa/bin/pleskbackup --no-gzip all --skip-logs ftp://backup:@backup.example.com/
Unable to parse options: Bad FTP file format at /usr/local/psa/bin/pleskbackup line 287.

Plesk – How to debug spam problems

Today I’ve received an alert from the monitoring system, the mails count from server’s queue was too high.

Depending on the numbers of the clients hosted on the server more than 500 of mails lasting more than half hour in the queue is meaning that someone has sent a newsletter or spam.

Let’s ssh there and study the problem. Firstly we should look at the server’s queue:

[root@ulise ~]# /var/qmail/bin/qmail-qstat 
messages in queue: 758
messages in queue but not yet preprocessed: 0

We do have 758 mails in the queue. Let’s examine the queue with qmail-qread. Seeing a bunch of strange email addresses in the recipient list usually it’s meaning spam.

[root@ulise ~]# /var/qmail/bin/qmail-qread
[...]

You can examine the email content of the emails in the queue using Plesk interface or just less command. Firstly we should find message’s id using qmail-qread, then find the file holding the email in /var/qmail/queue with find command.

[root@ulise ~]# /var/qmail/bin/qmail-qread
[...]
18 Jul 2008 02:01:11 GMT  #22094026  1552  <> 
        remote  user@yahoo.com
[...]
 
[root@ulise ~]# find /var/qmail/queue/ -name 22094026
/var/qmail/queue/mess/19/22094026
/var/qmail/queue/remote/19/22094026
/var/qmail/queue/info/19/22094026
 
[root@ulise ~]# less /var/qmail/queue/mess/19/22094026
Received: (qmail 10728 invoked from network); 22 Jul 2008 19:40:46 +0300
Received: from unknown (HELO User) (86.107.221.138)
  by domain.com with SMTP; 22 Jul 2008 19:40:46 +0300
Reply-To: <support@PayPal.Inc.com>
From: "PayPal"<support@PayPal.Inc.com>
Subject: Dispute Transaction
Date: Tue, 22 Jul 2008 19:40:52 +0300
MIME-Version: 1.0
Content-Type: text/html;
        charset="Windows-1251"
Content-Transfer-Encoding: 7bit
X-Priority: 1
X-MSMail-Priority: High
X-Mailer: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
[...]

Oops, we do have some spam in the queue that’s received from the network (IP: 86.107.221.138). We should remove spam from the queue or the server IP address will finish listed in the RBLs, qmail-remove is the right tool for this job.

Check the number of the spams with the spam pattern (”PayPal.Inc.com” in this case):

[root@ulise ~]# qmail-remove -p 'PayPal.Inc.com'

Now, remove spams (notice the ‘-r’ switch), they all will end up in the /var/qmail/queue/yanked directory. Don’t forget to stop qmail daemon before (/etc/init.d/qmail stop) :

[root@ulise ~]# qmail-remove -r -p 'PayPal.Inc.com'

In a few minutes we do have more emails with the same patterns from the same ip address. That’s great, we do have opportunity to examine smtp traffic from the spammer’s ip address. Run tcpdump and wait a few minutes.

[root@ulise ~]# tcpdump -i eth0 -n src 86.107.221.138 \or dst 86.107.221.138 -w smtp.tcpdump -s 2048

Examining log file with less or wireshark we found that spammer is sending spam using LOGIN authentication:

220 ulise.domain.com ESMTP
ehlo User
250-ulise.domain.com
250-AUTH=LOGIN CRAM-MD5 PLAIN
250-AUTH LOGIN CRAM-MD5 PLAIN
250-STARTTLS
250-PIPELINING
250 8BITMIME
AUTH LOGIN
334 VXNlcm5hbWU6
dGVzdA==
334 UGFzc3dvcmQ6
MTIzNDU=
235 go ahead

Interesting, let’s decode the user/pass to see which account is used:

[root@ulise ~]# perl -MMIME::Base64 -e 'print decode_base64("dGVzdA==")'
test
[root@ulise ~]# perl -MMIME::Base64 -e 'print decode_base64("MTIzNDU=")'
12345

So, someone created a test account with a weak password and someone else guessed it and is sending spam through the server.

Let’s find the domain owning of the mailbox:

[root@ulise ~]# mysql -uadmin -p`cat /etc/psa/.psa.shadow` psa 
[...]
mysql> SELECT m.mail_name, d.name, a.password FROM mail AS m LEFT JOIN (domains AS d, accounts AS a) ON (m.dom_id = d.id AND m.account_id = a.id) WHERE m.mail_name='test' AND a.password='12345';
+-----------+------------+----------+
| mail_name | name       | password |
+-----------+------------+----------+
| test      | example.com | 12345    | 
+-----------+------------+----------+
1 row in set (0.01 sec)

Next step is to delete test mailbox and send a warning to client.

To improve your server’s security you’ll need to enable:
Server -> Mail -> Check the passwords for mailboxes in the dictionary

Creating a mailbox “test” with password “12345″ is a stupid thing and spammers just love to exploit it.

Plesk 8.3.0 extract files from backup

Extracting files from a Plesk 8.3 backup it’s not an easy task and it’s time consuming.

Let’s examine backup file:

[root@monster ~]# file plesk_bigserver_2008-07-10.backup 
plesk_bigserver_2008-07-10.backup: ASCII English text, with very long lines

Plesk backup is a multi-part mime-encoded file, you can easy restore one domain or whole server using plesk backup utilities, but when you need a few files from backup you’ll need an external tool like ripemime or mpack.

Requirements:

  • Free disk space minimum 2*backup_file_size
  • mpack tool

Check your free space using df(disk free) command.

[root@monster ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda3             9.2G  2.5G  6.3G  29% /
/dev/hda1             190M   15M  166M   8% /boot
none                 1010M     0 1010M   0% /dev/shm
/dev/hda7              53G   17G   34G  34% /home
/dev/hda6             950M   17M  886M   2% /tmp
/dev/hda5              46G  7.2G   37G  17% /var

Let’s install mpack. On a Redhat/Fedora/CentOS system it’s easy, just subscribe to Dag Wieers’s repository. You’ll need to download rpmforge-release rpm that’s matching your server OS and architecture:

For CentOS 5 and x86_64 architecture we’ll use rpmforge-release-0.3.6-1.el5.rf.i386.rpm:

[root@monster tmp]# wget http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
[...]
[root@monster tmp]# rpm -ivh rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
[...]
[root@monster tmp]# yum install mpack
[...]

Let’s make a directory where we’ll extract backup files and then extract files there:

[root@monster ~]# mkdir recover
[root@monster ~]# cd recover
[root@monster ~]#  munpack < ../plesk_bigserver_2008-07-15.backup
[...]

Mpack will extract files into separate tar archives where you can locate the domain by archive name and extract files using tar command.

Redirect to www.domain.com with Nginx

Depending on your requirements you’ll need to redirect your users from domain.com to www.domain.com with a permanent redirect in order to improve your site SEO ranking. We already know how to do it with apache and mod_rewrite, but how do you make it in nginx ? It’s not too hard.

Apache configuration:

#.htaccess
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.domain\.com
RewriteRule (.*) http://www.domain.com$1 [R=301,L]

Nginx configuration:

# /etc/nginx/nginx.conf
if ($http_host !~ "^www\.domain\.com$") {
    rewrite  ^(.*)    http://www.domain.com$1 permanent;
}

Spawning FastCGI php process with custom php.ini file

You can specify custom php.ini file with spawn-fcgi using this format:

/usr/bin/spawn-fcgi [options] -- /usr/bin/php-cgi \
  -c /etc/php-fastcgi.ini

Install RubyGems on CentOS 4

This post will explain how to install RubyGems 1.2 on the server running CentOS 4.

Following instructions from the install section of the RubyGems User Guide:

http://www.rubygems.org/read/chapter/3

[root@monster tmp]# yum -y install ruby ruby-devel irb
...
[root@monster tmp]# wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
...
[root@monster tmp]# tar xvfzp rubygems-1.2.0.tgz
...
[root@monster tmp]# cd rubygems-1.2.0
[root@monster rubygems-1.2.0]# ruby setup.rb 
Expected Ruby version > 1.8.3, was 1.8.1

Oops, we’ll need a newer version of ruby, by default CentOS 4 comes with ruby 1.8.1 . To install a newer version of ruby we’ll subscribe to testing repository from CentOS. To do this we’ll create a repo file called CentOS-Testing.repo in /etc/yum.repos.d directory:

CentOS-Testing.repo content

# /etc/yum.repos.d/CentOS-Testing.repo
# packages in testing repository
[testing]
name=CentOS-$releasever - Testing
baseurl=http://dev.centos.org/centos/$releasever/testing/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://dev.centos.org/centos/RPM-GPG-KEY-CentOS-testing

Note the line with enabled=0, we’ll enable the repository only when needed. Install ruby from the testing repository:

[root@monster ~]# yum --enablerepo=testing install ruby ruby-devel ruby-libs ruby-irb ruby-rdoc 
Loading "fastestmirror" plugin
Setting up Install Process
Setting up repositories
Loading mirror speeds from cached hostfile
Reading repository metadata in from local files
Parsing package install arguments
Resolving Dependencies
...
Dependencies Resolved
 
=============================================================================
 Package                 Arch       Version          Repository        Size 
=============================================================================
Installing:
 ruby-irb                i386       1.8.5-5.el4.centos.1  testing            67 k
 ruby-rdoc               i386       1.8.5-5.el4.centos.1  testing           132 k
Updating:
 ruby                    i386       1.8.5-5.el4.centos.1  testing           272 k
 ruby-devel              i386       1.8.5-5.el4.centos.1  testing           503 k
 ruby-libs               i386       1.8.5-5.el4.centos.1  testing           1.5 M
 
Transaction Summary
=============================================================================
Install      2 Package(s)         
Update       3 Package(s)         
Remove       0 Package(s)         
Total download size: 2.5 M
Is this ok [y/N]: y
Downloading Packages:
(1/5): ruby-rdoc-1.8.5-5. 100% |=========================| 132 kB    00:02     
(2/5): ruby-libs-1.8.5-5. 100% |=========================| 1.5 MB    00:14     
(3/5): ruby-devel-1.8.5-5 100% |=========================| 503 kB    00:04     
(4/5): ruby-1.8.5-5.el4.c 100% |=========================| 272 kB    00:03     
(5/5): ruby-irb-1.8.5-5.e 100% |=========================|  67 kB    00:01     
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating  : ruby-libs                    ######################### [1/9] 
  Updating  : ruby                         ######################### [2/9] 
  Installing: ruby-irb                     ######################### [3/9] 
  Installing: ruby-rdoc                    ######################### [4/9] 
  Updating  : ruby-devel                   ######################### [5/9] 
  Cleanup   : ruby-libs                    ######################### [6/9]
  Cleanup   : ruby-devel                   ######################### [7/9]
  Cleanup   : ruby                         ######################### [8/9]
  Removing  : irb                          ######################### [9/9]
 
Installed: ruby-irb.i386 0:1.8.5-5.el4.centos.1 ruby-rdoc.i386 0:1.8.5-5.el4.centos.1
Updated: ruby.i386 0:1.8.5-5.el4.centos.1 ruby-devel.i386 0:1.8.5-5.el4.centos.1 ruby-libs.i386 0:1.8.5-5.el4.centos.1
Complete!

Now it’s better, we do have ruby 1.8.5 installed on the system. Let’s return to RubyGems install:

[root@monster rubygems-1.2.0]# ruby setup.rb
...
------------------------------------------------------------------------------
 
RubyGems installed the following executables:
        /usr/bin/gem
 
If `gem` was installed by a previous RubyGems installation, you may need
to remove it by hand.

Voila! We have installed RubyGems 1.2 on the CentOS 4 server.