sudo useradd james
Installing James as a service of CentOS
TweetPosted 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.
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
TweetPosted 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.
-
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
-
-
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.
-
Clone my GitHub repository named
derby-shutdown-bean
, build a jar and copy it to$JAMES_HOME/conf/lib
. it contains a bean namedDerbyShutdownSpringBean
which implementsDisposableBean
. 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
-
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
-
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 ofbeans
element because it makes invocation ofDerbyShutdownSpringBean#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"/>
-
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
More information
Tags: james
Customizing Roller's Gaurav theme
TweetPosted 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.
-
Download http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.map
-
Put
jquery.min.map
to $ROLLER_HOME/themes/gaurav/js -
Put
<resource path="js/jquery.min.map"/>
to theme.xml -
Reload roller
-
Change the theme of your weblog to custom theme using Gaurav
Other issues
I filed following issues that I found during customization and attached patches to solve.
Automating backup of Roller
TweetPosted 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
TweetPosted 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