Steelmon's tech stuff

Setting up a strict whitelist proxy server using Squid

Posted in Howto, Linux, Proxy, Security by steelmon on November 22, 2009

Squid is an open source proxy server that comes pre installed with many linux distributions. The software can be used for a lot of neat stuff, but I came across a situation where I wanted to be able to lock down access to the whole web except for a few approved sites – kind of an information kiosk scenario.

Assumptions

I am using Ubuntu Server 9.04, which comes with Squid installed already. Apparently it is not automatically installed with Ubuntu Desktop, but it is available in the repositories and as such can be installed quite easily by:

sudo apt-get install squid

Configuration

Once you’re set with a standard installation, edit /etc/squid/squid.conf and locate the line starting with INSERT YOUR OWN... Now, add the following lines:

acl whitelist dstdomain "/etc/squid/whitelist.txt"
http_access allow whitelist

You may want to comment out the line http_access allow localhost if you want the same rules to apply for localhost as well.

You can now edit /etc/squid/whitelist.txt and add domains using the following pattern:

  • example.com will add that domain
  • .example.com will add example.com and all subdomains.

It seems possible to be a lot more sophisticated with regular expressions and stuff, but this was good enough for me.

Reload the squid configuration:

/etc/init.d/squid/reload

Error pages are located in /usr/share/squid/errors and can be customized.

Finally, you’ll need to configure your browser to use the proxy server. If you are running Firefox, follow these steps:

  • From the Firefox menu, Choose Edit > Preferences. Click “Advanced” and then “Network”
  • Click “Settings” and select the “Manual Proxy Configuration” radio button.
  • In the “HTTP Proxy” field enter the name or IP address of the machine running your proxy.
  • In the “Port” field enter the value 3128 and check “Use this proxy server for all protocols”.

Your should now be able to visit only the sites registered in the whitelist.

References

Setting up CAS on Tomcat with Apache2 and SSL on Ubuntu – part 4

Posted in CAS, Howto, Linux, Security, Tomcat by steelmon on October 23, 2009

A common scenario when providing services via the web is to expose all applications via an Apache front end. The Apache server acts as a dispatcher, or reverse proxy, and takes care of virtual hosting as well as any SSL traffic. This way, only one IP address needs to be exposed to the Internet while users gets the experience of multiple stand-alone sites. This article series also describes how applications can be conveniently put behind access control using the Central Authentication Service, or CAS for short.

Part 4 – Protecting resources with CAS

This article is number four in a series. The steps described here are based on configurations that have been performed in the earlier steps. It is strongly recommended to read these first:

We’ll start by downloading and deploying CAS. The CAS server is found at http://www.ja-sig.org/downloads/cas/cas-server-3.3.4-release.tar.gz. While we’re at it, we are going to download the CAS client as well: http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.tar.gz

Extract the server and client to a suitable location, e.g. your desktop. From the extracted server directory copy modules/cas-server-webapp-3.3.4.war to Tomcats webapps/ directory (if you are following all steps in this guide it should be located in /opt/apache-tomcat-5.5.28/webapps). Start Tomcat and point the web browser to http://localhost:8080/cas-server-webapp-3.3.4/login.

You should now see the CAS login page where you can enter your username and password. By default, you should be able to log in by entering password in both the user name and password fields. If everything is working, a page stating that you have logged in successfully, should be displayed.

Now, we need to configure Tomcat to use CAS for authentication. In this setup we will be looking at CAS-enabling the Tomcat Manager application (there is a link to the Manager application under the Administration headline in the top left corner of Tomcat’s welcome page). If you try to access it at this stage, you will just be asked to log in using a basic auth scheme.

Locate the web.xml descriptor for the manager web application found in the /opt/apache-tomcat-5.5.28/server/webapps/manager/WEB-INF. Now we will remove the container authentication and security configuration and replace it with CAS and a simple authorization filter. To be on the safe side, make a backup copy in case you mess things up and want to start over:

cp web.xml web.xml.bk

Open the web.xml file and locate the following line, about two thirds into the file:

<!-- Define reference to the user database for looking up roles -->

