Dave Horner's Website - Yet another perspective on things...
Home Tech Talk Projects and Research Gate Arrays
165 guests
Rough Hits : 3106369
moon and stars
how did u find my site?





 
onomastics (seen in code)












 
“In mathematics you don’t understand things. You just get used to them.”
–John Von Neumann

L:0 I:0 A:0

IPOpener - Block everything and allow to few (The power of dynamic rules).

Thursday, 20 January 2005 19:06
IPOpener, open your ports to people you trust. Close them to everyone else.
Simple scripts to enable HTTP authenticated dynamic firewall rules.
Perfect for granting dynamic hosts access to trusted ports!

Update Mar-21-2007: Code and project updated, will update article in future to reflect new changes...and document code better...
Download 1.0 [latest]

Update: Mar-25-2005
I've now integrated the bash scripts from another article on my site which allows you to trust given dynamic DNS host entries. This means that you've got a way to open your iptables based firewall to trusted hosts which are not statically assigned. The remote host will not have to install a client to constantly update the server's IP address. Instead, the remote server will lookup the dDNS based DNS record. (pretty slick..and easy)
The scripts are documented inside my article on iptables..[here]
One day soon maybe I'll merge the content and explain better....don't have time now.

A while ago I read an article in the Linux Journal about Port Knocking. Port knocking allows the system administrator to keep their system invisible while granting access to those with the special "knock". Port knocks are great to increase system security because it defends against system probes. However, port knocking becomes useless on a system that MUST open even a single port. The probing system is aware that the system is listening on that IP and the attacker can focus his attention on that machine.

I'm proposing a new solution that doesn't seek to make your system invisible but instead helps maintain control of the sensitive ports which only trusted users should have access.

Instead of closing all ports. (something that most system can't do because they MUST provide services to the outside world). We setup port authorization on an existing external service. A perfect candidate for this solution is the webserver. Webservers typically allow traffic to ports http(80) and optionally https(433). Almost every system I have ever setup includes a webserver. In addition, most webservers run as non-root users so exploits on webservers are typically safer than root run servers like ssh.

The problem with just opening traffic to HTTP is that we still require other ports to be open for management and content submission. We'd like to be able to login from time to time using ssh but we don't want to open ssh to the world. Leaving ports open that are required for the outside world is dangerous because of potential software bugs. Software bugs in things like sshd lead to system compromise.

The solution is to create a place on your webserver that is password protected and encrypted. These requirements are easy to setup using a webserver like apache. Details on apache installation and setup with https are outside the scope of this document and can be found easily on google.

Once we get a place setup for authorized users to login. Users can begin to login to the site. If the user is an authorized user, their incoming IP is logged to a database and iptables is notified of the change. The webserver then indicates to the user that he may now connect to the authorized ports.

The benefits of a system such as this is that your may keep all unnecessary ports closed to everyone except those with password access. Users don't have to install software to open ports on your machine, all that is required is a web browser. Once users login to the authorized site, trusted port access can be granted indefinitely or for a brief period of time. Since users are required to login to the website before using the trusted ports, you have an audit trail which can be used to "track down" the user who is causing problems with the trusted service.

Installation and management of IPOpener is very easy.
Users and port access is all managed from a database. At this point it is done using mysql but other databases are possible.
Create a database and grant permission to a database user. Create the following table in the database:
CREATE TABLE `weballow` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) DEFAULT NULL,
  `name` text NOT NULL,
  `source_ip` varchar(20) NOT NULL DEFAULT '',
  `dest_port` varchar(4) NOT NULL DEFAULT '',
  `dest_proto` varchar(4) NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 ;

Then insert some user that can access the trusted ports.
For example I might want the guest user to be able to access the port for ssh. I would simply insert the following SQL into the database.
INSERT INTO `weballow` (`username`, `name`, `source_ip`, `dest_port`, `dest_proto`) VALUES ('guest', 'A guest user', '', 'ssh', 'tcp');

Then you can simply setup an .htaccess that only allows certain users access to a web accessable directory. In this cause I would only allow the user guest access. Inside the protected directory I would create an index.php that would update the user's IP and notify the system that IPTables should be updated with the user's new IP address. A sample index.php is shown below:
<?php
$REMOTE_USER=$_SERVER['REMOTE_USER'];
$REMOTE_ADDR=$_SERVER["REMOTE_ADDR"];
include "ipopenerinc.php";
$ipopener= new ipopener();
if($ipopener->init()) {
   if($ipopener->update_addr($REMOTE_USER, $REMOTE_ADDR."/32")) {
      echo "<font color=#ff0000>Changed access IP address. Wait 2 minutes before accessing trusted ports.</font>
";
   }
} else {
  echo "<font color=#ff0000>ERROR! IPOpener failed. Contact administrator.</font>
";
}
echo "Hello there ".$REMOTE_USER ." coming from: ".$REMOTE_ADDR."
";
?>
Now when the user guest logs into the protected directory using his webbrowser, the system will update the database with the new IP address that should have access and automatically add the rule to iptables.

