Web Knocker Firewall Service

Are you:

If you answered "Yes" to all of those questions, then you've found an obscure, open source project on the Internet that fulfills your desire: A web-based service written in pure PHP that opens protected TCP and UDP ports in response to encrypted requests from a correctly configured client for a limited but renewable time period.

Welcome to the Web Knocker Firewall Service.


The following is a list of features of the Web Knocker Firewall Service:

The Web Knocker Firewall Service is extremely useful for rigorously controlling and limiting access to a VPS, cloud host, or dedicated host where a root shell is available over SSH (or other critical services) without operating outside of the security-hardened IP stack. Keep rogue users and government entities out of your infrastructure.


Want to help out? Check out the official GitHub repository.

Donating financially helps keep this project alive.

Getting Started

To get started, download the latest Web Knocker Firewall Service release:

Download web-knocker-firewall-service-1.0rc2.zip

Extract the files to a new directory on your computer.

Upload the 'server' subdirectory to a relatively unguessable location on your Linux-based web server.

If you do not have PHP installed, then download and install the command-line (CLI) version for your distribution. Web Knocker Firewall Service is written in PHP and therefore requires PHP to be somewhere on the system to function.

From a command-line/shell session on the server, run:

php install.php

You will be asked a series of questions that will configure the service and then install and run it. Firewall/iptables rules will be modified. As a result, it is highly recommended to have a working recovery plan just in case access to the server is lost. Two possible options are to have a console or virtual console handy or switch temporarily from a DROP policy to an ALLOW policy in case things go horribly wrong.

Once the server portion is set up, put the 'client' subdirectory somewhere on the client and, from a command-line, run:

php install.php

During the installation, the client installer will ask for the encryption keys (key1, iv1, key2, iv2) and HMAC signing key (sign) and the server URL where 'index.php' is located. Copy the keys from the server installation screen and calculate the appropriate URL. Once the connectivity test passes, the configuration is saved and the client service is optionally installed and started. It can, of course, be manually run.

To unblock the ports manually or to debug server issues, run:

php run.php

On the server side of things, running 'iptables-save' and 'ip6tables-save' will show the current firewall rules including the Web Knocker Firewall Service rules. Once everything looks good, lock down the server if you switched INPUT from DROP to ACCEPT earlier and then gain a little extra peace of mind with fewer ports open to the world.

How It Works

The client and server share dual encryption keys and a HMAC signing key. Think of it as a permanently established pre-negotiated SSL session. When a client wants to open a port, it first makes an information query to identify what ports for which protocols can be opened, how long they can be opened for, and what the server sees as the client IP address. Stopping a man-in-the-middle (MITM) attack is quite difficult (if not impossible) to begin with but that's not exactly the objective here. The objective is to keep out all of the automated scripts that are just hammering away at the open ports all day long. The client's IP address plus a timestamp prevents replay attacks, which is probably more than sufficient for most purposes.

When a query is made by the client, it always uses the CubicleSoft dual encryption, packetization method. The block size of the request is 512 bytes and the total request size averages around 1,034 bytes - approximately 50% overhead. If a request is made every 10 minutes, approximately 150KB of data will be sent by the client daily to maintain one or more open ports. Data to be sent is JSON encoded, prefixed with the size, a HMAC is appended using the signing key, the result is wrapped in random bytes using a CSPRNG padded to the nearest 512 bytes, encrypted twice, and then Base64 encoded using the safe encoding mechanism.

On the server side, the 'index.php' file reverses the procedure to decode, decrypt, and then verify the received data. If any errors occur, a HTTP error code is emitted and additional information may or may not be available - usually nothing beyond the HTTP error code is available. If no errors occur and a valid API action was requested, the server responds with an encrypted data packet of its own.

When the request in the data packet is to open one or more ports, 'index.php' opens a TCP connection to the running server started by 'server.php' and passes along the packet information. 'index.php' is running under the web server user, which is probably something like 'www-data' and, of course, cannot make firewall changes. 'server.php', on the other hand, is running as a system service as the root user. Incoming localhost TCP connections (default is port 33491) send JSON encoded data to the server that specifies which port(s) to open for a specific IP address and for how long along with a shared secret (via 'config.php') that affords some basic protection. The server responds according to the information received and, upon success, returns when the applied firewall rules will expire. When the server opens a port (renewals don't count), it will also send notification e-mails if it is configured to do so.

Security Analysis

In standard SSL notation, the protocol in use is probably:


CBC mode is irrelevant here - ECB could have been used - since the packetization method described in the previous section mitigates all known (BEAST, etc.) and probably all unknown vulnerabilities. CBC is good for extra mixing, but that's all. The use of the SHA-1 hash for HMAC is more for compatibility than anything else but HMAC-SHA-1 is still considered to be secure. Although, if someone can get past the encryption bits to get to the hash, they probably stole your configuration file which contains the encryption keys AND your HMAC signing key, so it doesn't matter. It's probably much easier to find another way to make a request to 'server.php' via an application vulnerability in the other software running on the web server than to try to break the encryption/signing bits.

Remember all of this is to simply stop automated attack tools by closing the ports that are open to the world that already have their own security mechanisms built in. Most automated attack tools give up when they don't see an open port and move onto their next target.

Someone may point out that a web knocker has one serious problem: If the web server is down, it won't work. In my experience, 98% of the time the web server is down, SSH is also inaccessible due to either heavy CPU load or other irregular reasons (e.g. a poorly written script encounters an unexpected network outage and spawns thousands of processes) and only a remote reboot of the system resolves the multitude of issues involved. I've only ever occasionally been able to access such systems or already had an active SSH connection to the box - and, even in those cases, I've found that it is still simpler and more efficient to reboot to correct the immediate performance problem and then resolve the core issue that triggered the performance problem after the system comes back up rather than try to do both simultaneously.

© CubicleSoft