Posts tagged ‘Apache’

Apache external filter to emulate mod_qos

For one of our highly critical web-service we use mod_qos to add more security rules inside Apache in front the Application Server. I’ve been trying to recreate a similar environement on my work station and it was quite hard to get a windows version of mod_qos and mod_security. The feature I was trying to setup on Windows is the follwing :

- A client sends a soap request. The request shall contain a particular string, a client code, say XXX

- Apache, using mod_qos shall only allow requests with specific client codes, and reject anything else

- In case of a rejected request, Apache shall sends a specific XML response (rather than a HTTP code, etc.)

The production solution uses mod_qos directives :

QS_SetEnvIfBody “<code>(XXX|YYY|ZZZ)</code>” code=$1
QS_ErrorResponseCode 503
QS_DenyEvent +InvalidCode deny !code
ErrorDocument 503 myresponse.xml

That is : if the incoming request does not contain something like <code>XXX</code>, emit an HTTP 503 response code wich is finally translated into a custom XML response sent back to the client.

Getting the some implementation on a windows system is hard to come by. However, I managed getting some other dirty way to do it :

- Define an external filter for the web-service endpoint

- Create a small program (I wrote it first in PHP than move it to python to make it even more concise) that will be called in two ways  :

1.  As an input filter :

* Read the request body from stdin
* Check for the client code
* If found, write “OK” to a temp file, otherwise write “KO”
* Rewrite the request to stdout (forwarding it to the next filter in Apache chain)

2.  As an output filter :

* Read the response body from stdin
* Read the temp file
* if the temp file gives “OK”, write the response body as is to stdout, otherwise, read the custom xml response file and write its content to stdout.

Seen from the client, it gets the desired behavior : if it doesn’t send a client code in its soap request, it gets a specific XML response sent by Apache.

here is the Apache configuration :

ExtFilterDefine MyFilterIN   mode=input   cmd=”C:\\python\\python.exe C:\\my_filter.py IN”
ExtFilterDefine MyFilterOUT  mode=output  cmd=”C:\\python\\python.exe C:\\my_filter.py OUT”
<Location /Myservices/MyServiceEndPoint>
ExtFilterOptions DebugLevel=9 LogStderr
SetInputFilter  MyFilterIN
SetOutputFilter MyFilterOUT
</Location>

And this is the python piece of code doing the trick :


import sys
import re
TEMP_FILE    = "C:/my_temp.txt"
MY_XML        = "C:/503.xml"
soapData=''.join([x.strip() for x in sys.stdin.readlines()])
if( "IN" == sys.argv[1] ) :
        match = re.compile('.*<code>(XX|YY|ZZZ)</code>.*').match(soapData)
        f = open(TEMP_FILE,'w')
        f.write( "OK" if match else "KO" )
        f.close()
        print soapData
else :
        f = open(TEMP_FILE,'r')
        if( 'OK' == f.read().strip() ):
                print soapData
        else:
                custom = open(MY_XML,'r')
                print custom.read()
                custom.close()
        f.close()

I should confess that I was quite proud of the hack despite the dirtiness of the solution…

Apache modules : the power of ( II )

It’s been a long time ago since my last post here.  Maybe 2010 will give me much more energy to continue sharing stories of a Desperate House Geek.  By the way, I’ve been struggling against a strange behaviour of an Apache Server in front of an application server, with lines of logs like this :

[warn] [client 10.240.xxx.yyy] proxy: no HTTP 0.9 request (with no host line) on incoming request and preserve host set forcing hostname to be my.server.net for uri /

This is due to our monitoring servers with frequent requests to test if the application is Up or Down (mainly, if the Apache is responding)

Googling around landed me in sparse and rare pages about the problem. However, the source code of mod_proxy as well as the error message itself gave me the hint : trying to add the probably missing request header before the request is getting passed to mod_proxy, but only if the incoming request originated from the monitoring robot (10.240.XXX.YYY). Here comes in play the power of Apache with its handy modules mod_headers and mod_setenvif.  Here we go :


SetEnvIf  Remote_Addr  "10\.240\.xxx\.(yyy|zzz)" __ROBOT__
RequestHeader set Host "my.server.net" env=__ROBOT__

It solved the problem.

Java source highlighting

Here is a simple practical solution for highlighting source code served from an Apache web server. The motivation behind this was when I wondered how to allow syntax highlight for my SVN hosted source code when viwed with a browser. I came across a very useful tool written in python, pygmentize. Once this python module downloaded and installed, the following settings should be put in Apache httpd.conf file:

Action highlight /cgi-bin/highlight.py
AddHandler highlight .java

the highlight.py is a python script using pygmentise, and here’s the simplicity :


#!/bin/python
import cgi
import cgitb; cgitb.enable()
import os
from pygments import highlight
from pygments.lexers import JavaLexer
from pygments.formatters import HtmlFormatter

def main():
   print "Content-type: text/html\n"
   print highlight(open(os.environ['PATH_TRANSLATED']).read(), JavaLexer(), HtmlFormatter(full=True))

main()

Obviously, this will hilight java or whatever source code, but will not touch files served via WebDAV/SVN (Hopefully!)

Subversion with Apache

One of the greatest featurse with nowodays SVC systems, in particular Subversion, is its accessibility through a banch of network protocols, as HTTP, when SVN is coupled with Apache web server. When making my own install on my lapotop, and as I’m very sensitive to keep each peace of software in it’s own containing folder, I came to these points :