Remove everything from there to the end of the configuration file, leaving just the closing line:

</web-app>

Scroll back to the top of the configuration, and insert the following, just after the closing </description< tag, about ten lines from the top:

  <filter>
    <filter-name>CASFilter</filter-name>
    <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
    <init-param>
        <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
	<param-value>https://one.example.com/cas-server-webapp-3.3.4/login</param-value>
    </init-param>
    <init-param>
        <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
        <param-value>https://one.example.com/cas-server-webapp-3.3.4/serviceValidate</param-value>
    </init-param>
    <init-param>
        <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
        <param-value>one.example.com:443</param-value>
    </init-param>
  </filter>

  <filter>
    <filter-name>Authz Filter</filter-name>
    <filter-class>edu.yale.its.tp.cas.client.filter.SimpleCASAuthorizationFilter</filter-class>
    <init-param>
        <param-name>edu.yale.its.tp.cas.client.filter.authorizedUsers</param-name>
        <param-value>password</param-value>
    </init-param>
  </filter>

  <filter-mapping>
      <filter-name>CASFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter-mapping>
      <filter-name>Authz Filter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

What the above configuration says is that a servlet filter, CASFilter will intercept all requests to the application and check that the user is authenticated by CAS. If not, the user will be redirected to the CAS log in page. In the same way, the servlet filter Authz Filter will make sure that the user is authorized. The authorization is extremely simple in this example – it just checks that the user name is in the list specified in the filter parameter edu.yale.its.tp.cas.client.filter.authorizedUsers. The authentication filter (CASFilter) parameters might benefit from some more explanation:

  • edu.yale.its.tp.cas.client.filter.loginUrl points to the URL where users are redirected in case they are not already authenticated
  • edu.yale.its.tp.cas.client.filter.validateUrl points to the URL of the web service that provides the validation service. This URL needs to start with HTTPS – otherwise an exception will be thrown. Since we are using Apache2 as a front end to take care of all SSL handling, we point to an address that is managed by Apache (i.e. port 443). We will have to trust the SSL certificate of Apache, as will be shown shortly.
  • edu.yale.its.tp.cas.client.filter.serverName points to the server name (and port) to which the user gets redirected to after a successful login.

In order for the Tomcat Manager application to be able to communicate with CAS (through the just defined servlet filter), we need to add the CAS client jar file. Provided you extracted the client archive to the desktop, copy the file ~/Desktop/cas-client-java-2.1.1/dist/casclient.jar to the Tomcat managers lib directory:

cp ~/Desktop/cas-client-java-2.1.1/dist/casclient.jar /opt/apache-tomcat-5.5.28/server/webapps/manager/WEB-INF/lib

If you are using a commercial certificate for your Apache2 web server (i.e. a certificate that has been signed by a root CA certificate found in the JVM trust store), you are done. Since this example is based on using a self signed certificate, we need to add our certificate to the trust store manually. The reason for this is that the CAS servlet filter utilizes HTTPS, and that Java (rightfully) refuses to establish a connection if it can not verify that the identity of the remote side is valid.

To import the Apache2 certificate into the trust store, start by converting it into DER format:

cd /etc/apache2/ssl
sudo openssl x509 -in apache.pem -out apache.crt -outform DER

Now, import the DER certificate into the JVM trust store:

keytool -import -trustcacerts -keystore /usr/lib/jvm/java-6-sun/jre/lib/security/cacerts -storepass changeit -alias apache -file /etc/apache2/ssl/apache.crt

Restart Tomcat and enjoy the CAS-enabled Tomcat Manager!

References

http://www.ja-sig.org/wiki/display/CAS/CASifying+Tomcat+Manager

Setting up CAS on Tomcat with Apache2 and SSL on Ubuntu – part 3

Posted in Apache, Howto, Linux, Tomcat by steelmon on October 22, 2009

A common scenario when providing services via the web is to expose all applications via an Apache front end. The Apache server acts as a dispatcher, or reverse proxy, and takes care of virtual hosting as well as any SSL traffic. This way, only one IP address needs to be exposed to the Internet while users gets the experience of multiple stand-alone sites. This article series also describes how applications can be conveniently put behind access control using the Central Authentication Service, or CAS for short.

Part 3 – Adding Tomcat behind an Apache2 reverse proxy

This article is the third in a series. The steps described here are based on configurations that has been performed in the earlier steps. It is strongly recommended to read these first:

Before starting any configuration, we need to make sure that the required components are installed. We need to have a working Java installation and Apache Tomcat. I have been using Java 1.6 and Tomcat 5.5, but it should probably work with later versions as well. Start by installing Java:

sudo apt-get install sun-java6-jdk

Tomcat is downloaded from the Apache web site. Choose the core package and extract it to /opt, or another place of your choice. You may even want to put Tomcat onto a separate server (on which you’ll need Java installed as well).

Now, you should be able to start Tomcat by running:

/opt/apache-tomcat-5.5.28/bin/startup.sh

If you get an error message stating that the JAVA_HOME variable is not set, you can add the following line to the file /etc/environment:

JAVA_HOME=/usr/lib/jvm/java-6-sun/

This will set the JAVA_HOME environment variable globally for all users. In order to read it into memory without rebooting, run the following command:

source /etc/environment
export JAVA_HOME

Direct your browser to http://localhost:8080 and make sure you reach the Tomcat welcome page.

Now that tomcat is up and running, we want to enable Apache2 to serve as a front end, taking care of virtual hosting and SSL acceleration. One could argue that any Tomcat installation using SSL benefits from having an Apache front end that handles SSL encryption and decryption in native code.

The preferred way of connecting Apache2 with Tomcat is by using the AJP protocol provided by the mod_jk Apache module. This requires a couple of configurations. We’ll start by installing the required Apache2 module:

sudo apt-get install libapache2-mod-jk

Next, we need to create the file /etc/apache2/conf.d/tomcat. By putting it in the conf.d directory it is automatically included into the Apache2 configuration:

# mod_jk config
# Where to find workers.properties
JkWorkersFile /etc/apache2/workers.properties
#
# Where to put jk logs
JkLogFile /var/log/apache2/jk.log
#
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
#
#JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
#
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"

Next, create the file /etc/apache2/ workers.properties

#
# This file provides minimal jk configuration properties needed to
# connect to Tomcat.
#
# We define a worker named ‘default’
ps=/
workers.java_home=/usr/lib/jvm/java-1.5.0-sun/
worker.list=default
worker.default.port=8009
worker.default.host=localhost
worker.default.type=ajp13
worker.default.lbfactor=1

Edit the virtual host configuration /etc/apace2/sites-enabled/one.example.com-http and add the following just above the line starting with DocumentRoot:

JkMount /* default
JkMount /*.jsp default
DirectoryIndex index.jsp index.html
# Globally deny access to the WEB-INF directory
<LocationMatch ‘.*WEB-INF.*’>
deny from all
</LocationMatch>

Repeat the above with the HTTPS virtual host configuration /etc/apace2/sites-enabled/one.example.com-ssl.

Restart the Apache2 web server:

sudo /etc/init.d/apache2 restart

Now, you should be able to visit the Tomcat start page by directing the browser to either http://one.example.com or https://one.example.com.

Next Step

The next step is to get CAS up and running

References

http://blog.beplacid.net/2007/11/20/howto-apache-2-tomcat-5525-and-mod_jk-under-debian/

Setting up CAS on Tomcat with Apache2 and SSL on Ubuntu – part 2

Posted in Apache, Howto, Linux, SSL, Security by steelmon on October 22, 2009

A common scenario when providing services via the web is to expose all applications via an Apache front end. The Apache server acts as a dispatcher, or reverse proxy, and takes care of virtual hosting as well as any SSL traffic. This way, only one IP address needs to be exposed to the Internet while users gets the experience of multiple stand-alone sites. This article series also describes how applications can be conveniently put behind access control using the Central Authentication Service, or CAS for short.

Part 2 – Adding SSL support to Apache2 virtual hosts

In this part of the article series we are going to set up Apache2 so that it is possible to access it through SSL. The Apache2 configuration we are working on is described in this previous post.

Note that there is a limitation as to how you can configure virtual hosts on HTTPS. Remember that traffic is encrypted when it arrives to the web server. This includes the actual host name in the request URL as well. Thus it is impossible for Apache to know which security certificate to use in order to decrypt the request. There is however something called wildcard certificates – these can be used for domain patterns like *.example.com. If we are using a wildcard certificate, i.e. always the same certificate, we can host an arbitrary number of virtual hosts under the domain, and they will all use the same certificate.

Now, let’s get started. The first thing to do is to make sure Apache2 has the necessary module for serving HTTPS traffic:

sudo a2enmod ssl

Next, we need to set up the key and certificate to use for our virtual hosts. This can either be done by purchasing a commercial certificate, or by creating a self-signed certificate. In this article we are going to create a self-signed certificate. This means that anyone accessing our site will get a warning that the root certificate is not trusted, but otherwise it is identical to a commercial certificate. Set up the self-signed certificate by issuing the following commands:

sudo mkdir /etc/apache2/ssl
sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem
sudo chmod a+r /etc/apache2/ssl/apache.pem

When you issue the second command above, you will be asked for the certificate identity. At this point enter *.example.com. The asterisk (*) indicates that it is a wildcard certificate that maps to any URL where the host part ends with example.com

Now we are all set to setup a couple of virtual hosts that will respond to HTTPS requests. Like discussed in the previous post, this is done by adding configuration files into the /etc/apache2/sites-available directory. Start with the file /etc/apache2/sites-available/one.example.com-ssl:

#
# Virtual host (HTTPS)
# one.example.com (/var/www/one.example.com)
#
<VirtualHost *:443>
ServerAdmin webmaster@one.example.com
ServerName one.example.com:443
#
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
#
# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /var/www/one.example.com/htdocs
#
# Logfiles
ErrorLog /var/www/one.example.com/logs/error.log
CustomLog /var/www/one.example.com/logs/access.log combined
</VirtualHost>

Continue with the second host, /etc/apache2/sites-available/two.example.com-ssl:

#
# Virtual host (HTTPS)
# two.example.com (/var/www/two.example.com)
#
<VirtualHost *:443>
ServerAdmin webmaster@two.example.com
ServerName two.example.com:443
#
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
#
# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /var/www/two.example.com/htdocs
#
# Logfiles
ErrorLog /var/www/two.example.com/logs/error.log
CustomLog /var/www/two.example.com/logs/access.log combined
</VirtualHost>

The two host configurations above point to the same web content directories as their non-SSL counterparts. This is by no means necessary – they could have pointed to any location, they are in fact different virtual hosts from the perspective of the Apache2 web server.

Finally, lets see it working in action by enabling the sites, restarting Apache and pointing the browser to the new virtual hosts:

sudo a2ensite one.example.com-ssl
sudo a2ensite two.example.com-ssl
sudo /etc/init.d/apache2 restart

You should now be able to access https://one.example.com and https://two.example.com and see different content. If you are using a self-signed certificate, like I have described here, you will be asked to override the default security behavior in the browser. Assuming you trust yourself – go ahead and add the exceptions.

Next step

The next step will be to add Tomcat to the setup and make Apache2 communicate with the Tomcat backend through the AJP protocol as provided by the mod_jk module.

Setting up CAS on Tomcat with Apache2 and SSL on Ubuntu – part 1

Posted in Apache, Howto, Linux, Proxy by steelmon on October 22, 2009

A common scenario when providing services via the web is to expose all applications via an Apache front end. The Apache server acts as a dispatcher, or reverse proxy, and takes care of virtual hosting as well as any SSL traffic. This way, only one IP address needs to be exposed to the Internet while users gets the experience of multiple stand-alone sites. This article series also describes how applications can be conveniently put behind access control using the Central Authentication Service, or CAS for short.

Part 1 – Setting up Apache2 for virtual hosting

Installing and configuring Apache

We are going to create an environment where we can host multiple websites with a single server. This is quite straightforward to do with the use of the Apache web server. We are going to cover the use of the NameVirtualHost directive, which does not require any hard-wiring of IP addresses. The only thing you need is for your domain names to resolve to the IP address of your webserver.

For example if you have an Apache server running upon the IP address 10.0.1.20 and you wish to host the two sites one.example.com and two.example.com you’ll need to make sure that these names resolve to the IP address of your server. If you wish to do this in an isolated environment and avoid setting up DNS records, you can simply add the host names to your /etc/hosts file, which should then look something like the following (replacing the IP addresses with the address of your intended server):

127.0.0.1    localhost
10.0.1.20    one.example.com
10.0.1.20    two.example.com

After this preparation, the first thing to do is to setup an Apache2 web server. In Ubuntu, it is conveniently located in the repositories:

sudo apt-get install apache2

This installs the Apache web server and creates a basic configuration. After installation you should be able to access your newly created server on http://localhost. You should also be able to access the default server site on the addresses http://one.example.com and http://two.example.com.

The next thing to do is to enable virtual hosts in your Apache configuration. The simplest way to do this is to create a file called /etc/apache2/conf.d/virtual.conf and include the following content in it:

#
#  Handle multiple virtual hosts.
#
NameVirtualHost *:80
NameVirtualHost *:443

This effectively means that you are going to map all requests on port 80 and 443 (HTTPS) to virtual hosts. Note that there is a limitation as to how you can configure virtual hosts on HTTPS. Remember that traffic is encrypted when it arrives to the web server. This includes the actual host name in the request URL as well. Thus it is impossible for Apache to know which security certificate to use in order to decrypt the request. There is however something called wildcard certificates – these can be used for domain patterns like *.example.com. If we are using a wildcard certificate, we can host an arbitrary number of virtual hosts under the domain, and they will all use the same certificate. More on that in a later post.

Next, we need to create the two virtual web sites. All site configurations under apache2 are kept in the directory /etc/apache2/sites-available. Start by creating the file /etc/apache2/sites-available/one.example.com-http:

#
#  Virtual host
#  one.example.com (/var/www/one.example.com)
#
<VirtualHost *:80>
ServerAdmin webmaster@one.example.com
ServerName  one.example.com:80

# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /var/www/one.example.com/htdocs

# Logfiles
ErrorLog  /var/www/one.example.com/logs/error.log
CustomLog /var/www/one.example.com/logs/access.log combined
</VirtualHost>

Note that the directive ServerName marks the name of the virtual host, and when Apache receives a request that contains a url with this name, it will be directed to the directory /var/www/one.example.com/htdocs. Now, lets do the same with the second virtual host by creating the file /etc/apache2/sites-available/two.example.com-http:

#
#  Virtual host
#  two.example.com (/var/www/two.example.com)
#
<VirtualHost *:80>
ServerAdmin webmaster@two.example.com
ServerName  two.example.com:80

# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /var/www/two.example.com/htdocs

# Logfiles
ErrorLog  /var/www/two.example.com/logs/error.log
CustomLog /var/www/two.example.com/logs/access.log combined
</VirtualHost>

The last thing to do is to create a directory structure and some content to display for the sites:

sudo mkdir /var/www/one.example.com/htdocs
sudo mkdir /var/www/one.example.com/logs
sudo mkdir /var/www/two.example.com/htdocs
sudo mkdir /var/www/two.example.com/logs
sudo echo "site one.example.com" > /var/www/one.example.com/htdocs/index.html
sudo echo "site two.example.com" > /var/www/one.example.com/htdocs/index.html

Finally, lets enable the sites, restart apache and see the result. Enabling the sites boils down to creating symbolic links in the /etc/apache2/sites-enabled directory. These are automatically included by Apache when the configuration is loaded. For convenience there is  a script available that creates the link for us:

sudo a2ensite one.example.com-http
sudo a2ensite two.example.com-http
sudo /etc/init.d/apache2 restart

Now, direct the browser to http://one.example.com, followed by http://two.example.com. You should be greeted by two different web sites. Voila!

Next step

The next step is to enable SSL with the use of a wildcard certificate

References

http://www.debian-administration.org/articles/412