Archive for November, 2008

apache and tomcat on debian

Sunday, November 23rd, 2008
this is a little manual to get a debian etch server with apache2 and tomcat5.5 running.

the software you need

for tomcat you need a jdk. the one from sun is easy to install and stable. because it is in non-free you need to change your /etc/apt/sources.list file. after that it should look about: deb http://ftp.ch.debian.org/debian/ etch main non-free deb http://security.debian.org/ etch/updates main contrib non-free it usually should only be necessary to add the non-free tags. after changing the file you need to update your package-index with: apt-get update we need apache2, jdk, tomcat5.5 and, for the connection between tomcat and apache, mod_jk. to install them: apt-get install apache2 sun-java5-jdk tomcat5.5 libapache2-mod-jk now you should have a “it works” page from apache with the url http://localhost the tomcat you may need to start /etc/init.d/tomcat5.5 start after that you should get a blank page with http://localhost:8180 the blank page because there are no webapps installed yet.

tomcat configuration

we need no fancy configuration stuff, no cluster, no tomcat manager, so we can reduce the whole /etc/tomcat5.5/server.xml config file to: <Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8180" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" /> <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" /> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> </Host> </Engine> </Service> </Server> you can also leave it like it was, it should make no difference. next we will set up an example application. for that we will set up a “virtual host” so we can connect with a domain name. for example we take the domain example.com. at first we create a directory named example.com in /var/www. we also set the owner of example.com to tomcat55 because tomcat needs to write to this directory to deploy war files. mkdir /var/www/example.com chown tomcat55 /var/www/example.com in the next step we will set up the virtual server in tomcat. in the /etc/tomcat5.5/server.xml file we need to add a Host element to the Engine element. the Host element should look like: <Host name="example.com" appBase="/var/www/example.com" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> </Host> after that we need to restart tomcat again /etc/init.d/tomcat5.5 restart to test this, we can deploy an example war file. there is one downloadble from an apache server. we just need to get in the exampl.com directory and download it with wget. we save it as ROOT.war because this creates a the root webapp, the webapp, which is reachable directly with no aditional context path: cd /www/var/example.com wget -O ROOT.war http://tomcat.apache.org/tomcat-5.5-doc/appdev/sample/sample.war after that we should be able to view the sample page with the url http://example.com:8180. but for that we need to let point the domain example.com to the proper server. to do that you need to add the line 192.168.1.100 example.com into the /etc/hosts file from the client where you are trying to connect to the server. the ip can be 127.0.0.1 when you are trying to connect from the server itself, otherwise it must be the ip of the server. the page of http://example.com:8180 should look like an example “hello world!” page.

configure apache

now tomcat is running but we only can access tomcat files trough port 8180. we sure want to access these pages trough the default http port: 80. this port is already in use by the apache server. for this we need mod_jk. this is a kind of a proxy which requests files for some defined url patterns from tomcat and sends them back to the client. for that we need ad first to add a virtual host to the apache config. create a file named example.com in /etc/apache2/sites-available: <VirtualHost *> ServerAdmin your@email.com DocumentRoot /var/www/example.com/ROOT ServerName example.com ErrorLog /var/log/apache2/example.com.error.log CustomLog /var/log/apache2/example.com.access.log combined <Directory /var/www/example.com/ROOT> Options Indexes </Directory> <LocationMatch "/(WEB-INF|META-INF)/"> Order allow,deny Deny from all </LocationMatch> </VirtualHost> to activate the virtual host create a symbolic link of example.com in /etc/apache2/sites-enabled: ln -s /etc/apache2/sites-available/example.com /etc/apache2/sites-enabled/example.com and restart apache /etc/init.d/apache2 restart after that go to the url http://example.com now you should see the same page as before with the port 8180. it is the same page but it is served by the apache server and not by tomcat. there are two links in this page, the one goes to a file called hello.jsp. this jsp page should be interpreted by tomcat but it isn’t. we see the sourcecode. the secand link, /hello is a servlet and it isn’t served by tomcat to. for that we have to add two rules to the example.com apache config: JkMount /hello ajp13_worker JkMount /*.jsp ajp13_worker now this two patterns, the path hello and all paths ending with .jsp ashould be forwarded to tomcat. but wee ned to setup mod_jk properly at first.

mod_jk to glue them together

ther is already an mod_jk configuration, but it’s like almost all config files much to complicated. the config file is/etc/libapache2-mod-jk/workers.properties and should roughly contain: worker.list=ajp13_worker worker.ajp13_worker.port=8009 worker.ajp13_worker.host=localhost worker.ajp13_worker.type=ajp13 now ajp_13 is properly configured. the module is loaded by apache2 but apache doesn’t know where the config file ist. for that we create a file called jk.conf in /etc/apache2/mods_available: JkWorkersFile /etc/libapache2-mod-jk/workers.properties JkShmFile /var/run/apache2/jk-runtime-status JkLogFile /var/log/apache2/mod_jk.log JkLogLevel info now we need a smbolic link to this file inside /etc/apache2/mods-enabled: ln -s /etc/apache2/mods-available/jk.conf /etc/apache2/mods-enabled/jk.conf then restart apache again and it should work.

clean up the mess

if it works you can clean up, document and harden the whole config. for example you should kick out the http connector in tomcat (port 8180). because we can connect trough apache we don’t need this connector anymore. each closed port on a server improves security a bit. there are many configurations to improve security and performance. it’s important to tweak them and adapt them to the servers needs. but thats your task. it might be that the config i used here is very poorly, concerning security and performance.

http basic authentication in java

Saturday, November 22nd, 2008
sometimes it’s necessary to access webservices or websites out of a java programm. if the server uses basic authentication you need to provide the username and password to the connection. because URLConnection doesn’t provide a simple method to set these you have to do it manually. http uses the Authentication header to transmit authentication informations. for basic authentication this header looks like: Authorization: Basic dXNlcjpwYXNzd29yZA== the string dXNlcjpwYXNzd29yZA== is the username and password, encoded as base 64. the unencoded string is user:login with java you can use the setRequestProperty method of a URLConnection to add the header: URLConnection uc = new URL("http://test.url").openConnection(); uc.setRequestProperty("Authorization", "Basic dXNlcjpwYXNzd29yZA=="); uc.connect(); instead of the dXNlcjpwYXNzd29yZA== string you need your own base64 encoded login and password. if it doesn’t change during runtime it’s best to preencode it and store it in a configfile. you can use an online base64 encoder to encode it.