- It was impossible for me to avoid copying required SVN dlls to Apache bin folder. That’s the most annoying part of the installation especially when the 2 official tutorials are not really explicit. In fact, including the bin directory of SVN installation into the PATH system variable is not working. And copying only intl3_svn.dll and libdb44.dll is not working eather. I finally come across the solution consisting of copying intl3_svn.dll as well as all the lib*.dll to the Apache/bin folder, without overrwiting the existing ones. It’s about 12 dll files.
- The SVN official documentation states that the stylesheet files (necessary if we want to visualize a well-presented web page when accessing to the repository URL) shall be put in the DocumentRoot of the Apache server. That’s also an annoying point for me as I always want to avoid putting any extra document or file in the standard Apache installation. This time, I found a little hack to avoid this, without even playing with VirtualHosts configuration. The main part to add to httpd.conf is the following :

<Location /svn>
DAV svn
SVNListParentPath on
SVNParentPath D:\svnrepo
SVNIndexXSLT /svnindex.xsl
AuthType Basic
AuthName "Subversion repositories"
AuthUserFile "auth/__users.txt"
Require valid-user
</Location>

wich makes the SVN repository accessible at http://localhost/svn. Now we want the SVN stylesheets material to be placed outside the Apache DocumentRoot, for example in the folder D:/www/svn-web-content/, we have just to add the following configuration to httpd.conf :

Alias /svn-web "D:/www/svn-web-content/"
<Directory "D:/www/svn-web-content/">
AllowOverride None
Order Deny,Allow
Allow from all
</Directory>

And then change the directive SVNIndexXSLT to point at /svn-web/svnindex.xsl instead of /svnindex.xsl. Now if we open the page http://localhost/svn, we unfortunately see the same unformatted basic page. However, after looking to the Apache acess log file, we can understand the trick :

“GET /svn-web/svnindex.xsl HTTP/1.1″ 200 3558
“GET /svnindex.css HTTP/1.1″ 404 1950
“GET /menucheckout.ico HTTP/1.1″ 404 1950

So XSL file is correctly found and sent by the server, but not the CSS/ICO file. The solution is really simple by editing the XSL file and replacing each occurrence of href=”/svnindex.css with href=”/svn-web/svnindex.css, and the same for the file menucheckout.ico. It’s up and running.

Hacking (?) mod_autoindex

When browsing several Internet sites, we certainly have come across some commonly-formatted web pages. Lots of them are automatically generated by the Web server. Apache web server has a dedicated module to generate directory indexes. theses indexes are often “ugly” simple pages.

Here’s some steps to get around this starchy formattin, and don’t worry, I’m not gonne advice you to edit the module’s source code and recompile it. The hack is based on CSS and DOM manipulation using JavaScript, and some tips when configuring the server. First, we have to enhance the default settings of the directive IndexOptions of the httpd-autoindex.conf file as follows :

IndexOptions FancyIndexing HTMLTable FoldersFirst IgnoreCase IgnoreClient XHTML Type=text/html NameWidth=* SuppressDescription SuppressLastModified SuppressHTMLPreamble

Then, within the same file, we set the directive ReadmeName to /README.html (which is the default setting). This way, the README.html file wich is appended by Apache after each directory indexing will be used to host the CSS/JavaScript code used to impropuve the index formatting. This is the CSS dirctives I’ve included in my README.html file :


H1 {font-size:18px;font-family:Arial;font-weight:normal;color:#EEEEEE;text-align:center;background-color:#777777;margin-bottom:30px;}
BODY {margin-top:0px;margin-left:0px;margin-right:0px;background-color:#d8d8d8}
A {color:#3300cc; font-family:Arial; font-size:13px;text-decoration:none;}
A:hover {color:#330000; font-family:Arial; font-size:13px;text-decoration:underline;}
TD {font-family:Arial; font-size:12px;}
SPAN.GT {
color:orange;
font-weight:bold;
position:relative;
top:1px;
}

then, just after the <style> bloc, I’ve added the following JavaScript code :


<script langage="javascript">
if(document.getElementsByTagName)
{
t=document.getElementsByTagName("table").item(0)
t.setAttribute("align","center")
t.setAttribute("cellpadding","2")
t.setAttribute("border","0")
t.setAttribute("style","border-width:0px;border-style:solid;border-color:black;")
}
d=document.createElement("div");
d.setAttribute("style","width:500px;border-style:solid;border-width:1px;border-color:black;margin-top:20px;padding:20px");
d.appendChild(t)
h=document.getElementsByTagName("h1").item(0);
d.insertBefore(h,t)
c=document.createElement("center");
c.appendChild(d);
s=document.getElementsByTagName("script").item(0);
s.parentNode.insertBefore(c,s);
document.getElementsByTagName("h1").item(0).innerHTML=document.getElementsByTagName("h1").item(0).innerHTML.replace("Index of /" , "").replace(/\//g , " <span class=\"GT\">&amp;amp;gt;</span> ");
document.getElementsByTagName("tr").item(0).setAttribute("style","display:none;");
document.getElementsByTagName("tr").item(1).setAttribute("style","display:none;");
document.getElementsByTagName("tr").item(document.getElementsByTagName("tr").length-1).setAttribute("style","display:none;");
_tds=document.getElementsByTagName("td");
for(i=0,__loop=_tds.length;i<__loop;i++){
if( _tds.item(i).innerHTML == "  - "  )
document.getElementsByTagName("td").item(i).innerHTML="&amp;amp;nbsp;";
}
</script>

The above script basically creates an empty centered div tag inside of wich it places the generated html table, the index title and removes unwanted others hedares or tables headers (some <tr> elements). The final result looks much more pretty: