CWKPF Cuasi-Web Knocking for Packet Filter

My English is just horrible (corrections are welcome). Posiblemente quieras leer esto en español.

The problem

Many people, like myself usually have many servers hidden behind a single public IP address. To administrate them, my favorite tool is SSH; that is why I used to redirect non-standard ports to the 22/tcp of every machine. For example, the 22/tcp port of the public interface is my firewall, the 222 is the webserver and the 2222 is the database one.

The problem is that many times I meet to connect to those from restricted networks where some of those ports are closed. Then I had to hop from machine to machine having to remember the password and put up with the delay.

There is also the problem of the bruteforcing attacks that are a constant threat and nuisance to our SSH servers

The approach

So, I decided to write this cuasi-web knocking for OpenBSD's Packet Filter, my firewall of choise. The idea is simple, the firewall is hosting a simple web page that when surfed in a particular way, redirects the 22/tcp port to different hosts such as only the IP that surfed this web page has access

Guidelines, in order of importance:

  • Simplicity. Browsing the web page with telnet or netcat must be easy in case there is no browser available
  • Security. Keeping the OpenBSD's Apache inside it's chroot jail. Generating the redirection has to have at least some (while simple) form of authentication.
  • Efficiency: The processes must be lightweight (my firewall has more important things to do).

    Notice: I'm not sure I fullfilled all the requirements, so I'm open to any suggestions. This thing about a shell and netcat inside a chroot jail feels hackish. In any case, whatever you do is your responsibility.

    Requirement:

  • bash and mod_fastcgi, to run the webknock.sh script and it's config file, secret.
  • python, to run the pfctl.py script.
    All these packages are available in precompiled form in your favourite OpenBSD repository.

    Installation:

  • Inside the Apache chroot jail
    The main component is webknock.sh, a cgi web page that will become the actual webknock and will be placed here: /var/www/cgi-bin/webknock.sh. This web page can be configured from /var/www/conf/webknock/secret. The /var/www/conf/webknock directory must have write permisions for the www user or whoever user the Apache web server runs as.

    webknock.sh is a bash script that requires some extra commands inside the chroot to work, those must be copied there following the this structure:

    /var/www/
    |-- bin
    |   |-- cat
    |   `-- echo
    `-- usr
    |-- bin
    |   |-- cut
    |   |-- grep
    |   `-- nc
    |-- lib
    |   |-- libc.so.30.3
    |   |-- libc.so.38.2
    |   |-- libtermcap.so.9.0
    |   `-- libz.so.4.1
    |-- libexec
    |   `-- ld.so
    `-- local
        `-- bin
            `-- bash
    
    The library versions can change depending on the version of the SO. The ldd <binary> command will let you know what the right libraries are.
    Apache (with the fastcgi module already installed) must be configured the following way:
    ScriptAlias /knock "/var/www/cgi-bin/webknock.sh"
    <Directory "/var/www/cgi-bin/*">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all
    </Directory>
    
  • Outside the Apache chroot jail
    Package Filter must be configured to redirect the ssh port. To accomplish this,tables tables will be used. These will read the origin ip from /var/www/conf/webknock/orig and will redirect the 22/tcp port to the host inside /var/www/conf/webknock/dest. Therefore, the configuration in /etc/pf.conf is the following (the $ext_if is the external interface)
    table <ssh_orig> persist file "/var/www/conf/webknock/orig"
    table <ssh_dest> persist file "/var/www/conf/webknock/dest"
    rdr pass on $ext_if proto tcp from <ssh_orig> to ($ext_if) port 22 -> <ssh_dest>
    
    The pfctl.py script is a small daemon written in Python that listens in the 50150 port in the loopback interface. It's purpose is simple: each time it receives a connection, it will run the pfctl -Tl /etc/pf.conf command. webknock.sh will trigger this event every time the ssh_orig and ssh_dest tables need to be reloaded.

    pfctl.py should be copied to /usr/local/sbin/pfctl.py. To run it every time the system starts, you must include the following inside /etc/rc.local:

    if [ -x /usr/local/sbin/pfctl.py ]; then
                 echo -n ' pfctl.py';       /usr/local/sbin/pfctl.py &
    fi
    

    Usage:
    The webknocking will be accessible in http:\\[your_site_com]\knock. To make any change in the firewall redirection you can access to the links or directly to http://[your_site_com]/knock?[your_password]=[action].

    The author and license

    The author of this is Luciano Bello, who will be happy to read your consults, improvements and work with you to fix whatever error you think you have found at luciano [en] linux [punto] org [punto] ar. The webknock.sh and pfctl.py scripts are written under the DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE © 2008 Luciano Bello.


    Last update: Sat, 01 Mar 2008 19:15:02 -0200