How to setup a personal mail server with Postfix and Dovecot

May 21st, 2013 No comments

The instructions were tested on Fedora 17, most RedHat distributions should be very similar and it should at least give you an idea for other distros.

Install the required software:

# yum install postfix dovecot

Check that Postfix supports Dovecot SASL:

# postconf -a
cyrus
dovecot

Edit /etc/postfix/main.cf, add at the top of the file:

inet_interfaces = all
# list of domains receiving mails on this server, remember to set the MX record in their DNS
virtual_alias_domains = domain1.com, domain2.com
virtual_alias_maps = hash:/etc/postfix/virtual
mynetworks_style = host
# add the ips that are always allowed to relay to mynetworks list
mynetworks = 127.0.0.0/8
# use reject_rbl_client to specify RBLs (simple anti-spam measure)
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
reject_rbl_client sbl-xbl.spamhaus.org
reject_rbl_client bl.spamcop.net

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

Create/edit /etc/postfix/virtual and add a couple of email aliases:

john@domain1.com myaccount
office@domain1.com myaccount

Compile the aliases table:

# postmap /etc/postfix/virtual

Restart the postfix service, for minor changes in the configuration file you can also use:

# postfix reload

Uncomment the postfix smtp-auth settings in /etc/dovecot/conf.d/10-master.conf

# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
}

Edit /etc/dovecot/conf.d/10-mail.conf and set mail_location:

mail_location = mbox:~/mail:INBOX=/var/mail/%u

Restart dovecot.

This should be enough for a couple of email accounts for your domains, accessible by POP3 and IMAP.

Categories: Linux Tags: , , ,

The SimpleXML

March 27th, 2012 No comments

The SimpleXML extensions is intended to provide a “very simple and easily usable toolset”. This description lets you think that is simple to use but a more accurate description is that it lets you use it for for quick and simple cases. The basic example looks good:

$movies = new SimpleXMLElement($xmlstr);
 
/* For each <character> node, we echo a separate <name>. */
foreach ($movies->movie->characters->character as $character) {
   echo $character->name, ' played by ', $character->actor, PHP_EOL;
}

One little issue: $character->name is an object not a regular php string. As a result, you have to cast everywhere as if you use a static language:

if((string) $foo->bar == 'etc') {

or

str_etc((string)$xml->str);

There are also small differences on what functions are available or how they work, depending on what version of PHP you use.

In case of a slightly more complex xml (like some custom data feed) it is an usual approach to convert the xml object to nested array structure. http://php.net/manual/en/book.simplexml.php has a section of user contributed notes that is full of post regarding this action. There are two basic approaches:

$array = json_decode(json_encode($xml), TRUE);
...
// some cleanup if neeed

and some recursive parsing of the xml tree. Both methods kind of work if applied for the right problem. This shows that for the more than basic tasks SimpleXML becomes cumbersome, a nuisance to use.

The extension could be improved a bit to make it more usable but I think a lot of problems come from the nature of the XML format. Most data feed providers do not actually need or use the power/complexity of the XML format and could use a lighter more suitable format. Used data from providers that could easily use csv or json. It is easier to generate, parse, debug and use a lot less bandwidth & processing power all at the cost of sounding less “enterprise”.

Categories: Programming Tags: , ,

PHP foreach and references

September 26th, 2011 No comments

The foreach construct is an usual way to iterate over an array. Since PHP 5, you can also modify the array values using references. Here is one interesting side effect:

<?php
$a = range(1,5);
foreach($a as &$x) {
	$x++;
}
 
foreach($a as $x) {
	echo $x;
}

The output is 23455. This happens because the $x reference remains even after the foreach loop ends. The reference is destroyed if you unset $x after the loop.

This is not very well known. If you have the misfortune to maintain some scripts with a coding style involving little structure, lots of spaghetti code and nested includes than you might be very puzzled by the behavior of a regular foreach loop just because the iterating value was used previously as a reference.

Categories: Programming Tags: ,

Google AI Challenge

June 30th, 2011 No comments

Artificial inteligence(AI) is a complex branch of computer science involving a lot of research by private and academic entities. The Google AI Challenge brings bot writers around a simple and fun idea. The idea is to write a bot to play a strategy game against other bots.

In the next challenge the bots will play an Ants game where they control an ant colony fighting for resources against another colonies. The system is functional but in beta version. There is a set of APIs for most programming languages, a couple of tutorials and the source code for the system itself is available.

The University of Waterloo Computer Science Club is organizing the contest with Google as a sponsor. There are no listed prizes but for people with some spare time it will provide quite enough entertainment value. I hope to have a least a bit of spare time for this and play a bit with it.

Most information is on the forum and there is also a beta site.

Categories: Programming Tags:

Which package owns a file?

January 2nd, 2011 No comments

Sometimes you wonder which package installed a file. There is a simple way to do this on RPM based systems. Unfortunately, I tend to forget it so I will post it here.

# rpm -qf /usr/bin/od
coreutils-8.5-7.fc14.i686

… and to get more info about the package:

[root@iweb ~]# yum info coreutils
Loaded plugins: fastestmirror, presto
Loading mirror speeds from cached hostfile
 * fedora: fedora.mirror.iweb.ca
 * updates: mirror.cc.vt.edu
Installed Packages
Name        : coreutils
Arch        : i686
Version     : 8.5
Release     : 7.fc14
Size        : 12 M
Repo        : installed
From repo   : updates
Summary     : A set of basic GNU tools commonly used in shell scripts
URL         : http://www.gnu.org/software/coreutils/
License     : GPLv3+
Description : These are the GNU core utilities.  This package is the combination
            : of the old GNU fileutils, sh-utils, and textutils packages.
Categories: Linux Tags: ,

How to reset the MySQL root password

December 30th, 2010 No comments

The MySQL server root password is not used very often and you can forget it or you inherit some already setup system and you do not have the MySQL root password. Technically, there is no way to recover the password but you can reset it.

The main inconvenience is that you have to stop the database server twice. The following instructions were tested on a Fedora Linux distribution but the main idea can be used on different operating systems, including Windows.

The main idea is to restart the mysql server without security, change the root password and restart again in normal mode. I recommend not doing this on a live server but if you already need this than there is a big sign that your system design has some issues.

First, stop the mysql server:

# service mysqld stop

Start the server with an option that enables anyone to connect without password.

# mysqld_safe --skip-grant-tables &

Wait for the mysql server start, you will get some info about it:

101230 20:00:03 mysqld_safe Logging to '/var/log/mysql/error.log'.
101230 20:00:03 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql

Connect as root without the need for a password:

# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.52-log Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Let’s say that you want to use the password “NEWPASS”, in the mysql prompt type:

mysql> use mysql;
mysql> update user set password=PASSWORD("NEWPASS") where User='root';
mysql> flush privileges;
mysql> quit

Restart the mysql server to use the new password:

 # service mysqld restart 

Now you have your regular database server with a shiny new root password. Do not forget it!

Categories: Linux, Software Tags: ,

Intuitive Zoom with JScrollPane

September 2nd, 2010 2 comments

The problem: Display an image inside a panel and handle different zoom levels. The best approach is to use an already made component. If a component is not available or you just have to write it using only the basic Swing components than might help you save some time.

One approach is to hold a BufferedImage and the zoom level(integer, initial 100) and draw the image with appropriate settings in a JPanel. Overwrite the paintComponent function of a JPanel. Set the size of the panel to match the size of the zoomed image. Add this panel inside a JScrollPane and you have an initial version. Enable double buffering for the resulting panel to have a smooth appearance.

I prefer this approach instead of using a zoomed copy of the image as it saves a lot of memory.

The positions on the drawing panel match the positions on the zoomed image. The coordinates in the original image are calculated using a simple formula:

int imageX = panelX * 100/zoom;

If the zoomed image is smaller than the container than the image will be in the top right corner. Most users will want it in the center of the container. The solution is to wrap the drawing panel inside a centering panel. There a couple of solutions using a custom layout manager, a combination of Box layouts, SpringLayout, etc. A simple solution is the GridBagLayout:

JPanel centeringPanel = new JPanel(new GridBagLayout());
centeringPanel.add(drawingPanel, new GridBagConstraints());

This will center the drawing panel vertically and horizontally.

When changing the zoom, change the size of the drawing panel and call invalidate() and repaint() on the scroll pane view port. Now you have zoom in and zoom out.

You will notice a small problem. The zoom is not very intuitive, it will move the image to the top left corner. A more usable panel would zoom in/out preserving the view on the same area of the image. You need to calculate the new view position. There a couple of ways to do this I will present one of them:

// Save the previous coordinates
int oldZoom = zoom;
Rectangle oldView = scrollPane.getViewport().getViewRect();
// resize the panel for the new zoom
....
// calculate the new view position
Point newViewPos = new Point();
newViewPos.x = Math.max(0, (oldView.x + oldView.width / 2) * newZoom / oldZoom - oldView.width / 2);
newViewPos.y = Math.max(0, (oldView.y + oldView.height / 2) * newZoom / oldZoom - oldView.height / 2);
scrollPane.getViewport().setViewPosition(newViewPos);

You can add many usability improvements and optimizations but what I described here is an easy to implement and usable component that can be used in any application.

Categories: Programming Tags: , ,

Quick Fix for the Fedora DNSSEC Issue

June 26th, 2010 3 comments

After a routing update, Fedora 12 has some problems with the DNS service. The named service fails to start with with the following error:

Error in named configuration:
/etc/pki/dnssec-keys//named.dnssec.keys:1: open: /etc/pki/dnssec-keys//production/bg.conf: file not found

The update was not a fortunate one and an official fix will probably be issued soon. A quick way is to disable the DNSSEC options in named. Edit /etc/named.conf and comment the following lines:

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside . trust-anchor dlv.isc.org.;

and at the bottom:

include "/etc/pki/dnssec-keys//named.dnssec.keys";
include "/etc/pki/dnssec-keys//dlv/dlv.isc.org.conf";

The DNSSEC features ads digital signatures to your DNS queries. If you need this, keep searching for other solutions.

Categories: Linux Tags: , , ,

Simple Web Server

May 26th, 2010 No comments

If you need a very simple web server to transfer some files you can run:
python -m SimpleHTTPServer 80
and you will create a simple web server serving files from the current directory.

Categories: Linux Tags:

Strange ArchLinux Error

May 25th, 2010 No comments

Arch Linux is a lightweight and simple distribution as they claim on the website. I am interested in a rolling release system without the headaches of Gentoo. The first setup was strange, I have no problems with an ugly console GUI but the entire experience was counterintuitive.

On example that gave me some headaches was at “Configure System” step. There was a strange error “Failed to import current network settings into target system” and all configuration files were empty. It took me sometime to figure the cause and here is this post in case somebody else has this problem. There was an error downloading one of the packages (dhcpd) and the setup program just continued without a proper notification. To recover from this you have to go back to the “Install Packages” step (only the missing packages are downloaded) until everything is downloaded.

There were a lot of small things that added up and in the end too many headaches just for a basic setup. I will check it again in after some time passes and maybe it will get better.

Categories: Linux Tags: ,