Kohei Nozaki's blog 

Installing James as a service of CentOS


Posted on Thursday Feb 05, 2015 at 05:16PM in Technology


In previous posting, I set up James as a plain standalone application on OS X. this time I’m going to install James as a service on CentOS 6.6, and expose its SMTP, POP3 and IMAP ports to external network.

Create a user for James

The java process of James will run james user which added in this step.

sudo useradd james

Extract tarball

I’ll use james-server-app-3.0.0-beta5-SNAPSHOT-app.tar.gz which built in previous posting.

sudo tar zxvf james-server-app-3.0.0-beta5-SNAPSHOT-app.tar.gz -C /usr/local --no-same-owner
sudo chown -R james:james /usr/local/james-server-app-3.0.0-beta5-SNAPSHOT
sudo ln -s /usr/local/james-server-app-3.0.0-beta5-SNAPSHOT /usr/local/james

Change ports that James will listen

Add offset of 10000 to bind element in smtpserver.xml, pop3server.xml and imapserver.xml respectively as I did in previous posting.

Reduce heap size

Default maximum heap size of James is 512MB but it’s too large for me because I have only small amount of memory on the server so I reduced it to more smaller. this can be done with modifying the file $JAMES_HOME/conf/wrapper.conf as follows:

wrapper.java.maxmemory=256

Define user to startup script

In $JAMES_HOME/bin/james there’s a variable which defines the user to run the process of James. so set it to james as follows:

RUN_AS_USER=james

Register the startup script

sudo ln -s /usr/local/james/bin/james /etc/init.d
sudo chkconfig --add james
sudo chkconfig james on

Now we can control James with service command as follows:

sudo service james start
sudo service james stop

Also James will be launched / shutdown automatically at every boot/shutdown process of CentOS.

NOTE on some environment, following error may occur.

$ sudo service james start
Starting Apache James :: Server :: App...
/usr/local/james-server-app-3.0.0-beta5-SNAPSHOT/bin/james: /usr/local/james-server-app-3.0.0-beta5-SNAPSHOT/bin/./wrapper-linux-x86-32: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
$

According to this discussion, it related to the environment which used in build. then the problem should be fixed with issuing following command:

sudo yum install glibc.i686

Configure port forwarding

This makes SMTP, POP3 and IMAP ports to be forwarded to ports of James listening. this enables us to launch James process as a regular user owning process, not root process. here’s an example of /etc/sysconfig/iptables:

*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp --dport 25 -j DNAT --to-destination :10025
-A PREROUTING -i eth0 -p tcp --dport 110 -j DNAT --to-destination :10110
-A PREROUTING -i eth0 -p tcp --dport 143 -j DNAT --to-destination :10143
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 10025 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 10110 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 10143 -j ACCEPT
COMMIT

After update the /etc/sysconfig/iptables file, restart the iptables serivce as follows:

sudo service iptables restart

Remaining tasks such as registering shutdown hook of Derby, creating domains, users…​

NOTE: You should make James to use secured connection

Currently all of communication between the server and client is clear text so any data including credentials can be sniffed. I would try to configure James to use secured connection in another post later.


Setting up Apache James mail server


Posted on Wednesday Feb 04, 2015 at 11:04PM in Technology


I’m trying to setup the Apache James server. latest 3.0.0.beta4 looks obsolete so I’ll use latest version in SVN trunk. first I’m afraid about if it is abandonded because the last beta release was released on 2012, but there are some traffics in its mailing list and issue tracker. I think I would be able to contact with users or developers.

Checkout and build

First, checkout the code from trunk and build it.

UPDATE November 2015 According to http://www.mail-archive.com/server-user@james.apache.org/msg15244.html It looks like the SVN repository involved some changes so use the following instead:

svn checkout http://svn.apache.org/repos/asf/james/project/trunk james-trunk
cd james-trunk
mvn clean install -DskipTests=true
cd server/app
mvn clean package -Pwith-assembly

svn co http://svn.apache.org/repos/asf/james/server/trunk james-server
cd james-server; mvn clean install

UPDATE February 2016

Now the repository of James has been migrated to git, and build instruction has changed as well. I’ve succeeded to build the package with following procedure:

git clone http://git-wip-us.apache.org/repos/asf/james-project.git
cd james-project
mvn package -DskipTests=true -Pwith-assembly

Check official guide for latest info.

Then james-server-app-3.0.0-beta5-SNAPSHOT-app.tar.gz will be built in server/app/target. I’ll use this archive.

Configure and run

Initially James will try to listen ports of 25, 110 and 143 but it requires root privilege. I don’t want to run James process in root account so I changed the port which James will use. it can be achieved with custom configuration files named smtpserver.xml, popserver.xml and imapserver.xml in $JAMES_HOME/conf. we have to copy the configuration templates and modify to suit each use case.

cd conf
cp smtpserver-template.xml smtpserver.xml
cp pop3server-template.xml pop3server.xml
cp imapserver-template.xml imapserver.xml