Here is the included ipopenerinc.php file
<?
   require_once('DB.php');    // Include the Pear::DB class code
   $VERSION = "1.1";
 
   class ipopener_rule {
      var $id;
      var $name;
      var $source_ip;
      var $dest_port;
      var $dest_proto;
   };
 
   class ipopener {
      var $db;
      var $table_user="webusers";
      var $table_allow="weballow";
      var $dsn = array('phptype'  => "mysql",
                       'hostspec' => "localhost",
                       'database' => "ipopener",
                       'username' => "root",
                       'password' => "");
 
      function init($db=NULL) {
         if($db==NULL) {
             $db=DB::connect($this->dsn);
             if (DB::isError($db)) {
                 echo "An error occurred while trying to connect to the database server.
\n";
                 echo "Error message: " . $db->getMessage() . "
\n";
                 echo "A more detailed error description: " . $db->getDebugInfo() . "
\n";
                 return false;
             }
             $db->setOption('debug', 8);
         }
         $this->db=$db;
         return true;
      }
      function update_addr($username, $ipaddress) {
         // our database isn't opened!
         if(!$this->db) {
             return false;
         }
         $fields_values = array('source_ip' => $ipaddress);
         $res = $this->db->autoExecute($this->table_allow, $fields_values, DB_AUTOQUERY_UPDATE,"username=".$this->db->quoteSmart($username));
         if (DB::isError($res)) {
      $res->getDebugInfo();
            die($res->getMessage());
         }
         return $this->db->affectedRows(); 
      }
   };
?>


So this gets the data into your system. But now how do we dynamically add rules to our firewall?
There are a couple of ways to do it. One would be to make an IPTABLES module that actually reads results from the database, another would be to write a simple daemon that monitors the database for changes and executes the appropriate iptable commands, and the last and easiest would be to create a simple cron script to run at a regular interval.

For simplicity I chose to implement it using the last method for now:


Add a cron entry like so (decide yourself how often):
/etc/cron.d/ipopener
# Run the ipopener script every 1 minutes
* * * * * root /root/ipopener/cmd/ipopener_apply > /dev/null  2>&1
# Force application every 5 minutes.
# Makes sure that iptable chain not lost in mem, but file on disk unchanged.
*/5 * * * * root /root/ipopener/cmd/ipopener_apply force > /dev/null  2>&1


Port Knocking

I thought I may as well include these links on knocking dynamic rules in...
How to safely connect from anywhere to your closed Linux firewall | MDLog:/sysadmin


cipherdyne.org | System and Network Security
Single Packet Authorization with Fwknop
fwknop: Single Packet Authorization and Port Knocking
fwsnort - iptables Intrusion Detection with String Matching and Snort Rules
Pure C Implementation of Single Packet Authorization
Creating Ghost Services with Single Packet Authorization
Port Forwarding via Single Packet Authorization
The Security Properties of Port Knocking and SPA
fwknop: Single Packet Authorization in Ubuntu | SavvyAdmin.com
Tutorial on Single Packet Authorization with fwknop
IPTables::Parse perl module - IPTables::Parse - Perl extension for parsing iptables and ip6tables firewall rulesets, IPTables::Parse module used by the psad and fwsnort
IPTables::ChainMgr perl module - IPTables::ChainMgr - Perl extension for manipulating iptables and ip6tables policies
psad - Intrusion Detection with iptables, iptables Log Analysis, iptables Policy Analysis - psad is a collection of three lightweight system daemons (two main daemons and one helper daemon) that run on Linux machines and analyze iptables log messages to detect port scans and other suspicious traffic.


MyDNS Dynamic Hosts

Using Dynamic DNS you can do trusted hostnames to gain access. You just need to resolve the dynamic IP to refresh the IP tables rule...
Simple Dynamic DNS with MyDNS - Blink - provides a web php script for updating mydns records from a wget shell script on the remote server.

< Prev  Next >
Last Updated on Thursday, 19 June 2014 23:14