First, I changed the value of bind element as follows which is placed inside smtpserver element in smtpserver.xml.

<bind>0.0.0.0:10025</bind>

For pop3server.xml I did the same as follows.

<bind>0.0.0.0:10110</bind>

imapserver.xml too.

<bind>0.0.0.0:10143</bind>

Then execute following command.

cd ../bin
./james start

Then you can test if James is up and running properly with command telnet localhost 10025 as follows. if you can’t connect to James check $JAMES_HOME/log/wrapper.log to find what the cause is.

$ telnet localhost 10025
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 kyle-no-MacBook.local JAMES SMTP Server Server (JAMES SMTP Server ) ready
QUIT
221 2.0.0 kyle-no-MacBook.local Service closing transmission channel
Connection closed by foreign host.

You can stop James as follows.

./james stop

Create an account and domain

I’ll create a domain my.localdomain and a user kyle who uses his password as mypassword.

./james-cli.sh -h localhost -p 9999 adddomain my.localdomain
./james-cli.sh -h localhost -p 9999 adduser kyle@my.localdomain mypassword

Test from Thunderbird

Now you can send and receive mails using James server.

  1. Configure mail account as follows:

    • Mail address: kyle@my.localdomain

    • Password: mypassword

    • Receiving server: protocol=IMAP, hostname=localhost, port=10143

    • Sending server: protocol=SMTP, hostname=localhost, port=10025

  2. Send a mail to kyle@my.localdomain

Add a shutdown hook which executes shutdown of Derby

By default, $JAMES_HOME/var/store/derby/db.lck file will be left undeleted after shutdown of James. it means that James doesn’t execute properly shutdown procedure of Derby. I guess it may cause data corruption of the Derby database. so I added shutdown hook so that Derby can execute properly shutdown at every shutdown of James.

  1. Clone my GitHub repository named derby-shutdown-bean, build a jar and copy it to $JAMES_HOME/conf/lib. it contains a bean named DerbyShutdownSpringBean which implements DisposableBean. it will be instantiated at the time of booting James, then it executes shutdown procedure of Derby at the time of shutdown of James.

    git clone https://github.com/lbtc-xxx/derby-shutdown-bean
    cd derby-shutdown-bean
    mvn clean package
    cp target/derby-shutdown-bean.jar ~/servers/james-server-app-3.0.0-beta5-SNAPSHOT/conf/lib
  2. Copy spring-server.xml to $JAMES_HOME/conf/META-INF/org/apache/james. that file is available at /container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml of source distribution.

    $ pwd
    /Users/kyle/servers/james-server-app-3.0.0-beta5-SNAPSHOT/conf
    $ mkdir -p META-INF/org/apache/james
    $ cp ~/src/james-server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml META-INF/org/apache/james
  3. Add following definition to $JAMES_HOME/conf/META-INF/org/apache/james/spring-server.xml. I think you should put that definition as the first children of beans element because it makes invocation of DerbyShutdownSpringBean#destroy() just before termination of the JVM. I suppose that if Derby was shutdown before stopping of other services of James, it may bring problem.

    <bean id="derbyShutdownSpringBean" class="org.nailedtothex.derby.DerbyShutdownSpringBean"/>
  4. Add following definition to $JAMES_HOME/conf/log4j.properties.

    log4j.logger.org.nailedtothex.derby=INFO, CONS, FILE

    Then you can check whether shutdown was successfully executed in $JAMES_HOME/log/james-server.log as follows:

    INFO  22:13:50,633 | org.nailedtothex.derby.DerbyShutdownSpringBean | Derby shutdown succeeded. SQLState=XJ015, message=Derby system shutdown.

Adjusting timeouts of Java Service Wrapper

James uses Java Service Wrapper to manage its JVM. if you have to run James on cheaper environment, consider adjusting following variables in $JAMES_HOME/conf/wrapper.conf to prevent unexpected emergency shutdown. it may cause data corruption of Embedded Derby server.

wrapper.jvm_exit.timeout=120
wrapper.startup.timeout=120
wrapper.shutdown.timeout=120
wrapper.ping.timeout=300

See following URLs for detail.

Remaining tasks or configurations

I would write more as another posting about more realistic topics that needed to use James as external server.

  • Disallowing mail relaying except connection from localhost

  • Checking whether the server is prohibited open relay

  • Using secure connection

  • Register as a daemon of Linux


Customizing Roller's Gaurav theme


Posted on Tuesday Feb 03, 2015 at 04:37PM in Technology


I started using Gaurav theme which is HTML5/CSS3 enabled responsive theme, introduced with Apache Roller 5.1. it enables us to use same HTML template for various browsing environment such as smartphones, tables and PC. it changes its layout to suit these different displays automatically. and I added some customization as my prefer.

For smartphones and tablets

I added following definition to the template standard_head to use of appropriate viewport and font size.

<meta name="viewport" content="width=device-width"/>

Also added some to style sheet:

/* to prevent narrower displaying in iPhone */
div.entryContent code {
    white-space: pre-wrap;
    word-wrap: break-word;
}

div.entryContent a {
    word-wrap: break-word;
}

Add tweet button and Twitter widget

Add following snippet to standard_head template.

<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

Add following snippet to _day template. I put it just after the title of an entry. don’t forget to put your account into data-via attribute.

<a href="https://twitter.com/share" class="twitter-share-button" data-url="$url.entry($entry.anchor)" data-text="$entry.title" data-via="[YOUR TWITTER ACCOUNT HERE]">Tweet</a>

I also added Timeline widget which can be created in Twitter website (user configuration page) to Weblog template.

Add Google Adsense

I added responsive units into standard_header, standard_footer and Weblog templates.

Recent entries

I added recent 20 entries listing to Weblog template as follows:

<div class="well">
	<h3>Recent entries</h3>
	#set($recent = $model.weblog.getRecentWeblogEntries(nil, 20))
	<ul>#foreach($recentEntry in $recent)
		  <li class="entryLink"><a href="$recentEntry.permalink">$recentEntry.title</a></li>
	#end</ul>
</div>

Recent comments

I added recent 10 comments listing to Weblog template as follows:

<div class="well">
	<h3>Recent comments</h3>
	#set($recent = $model.weblog.getRecentComments(10))
	<ul>#foreach($recentComment in $recent)
		  <li class="entryLink">
		  #if($utils.isNotEmpty($recentComment.url))
		  	<a href="$recentComment.url">$recentComment.name</a>
		  #else
		  	$recentComment.name
		  #end
		  on
		  <a href="$recentComment.weblogEntry.permalink">$recentComment.weblogEntry.title</a>
		  </li>
	#end</ul>
</div>

Calendar

Added following snippet in Weblog template to show Calendar:

<div class="well">
<h3>Archives</h3>
#showWeblogEntryCalendar($model.weblog "nil")
</div>

Also tweak its style:

table.hCalendarTable {
	width: 100%;
}

Using Web Font

I like to use Oswald font to headings so I added following to standard_head template.

<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Oswald"/>

Also added following to stylesheet:

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: Oswald,Helvetica,Arial,sans-serif !important;
}

Tweak other fonts

Added following to style sheet:

body {
	font-family: Georgia, Palatino, Verdana, Libertine, 'Palatino Linotype', 'Book Antiqua', 'Times New Roman', serif;
}

div.entryContent pre, div.entryContent code {
	font-family: Menlo,Inconsolata,Consolas,'Ubuntu Mono',monospace;
}

div.entryContent pre {
	font-size: 85%;
}

Minor tweaks

I added following element to inside head element of a template named TagsIndex which is missing custom.css.

<link rel="stylesheet" href='$url.page("custom.css")' />

Removed following element from _day template because I’m the only person who is writing the blog.

<p class="lead">by <span style="text-transform: capitalize;">$entry.creator.screenName</span></p>

About jquery.min.map

In some environments jQuery requests a file named jquery.min.map and Roller returns 404. someone said that it makes debug of jQuery easier. I think there’s no side effect for regular use but following procedure would resolve the issue. note that you have to do this before copying initial template.

  1. Download http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.map

  2. Put jquery.min.map to $ROLLER_HOME/themes/gaurav/js

  3. Put <resource path="js/jquery.min.map"/> to theme.xml

  4. Reload roller

  5. Change the theme of your weblog to custom theme using Gaurav


Automating backup of Roller


Posted on Sunday Feb 01, 2015 at 11:17AM in Technology


I wrote an another Ant script to backup Apache Roller database and data directory. intended to use for PostgreSQL and Linux server. see my GitHub repository for more information.

At first I implemented it with sshexec task and used its output attribute to download the backup stream to local file but the file was corrupted. unfortunately sshexec task uses ByteArrayOutputStream to collect the output stream, then converts the byte array to String as far as I found out. I think it’s not preferable and it can be simply redirected to local file stream. so I changed implementation to that dump the data as a temporary file on remote server, then download it with scp task. I know it’s inefficient and consumes free space the same as the data. implementing redirection of the streams to sshexec task or changing the script to use ssh command directly would be a solution.


Automating daily cold backup of a virtual machine


Posted on Saturday Jan 31, 2015 at 01:24PM in Technology


I have a virtual machine which is running on VMware Fusion 6, and runs some batch jobs for every weekday. I wrote a backup script for it. it does some annoying work such as mounting, un-mounting and stopping or restarting the vm then simply copies .vmware directory into mounted directory. also purging function is available. see my GitHub repository for detail.

First, I wrote the script with tmutil which manipulates Time Machine via CLI, but it excludes virtual machines while exclusion list is empty so I stopped use it. so the script simply copies with copy task of Ant instead.

As to snapshot - I exclude it from the options because it’s not recommended for production use by VMware (VMware does not recommend running production virtual machines off snapshots on a permanent basis). additionally, they said that AutoProtect should only be used in testing environments. see http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1014509