Configuring The Firewall Using IPTABLES

About the Script:

The script is about to build a firewall in Linux using iptables, the user need only to monitor and respond to simple and easy measures and the script will generate the user specified iptables rule in its form original.

I tested the script to PCLinuxOS, FEDORA-9, DREAM_LINUX, UBUNTU-8.
This is my iptables, version 1.0

About iptables:

Network security is a primary consideration in any decision to host a website as the threats are becoming more widespread and persistent every day. One way to provide additional protection is to invest in a firewall. Although prices are still falling, in some cases, you be able to create a comparable unit using the Linux iptables package on a server for little or no additional cost.

Originally, most firewall / NAT package running on Linux was ipchains, but it had a number of shortcomings. To remedy this situation, Netfilter organization has decided to create a product called iptables.


Starting of the Script

A Menu will appear like this:

*****Main Menu*****
1. Check Iptables Package
2. Iptables Services
3. Build Your Firewall with Iptables
4. Exit


1. Check Iptables Package
Now let the user select the option 1. Check iptable Package from the menu by pressing "1" from the keyboard.
Now the script confirms that the user must be Root, and we know that the UID of Root is zero ( 0 ). So first I have to compare the UID of the current user with zero ( 0 ), if the UID doesn't match with the UID of root then it will display the following message:


****You must be the root user to run this script!****
and if the UID matches with root's UID then it displays the following message and runs the script:
***Identity Verified_You are the Root***

We can check the UID of the current user by typing the following command in the terminal:

echo $UID

If the identity of the user is verified as root, then the script will check the iptables package in the Linux OS by using the following command.

rpm -q iptables

*****Main Menu*****
1. Check Iptables Package
2. Iptables Services
3. Build Your Firewall with Iptables
4. Exit


Now if the user selects the option 2. Iptables Services then the checkstatus function will be called. In this function there are some options for the user:

*****Note: Save your Iptables before stop/Restart the iptables Services*****
1. Save the iptables
2. Status of Iptables
3. Start iptables Services
4. Stop iptables Services
5. Restart iptable Services
6. Flush iptables (**Use Carefully_it will remove all the rules from iptables**)
7. Go back to Main Menu


If the user selects 1. Save the iptables the iptables rules will be saved in the Linux OS by using the following command:

/etc/init.d/iptables save

If the user selects 2. Status of iptables the current status of iptables will be displayed, using the following command:

/etc/init.d/iptables status

Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- 192.168.1.45 172.16.4.8 reject-with icmp-port-unreachable
ACCEPT tcp -- 192.168.1.1 192.168.1.25
LOG icmp -- anywhere anywhere LOG level warning

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP udp -- 192.168.6.3 10.6.3.7


If the user selects 3. Start iptables Services then iptables will be started, using the following command:

/etc/init.d/iptables start

If the user selects 4. Stop iptables Services then iptables will be stopped, using the following command:


/etc/init.d/iptables stop

If the user selects 5. Restart iptable Services then iptables will be restarted, using the following command, it will load the saved iptables rules:

/etc/init.d/iptables restart

If the user selects 6. Flush iptables then iptables will be flushed, (**use Carefully_it will remove all the rules from iptables**), using the following command, it will flush the saved iptables rules:


iptables -F

To go back to the Main Menu the user must select option 7. Go back to Main Menu.

*****Main Menu*****
1. Check Iptables Package
2. Iptables Services
3. Build Your Firewall with Iptables
4. Exit

Option 3. Build your Firewall with Iptables is the heart of this script, by using this option users can create the firewall with iptables using simple steps, when a user selects the option 3. Build your Firewall with Iptables then the script will ask the user to create the firewall.


Using Which Chain of Filter Table?
1. INPUT
2. OUTPUT
3. Forward"

The above menu will ask the user to select the chain where he/she wants to put the rule.

Now the script will ask the user to get the IP information from the Source side...

1. Firewall using Single Source IP
2. Firewall using Source Subnet
3. Firewall using for All Source Networks

Then the above menu ask the user the above three question, if the user selects the option 1. Firewall using Single Source IP then the script will ask the user to enter the IP address.


If the user selects option 2. Firewall using Source Subnet then the script will ask the user to enter the subnet in the form of "192.168.1.0/24".

If the user selects option 3. Firewall using for All Source Networks then the script will put 0/0 in the variable named "ip_source" in the script.

Now the script will ask the user to get the IP information from the Destination side...


1. Firewall using Single Destination IP
2. Firewall using Destination Subnet
3. Firewall using for All Destination Networks

Then the above menu asks the user the above three questions, if the user selects option 1. Firewall using Single Destination IP then the script will ask the user to enter the IP address.

If the user selects option 2. Firewall using Destination Subnet then the script will ask the user to enter the subnet in the form of "192.168.1.0/24"

If the user selects option 3. Firewall using for All Destination Networks then the script will put 0/0 in the variable named "ip_dest" in the script.


Now the script asks the user to select the PROTOCOL:

1. Block All Traffic of TCP
2. Block Specific TCP Service
3. Block Specific Port
4. Using no Protocol

Now from the above displayed menu if the user selects 1. Block All Traffic of TCP then the script will block all the TCP Traffic.

If the user selects 2. Block Specific TCP Service, now the script will ask the user to enter the TCP Service of his/her choice (e.g ICMP).


Note: the TCP Service name should be in CAPITAL LETTERS!!!

If the user selects 3. Block Specific Port the script will ask the user to enter the PORT number.

Now the script prompts the user What to do with the Above Created Rule?

What to do with Rule?
1. Accept the Packet
2. Reject the Packet
3. Drop the Packet
4. Create Log


If the user selects 1. Accept the Packet then the packet will be accepted.

If the user selects 2. Reject the Packet then the packet will be rejected.

If the user selects 3. Drop the Packet then the packet will be dropped.

If the user selects 4. Create Log then only the log will be created.


Now the following message will be shown to the user:

Press Enter key to Generate the Complete Rule!!!

When the user presses the Enter key then the script generates the original rule with the correct syntax and displays it to the user, in my case:

The Generated Rule is
iptables -A INPUT -s 192.168.0.0/24 -d 172.16.0.0/16 -p TCP -j ACCEPT

Now the script shows the following message to the user:

Do you want to Enter the Above rule to the IPTABLES? Yes=1 , No=2

If the above rule is correct then the user presses 1 for Yes and adds the rule to iptables
otherwise 2 for No and the script will return to let the user edit the rule.


Here is the whole script:
#!/bin/bash
echo -e "****************Welcome*************"
###############################IPTABLE SERVICES PROGRAM BEGINS HERE###############################
checkstatus()
{
opt_checkstatus=1
while [ $opt_checkstatus != 7 ]
do
clear
#echo -e "\nChoose the Option Bellow!!!\n
echo -e "\n\t*****Note: Save your Iptables before stop/Restart the iptables Services*****\n"
echo -e " 1. Save the iptables\n
2. Status of Iptables\n
3. Start iptables Services\n
4. Stop iptables Services\n
5. Restart iptable Services\n
6. Flush iptables (**Use Carefully_it will remove all the rules from iptables**)\n
7. Go back to Main Menu"
read opt_checkstatus
case $opt_checkstatus in
1) echo -e "*******************************************************\n"
/etc/init.d/iptables save
echo -e "\n*******************************************************\n"
echo -e "Press Enter key to Continue..."
read temp;;
2) echo -e "*******************************************************\n"
/etc/init.d/iptables status
echo -e "*******************************************************"
echo -e "Press Enter key to Continue..."
read temp;;
3) echo -e "*******************************************************\n"
/etc/init.d/iptables start
echo -e "*******************************************************\n"
echo -e "Press Enter key to Continue..."
read temp;;

4) echo -e "*******************************************************\n"
/etc/init.d/iptables stop
echo -e "*******************************************************\n"
echo -e "Press Enter key to Continue..."
read temp;;

5) echo -e "*******************************************************\n"
/etc/init.d/iptables restart
echo -e "*******************************************************\n"
echo -e "Press Enter key to Continue..."
read temp;;
6) iptables -F
echo -e "*******************************************************"
echo -e "All the Rules from the Iptables are Flushed!!!"
echo -e "*******************************************************\n"
echo -e "Press Enter key to Continue..."
read temp;;
7) main;;
*) echo -e "Wrong Option Selected!!!"
esac
done
}
###############################BUILD FIREWALL PROGRAM BEGINS FROM HERE###############################
buildfirewall()
{
###############Getting the Chain############
echo -e "Using Which Chain of Filter Table?\n
1. INPUT
2. OUTPUT
3. Forward"
read opt_ch
case $opt_ch in
1) chain="INPUT" ;;
2) chain="OUTPUT" ;;
3) chain="FORWARD" ;;
*) echo -e "Wrong Option Selected!!!"
esac

#########Getting Source IP Address##########
#Label

echo -e "
1. Firewall using Single Source IP\n
2. Firewall using Source Subnet\n
3. Firewall using for All Source Networks\n"
read opt_ip

case $opt_ip in
1) echo -e "\nPlease Enter the IP Address of the Source"
read ip_source ;;
2) echo -e "\nPlease Enter the Source Subnet (e.g 192.168.10.0/24)"
read ip_source ;;
3) ip_source="0/0" ;;
#4) ip_source = "NULL" ;;
*) echo -e "Wrong Option Selected"
esac
#########Getting Destination IP Address##########
echo -e "
1. Firewall using Single Destination IP\n
2. Firewall using Destination Subnet\n
3. Firewall using for All Destination Networks\n"

read opt_ip
case $opt_ip in
1) echo -e "\nPlease Enter the IP Address of the Destination"
read ip_dest ;;
2) echo -e "\nPlease Enter the Destination Subnet (e.g 192.168.10.0/24)"
read ip_dest ;;
3) ip_dest="0/0" ;;
#4) ip_dest = "NULL" ;;
*) echo -e "Wrong Option Selected"
esac
###############Getting the Protocol#############
echo -e "
1. Block All Traffic of TCP
2. Block Specific TCP Service
3. Block Specific Port
4. Using no Protocol"
read proto_ch
case $proto_ch in
1) proto=TCP ;;
2) echo -e "Enter the TCP Service Name: (CAPITAL LETTERS!!!)"
read proto ;;
3) echo -e "Enter the Port Name: (CAPITAL LETTERS!!!)"
read proto ;;
4) proto="NULL" ;;
*) echo -e "Wrong option Selected!!!"
esac

#############What to do With Rule#############
echo -e "What to do with Rule?
1. Accept the Packet
2. Reject the Packet
3. Drop the Packet
4. Create Log"
read rule_ch
case $rule_ch in
1) rule="ACCEPT" ;;
2) rule="REJECT" ;;
3) rule="DROP" ;;
4) rule="LOG" ;;
esac
###################Generating the Rule####################
echo -e "\n\tPress Enter key to Generate the Complete Rule!!!"
read temp
echo -e "The Generated Rule is \n"
if [ $proto == "NULL" ]; then
echo -e "\niptables -A $chain -s $ip_source -d $ip_dest -j $rule\n"
gen=1
else
echo -e "\niptables -A $chain -s $ip_source -d $ip_dest -p $proto -j $rule\n"
gen=2
fi
echo -e "\n\tDo you want to Enter the Above rule to the IPTABLES? Yes=1 , No=2"
read yesno
if [ $yesno == 1 ] && [ $gen == 1 ]; then
iptables -A $chain -s $ip_source -d $ip_dest -j $rule
else if [ $yesno == 1 ] && [ $gen == 2 ]; then
iptables -A $chain -s $ip_source -d $ip_dest -p $proto -j $rule

else if [ $yesno == 2 ]; then

main
fi
fi
fi
}

main()
{
ROOT_UID=0
if [ $UID == $ROOT_UID ];
then
clear
opt_main=1
while [ $opt_main != 4 ]
do
echo -e "/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n"
#############Check Whether the iptables installed or not############
echo -e "\t*****Main Menu*****\n
1. Check Iptables Package\n
2. Iptables Services\n
3. Build Your Firewall with Iptables\n
4. Exit"
read opt_main
case $opt_main in
1) echo -e "******************************"
rpm -q iptables
echo -e "******************************" ;;
2) checkstatus ;;
3) buildfirewall ;;
4) exit 0 ;;
*) echo -e "Wrong option Selected!!!"
esac
done
else
echo -e "You Must be the ROOT to Perfom this Task!!!"
fi
}
main
exit 0


Read more...

Set Up DHCP Failover On Centos

This tutorial will guide you through setting up DHCP fail on CentOS 5.1 default using the ISC DHCP server, which can be easily adapted to any other Linux distribution on the market. You'll probably need changeover in network environments where downtime can not be tolerated. At my house is running a configuration DLNA so I need my devices to be able to obtain network settings at any time.

Since DHCP and DNS often go hand in hand i will be setting up a local DNS server which allows updates dynamic, such as host names will be automatically updated DNS forever when a lease is granted to a customer.

My setup use the following configuration please substitute to your own network configuration.


  • Domain name - home.topdog-software.com

  • Network - 192.168.1.0/24

  • DHCP servers - 192.168.1.2,192.168.1.3

  • Gateway - 192.168.1.254

  • DNS servers - 192.168.1.2,192.168.1.3


Install required Packages

  • DHCP
    # yum install dhcp -y


  • DNS
    # yum install bind bind-chroot caching-nameserver -y


  • NTP
    # yum install ntp -y




Configuration :
DHCP

Backup your original config on the Master 192.168.1.2:

# cp /etc/dhcpd.conf /etc/dhcpd.conf.orig

Edit the DHCP configuration /etc/dhcpd.conf on the master 192.168.1.2 and add the following, read the comments to understand the options:

authoritative;                                  # server is authoritative
option domain-name "home.topdog-software.com"; # the domain name issued
option domain-name-servers 192.168.1.2,192.168.1.3; # name servers issued
option netbios-name-servers 192.168.1.2; # netbios servers
allow booting; # allow for booting over the network
allow bootp; # allow for booting
next-server 192.168.1.2; # TFTP server for booting
filename "pxelinux.0"; # kernel for network booting
ddns-update-style interim; # setup dynamic DNS updates
ddns-updates on;
ddns-domainname "home.topdog-software.com"; # domain name for DDNS updates
key rndckey {
algorithm hmac-md5;
secret "xxxxxxxxxx"; # get from the /etc/rndc.key file
}
zone home.topdog-software.com # forward zone to update
{
primary 127.0.0.1; # update on the local machine
key rndckey; # key to use for the update
}
zone 1.168.192.in-addr.arpa # reverse zone to update
{
primary 127.0.0.1; # update on the local machine
key rndckey; # key for update
}
failover peer "home-net" { # fail over configuration
primary; # This is the primary
address 192.168.1.2; # primarys ip address
port 647;
peer address 192.168.1.3; # peer's ip address
peer port 647;
max-response-delay 60;
max-unacked-updates 10;
mclt 3600;
split 128;
load balance max seconds 3;
}
subnet 192.168.1.0 netmask 255.255.255.0 # zone to issue addresses from
{
pool {
failover peer "home-net"; # pool for dhcp leases with failover bootp not allowed
deny dynamic bootp clients;
option routers 192.168.1.254;
range 192.168.1.25 192.168.1.50;
}
pool { # accomodate our bootp clients here no replication and failover
option routers 192.168.1.254;
range 192.168.1.51 192.168.1.55;
}
allow unknown-clients;
ignore client-updates;
}


Back up your original config on the Slave 192.168.1.3:

# cp /etc/dhcpd.conf /etc/dhcpd.conf.orig

Edit the DHCP configuration /etc/dhcpd.conf on the slave 192.168.1.3 and add the following, read the comments to understand the options:

authoritative;                                  # server is authoritative
option domain-name "home.topdog-software.com"; # the domain name issued
option domain-name-servers 192.168.1.2,192.168.1.3; # name servers issued
option netbios-name-servers 192.168.1.2; # netbios servers
allow booting; # allow for booting over the network
allow bootp; # allow for booting
next-server 192.168.1.2; # TFTP server for booting
filename "pxelinux.0"; # kernel for network booting
ddns-update-style interim; # setup dynamic DNS updates
ddns-updates on;
ddns-domainname "home.topdog-software.com"; # domain name for DDNS updates
key rndckey {
algorithm hmac-md5;
secret "xxxxxxxxxx"; # get from the /etc/rndc.key file on the master
}
zone home.topdog-software.com # forward zone to update
{
primary 192.168.1.2; # update on the local machine
key rndckey; # key to use for the update
}
zone 1.168.192.in-addr.arpa # reverse zone to update
{
primary 192.168.1.2; # update on the local machine
key rndckey; # key for update
}
failover peer "home-net" { # fail over configuration
secondary; # This is the secondary
address 192.168.1.3; # our ip address
port 647;
peer address 192.168.1.2; # primary's ip address
peer port 647;
max-response-delay 60;
max-unacked-updates 10;
mclt 3600;
load balance max seconds 3;
}
subnet 192.168.1.0 netmask 255.255.255.0 # zone to issue addresses from
{
pool {
failover peer "home-net"; # pool for dhcp leases with failover bootp not allowed
deny dynamic bootp clients;
option routers 192.168.1.254;
range 192.168.1.25 192.168.1.50;
}
pool { # accomodate our bootp clients here no replication and failover
option routers 192.168.1.254;
range 192.168.1.51 192.168.1.55;
}
allow unknown-clients;
ignore client-updates;
}


DNS
Back up the the Bind configuration on the master:

# cp /var/named/chroot/etc/named.caching-nameserver.conf /var/named/chroot/etc/named.caching-nameserver.conf.orig

Edit the configuration to reflect the config below.

options {
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
query-source port 53;
query-source-v6 port 53;
allow-query { localhost; localnets; };
};
include "/etc/rndc.key";
include "/etc/named.rfc1912.zones";
zone "home.topdog-software.com" {
type master;
file "data/home.topdog-software.com.hosts";
allow-transfer { 192.168.1.3; };
allow-update { key "rndckey"; };
allow-query { any; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "data/1.168.192.in-addr.arpa.hosts";
allow-transfer { 192.168.1.3; };
allow-update { key "rndckey"; };
allow-query { any; };
};

Back up the the Bind configuration on the slave:

# cp /var/named/chroot/etc/named.caching-nameserver.conf /var/named/chroot/etc/named.caching-nameserver.conf.orig

Edit the configuration to reflect the config below.

options {
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
query-source port 53;
query-source-v6 port 53;
allow-query { localhost; localnets; };
};
include "/etc/rndc.key";
include "/etc/named.rfc1912.zones";
zone "home.topdog-software.com" {
type slave;
masters { 192.168.1.2; };
file "data/home.topdog-software.com.hosts";
};
zone "1.168.192.in-addr.arpa" {
type slave;
masters { 192.168.1.2; };
file "data/1.168.192.in-addr.arpa.hosts";
};

Create the zone files on the master



  • /var/named/chroot/var/named/data/home.topdog-software.com.hosts
    $ORIGIN .
    $TTL 38400
    home.topdog-software.com IN SOA ns1.home.topdog-software.com. andrew.topdog.za.net. (
    2008061629 ; serial
    10800 ; refresh (3 hours)
    3600 ; retry (1 hour)
    604800 ; expire (1 week)
    38400 ; minimum (10 hours 40 minutes)
    )
    NS ns1.home.topdog-software.com.
    NS ns2.home.topdog-software.com.
    ns1 IN A 192.168.1.2
    ns2 IN A 192.168.1.3


  • /var/named/chroot/var/named/data/1.168.192.in-addr.arpa.hosts
    $ORIGIN .
    $TTL 38400 ; 10 hours 40 minutes
    1.168.192.in-addr.arpa IN SOA ns1.home.topdog-software.com. andrew.topdog.za.net. (
    2008061644 ; serial
    10800 ; refresh (3 hours)
    3600 ; retry (1 hour)
    604800 ; expire (1 week)
    38400 ; minimum (10 hours 40 minutes)
    )
    NS ns1.home.topdog-software.com.
    NS ns2.home.topdog-software.com.
    2 IN PTR ns1.home.topdog-software.com.
    3 IN PTR ns2.home.topdog-software.com.




NTP

NTP is required because the two DHCP servers need to be in sync for fail over as well as DDNS to take place. You can run a full fledged NTP server if you want, i will only provide you with instructions on using cron to sync NTP to an external NTP server every hour. You need to do this on BOTH servers.



  • create a file /etc/cron.hourly/timesync and add the following:

    #!/bin/bash
    #
    ntpdate -s 0.rhel.pool.ntp.org


  • make the file executable and run it for the first time:
    # /etc/cron.hourly/timesync



Finally
Well we are done, let's fire up the services and begin testing.



  • on the master:
    # service named start

    # service dhcpd start


  • on the slave:
    # service named start

    # service dhcpd start




You should see the following in your logs on the master:

Jun 16 13:58:56 kudusoft dhcpd: failover peer home-net: I move from recover to startup
Jun 16 13:58:56 kudusoft dhcpd: dhcpd startup succeeded
Jun 16 13:58:56 kudusoft dhcpd: failover peer home-net: I move from startup to recover
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: peer moves from unknown-state to recover
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: requesting full update from peer
Jun 16 13:59:12 kudusoft dhcpd: Sent update request all message to home-net
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: peer moves from recover to recover
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: requesting full update from peer
Jun 16 13:59:12 kudusoft dhcpd: Update request all from home-net: sending update
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: peer update completed.
Jun 16 13:59:12 kudusoft dhcpd: failover peer home-net: I move from recover to recover-done
Jun 16 13:59:13 kudusoft dhcpd: Sent update done message to home-net
Jun 16 13:59:13 kudusoft dhcpd: failover peer home-net: peer moves from recover to recover-done
Jun 16 13:59:13 kudusoft dhcpd: failover peer home-net: I move from recover-done to normal
Jun 16 13:59:13 kudusoft dhcpd: failover peer home-net: peer moves from recover-done to normal
Jun 16 13:59:14 kudusoft dhcpd: pool 914eb10 192.168.1/24 total 26 free 25 backup 0 lts -12
Jun 16 13:59:14 kudusoft dhcpd: pool 914eb10 192.168.1/24 total 26 free 25 backup 0 lts 12

And on the slave:

Jun 16 13:59:12 shaka dhcpd: Sending on   Socket/fallback/fallback-net
Jun 16 13:59:12 shaka dhcpd: failover peer home-net: I move from recover to startup
Jun 16 13:59:12 shaka dhcpd: failover peer home-net: peer moves from unknown-state to recover
Jun 16 13:59:12 shaka dhcpd: dhcpd startup succeeded
Jun 16 13:59:12 shaka dhcpd: failover peer home-net: requesting full update from peer
Jun 16 13:59:12 shaka dhcpd: failover peer home-net: I move from startup to recover
Jun 16 13:59:12 shaka dhcpd: Sent update request all message to home-net
Jun 16 13:59:12 shaka dhcpd: Sent update done message to home-net
Jun 16 13:59:12 shaka dhcpd: Update request all from home-net: nothing pending
Jun 16 13:59:12 shaka dhcpd: failover peer home-net: peer moves from recover to recover-done
Jun 16 13:59:14 shaka dhcpd: failover peer home-net: peer update completed.
Jun 16 13:59:14 shaka dhcpd: failover peer home-net: I move from recover to recover-done
Jun 16 13:59:14 shaka dhcpd: failover peer home-net: peer moves from recover-done to normal
Jun 16 13:59:14 shaka dhcpd: failover peer home-net: I move from recover-done to normal
Jun 16 13:59:14 shaka dhcpd: pool 9d78ad8 192.168.1/24 total 26 free 25 backup 0 lts 12
Jun 16 13:59:14 shaka dhcpd: pool response: 12 leases


Read more...

Securing Postgresql with Two-Factor Authentication

This tutorial will demonstrate how to secured PostgreSQL databases using two factors authentication of the WiKID strong authentication server via WFP on Linux. We assume that you have PostgreSQL and WiKID strong authentication server configured.

Configuring Postgresql

Configuring Postgresql to use PAM authentication is trivial. Edit the pg_hba.conf file to use PAM and add
an entry for PAM for the appropriate network:


host all all 192.168.0.0/24 pam postgresql

This entry specifies that all the users from the local lan (192.168.x.x) will use PAM, specifically the file postgresql which on redhat flavors is found in /etc/pam.d. We assume you have a separate line for access by applications. You don't want to break any applications that are using Postgres.


Configuring PAM

If your system does not have a package for pam_radius you can download the source from the Pam Radius website. Installation documentation is
also available.


Once installed, edit the postgresql PAM file to use radius:


#%PAM-1.0 

auth sufficient /lib/security/pam_radius_auth.so

account include system-auth

password include system-auth

session include system-auth

PAM settings vary by linux flavor, so please consult your distribution's PAM documentation.

Now edit the /etc/raddb/server file to point to your WiKID server:


# server[:port] shared_secret      timeout (s)
#127.0.0.1 secret 1
192.168.0.10 your_shared_secret 3

Configuring the WiKID Strong Authentication Server
Adding a domain to the WiKID server 

The WiKID Authentication System employs the concept of authentication domains. An authentication domain is a segmentation of authentication authority. Any given token client using the system can participate in any number of authentication domains. These domains may exist on an individual WiKID Strong Authentication Server or they may exist on separate and discrete servers (or any combination). Conversely, a WiKID Strong Authentication Server may provide authentication services for any number of discrete domains. These domains may be exclusive or inclusive of any set of token clients.


An authentication domain is initially defined by the 12-digit code used in token client provisioning. This code allows any un-configured, unrelated token client to locate and register with a particular WiKID Strong Authentication Server and domain. In practice, the 12-digit code signifies a zero-padded IP address that is Internet accessible. Optionally, if may designate a prefix in the wikidsystems.net domain. For example, a WiKID Strong Authentication Server with the public IP address of 27.232.7.14 would be directly accessible via the 12-digit code 027232007014. Using the wikidsystem.net service, codes signifying non-routable IP addresses may be used, such as 999888777666. You can also alter the DNS settings by deploying a custom jw.properties file with your software token.


Selecting the [Domains] header option will display the current domains served by this WiKID Strong Authentication Server. See Figure 1 below.




Figure 1 – Domain Configuration Screen


Selecting [Create New Domain] on this screen will allow the administrator to establish a new authentication domain for this server. The new domain parameter screen is depicted in Figure 2.



The required domain configuration options are:

Domain Name – This is a descriptive label for this domain visible only in the administration system.


Device Domain Name – This is the domain label that will appear in the menu option on the token client. This label should be relatively short to facilitate viewing on a mobile device.


Minimum PIN Length - This is the minimum allowable PIN length for this domain. Any attempt to set a pin shorter than this value will generate an error on the client token client.


Passcode Lifetime – This parameter specifies the maximum lifetime of the one-time passcode generated in this domain. After N elapsed seconds, the one-time passcode will automatically be invalidated.


Server Code – This is the zero-padded IP address of the server or the pre-registered prefix in the wikidsystems.net domain. This value must be exactly 12 digits in length.


Max Bad PIN Attempts – The maximum number of bad PINs attempted by a token client in this domain before the token is disabled.


Max Bad Passcode Attempts – The maximum number of bad passcodes entered for a userid registered in this domain before the userid is disabled.


Max Sequential Offlines – The maximum number of times a token client may use the offline challenge/response authentication before being required to authenticate online. This feature is used in the Enterprise version for the wireless clients when they are out-of-network coverage.


Use TACACS+ Select this to use TACACS+ for this domain.


Creating Network Clients

Network clients are systems that request one-time password validation from a WiKID Strong Authentication Server. These systems act in a proxy capacity, accepting questionable information from users and communicating with the WiKID Strong Authentication Server for validation.
Network clients utilize one of the installed protocol modules. The protocol module must be installed, initialized and enabled before you can configure add a network client for it.


Each network client must be configured on the WiKID Strong Authentication Server before it will allow the client to request validation.
Figure 3 shows the initial network client screen.




Initial Network Client Screen


Select – Create new Network Client - to begin adding a network client. You will be presented with a screen similar to Figure 4 below.






Network Client Properties Screen


These are the general network client properties. These values are required for each network client configured, regardless of the protocol selected. Property definitions are:


Name – The descriptive name of the server. This will be the primary display name in the administrative system and in system logs and reports. It is recommended that you use a combination of hostname, and WiKID domain for clarity.


IP Address – The IP address of the network client.


Protocol – The communications protocol used by this network client. Only protocols previously enabled will be available. The protocol selection will dictate the additional properties that must be defined for this client. In this instance, choose Radius.


Domain – This is the WiKID authentication domain in which this client will request credential validation. Your postgresql administrators will need to have their tokens registered in this domain.


Radius traffic is encoded by a shared secret, so we need to enter the same shared secret here as we entered on Postgresql server's /etc/raddb/server file:


That's it! To access Postgresql from the command line or from any GUI interface will require a one-time passcode from the WiKID Strong Authentication server.


Read more...

Install MySQL Proxy On CentOS

This tutorial explains how you can install MySQL Proxy on a CentOS 5 (x86_64). MySQL Proxy is a simple program that sits between your client and MySQL server that can monitor, analyze and transform their communication. Its flexibility allows an unlimited number of uses; common include: load balancing, failover; query analysis, filtering and application modification, and many others.

At a minimum Centos 5 final x86_64 install:

yum
install gcc.x86_64 libevent.x86_64 libevent-devel.x86_64
readline.x86_64 readline-devel.x86_64 ncurses.x86_64
ncurses-devel.x86_64 glib2.x86_64 glib2-devel.x86_64


cd /usr/local/src/


wget http://www.lua.org/ftp/lua-5.1.3.tar.gz

tar zxvf lua-5.1.3.tar.gz


cd lua-5.1.3

make linux

make install


wget
http://dev.mysql.com/get/Downloads/MySQL-Cluster-6.2/mysql-5.1.23-ndb-6.2.15-linux-x86_64-glibc23.tar.gz/\
from/http://www.mirrorservice.org/sites/ftp.mysql.com/


tar xzvf mysql-5.1.23-ndb-6.2.15-linux-x86_64-glibc23.tar.gz

ln -s mysql-5.1.23-ndb-6.2.15-linux-x86_64-glibc23 mysql

PATH=$PATH:/usr/local/mysql/bin

export PATH


Edit your .profile to make this permanent:


# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:/usr/local/mysql/bin:$HOME/bin

export PATH
unset USERNAME

wget
http://dev.mysql.com/get/Downloads/MySQL-Proxy/mysql-proxy-0.6.1.tar.gz/from/http://www.mirrorservice.org/sites/ftp.mysql.com/


tar zxvf mysql-proxy-0.6.1.tar.gz

cd mysql-proxy-0.6.1


./configure LDFLAGS="-lm -ldl" LUA_CFLAGS="-I/usr/local/include/" LUA_LIBS=/usr/local/lib/liblua.a


make

make install


Let's create a sample LUA script so you can see some logs.


mkdir /var/log/mysql-proxy/

mkdir -p /usr/local/mysql/lua-scripts/


vi /usr/local/mysql/lua-scripts/simple-log.lua




Script modified to get IP and to use proxy.connection.server.thread_id.)


local log_file = '/var/log/mysql-proxy/mysql.log'
local fh = io.open(log_file, "a+")

function read_query( packet )
if string.byte(packet) == proxy.COM_QUERY then
local query = string.sub(packet, 2)
fh:write( string.format("%s %6d -- %s :IP %s :USER: %s\n",
os.date('%Y-%m-%d %H:%M:%S'),
proxy.connection.server.thread_id,
query,
proxy.connection.client.address,
proxy.connection.client.username))
fh:flush()
end
end

Now start up your proxy using the variable --proxy-backend-addresses to point the proxy at your servers.


/usr/local/sbin/mysql-proxy
--proxy-lua-script=/usr/local/mysql/lua-scripts/simple-log.lua
--proxy-backend-addresses=192.168.1.33:3306
--proxy-backend-addresses=192.168.1.34:3306 --daemon


192.168.1.33 and 192.168.1.34 are the MySQL nodes that the proxy will be connecting to.


Allow connections for the proxy through your firewall:


### ALLOWED TO CONNECT TO MYSQL PROXY
###
### LOCAL ADMINS
-A INPUT -s SRC-IP -d DST-IP -p tcp -m state --state NEW -m tcp --dport 4040 -j ACCEPT

Where DST-IP is my proxy server and SRC-IP is my local box (client machine).


Now
from your local box (not the mysql-proxy server) try and connect to the
backend databases through the proxy ( user with relevent permissions
must exist in the db).


mysql -u dba_admin -p -h PROXY-SERVER -P 4040


Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 16 to server version: 5.1.23-ndb-6.2.15

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.


mysql> show databases;



+--------------------+
| Database |
+--------------------+
| information_schema |
| Imap_Forms |
| mysql |
| test |
+--------------------+

4 rows in set (0.01 sec)


mysql> quit


Bye


N.B. The proxy uses the port 4040 instead of 3306.


Test the mysql-proxy admin interface from the mysql-proxy server:


mysql -u root -p -h 127.0.0.1 -P 4041


Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.1.20-agent MySQL Enterprise Agent

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.


mysql> select * from proxy_connections;


+------+--------+-------+------+
| id | type | state | db |
+------+--------+-------+------+
| 0 | server | 0 | |
| 1 | proxy | 0 | |
| 2 | server | 10 | |
+------+--------+-------+------+

3 rows in set (0.00 sec)


mysql>quit


bye


Job done! Now read on:




Read more...

Intrusion Detection For PHP

This tutorial explains how to set up PHPIDS on a web server with Apache2 and PHP5. PHPIDS (PHP-Intrusion Detection System) is a simple to use, well structured, fast and state-of-the-art layer of security for your PHP based web application. The IDS or bands or filters sanitizes any malicious input, it recognizes when an attacker tries to break your site and reacts exactly how you want. On the basis of a set of highly approved and tested filtering rules any attack is a digital impact rating which makes it easy to decide what type of action should follow the hacking attempt. It may be the simple logging to send an urgent email to the development team, displaying a warning message to the attacker or even to terminate the user session.


1 Preliminary Note

I have tested this on a Debian Etch LAMP system with Apache2 and PHP5 and the IP address 192.168.0.100. The Apache user and group on Debian Etch is www-data, so if you are on a different distribution, the Apache user and group might be different. The location of php.ini (/etc/php5/apache2/php.ini on Debian Etch) might differ as well.


I'm using a virtual host with the document root /var/www/web1/web in this example.

2 Installing PHPIDS
For security reasons, I want to install PHPIDS outside of the document root, so I create the directory /var/www/web1/phpids:

mkdir /var/www/web1/phpids

Then I install PHPIDS as follows (at the time of this writing the latest version was 0.4.7) - of all the contents of the phpids-0.4.7.tar.gz file, we only need the lib/ directory:


cd /tmp

wget http://php-ids.org/files/phpids-0.4.7.tar.gz

tar xvfz phpids-0.4.7.tar.gz

cd phpids-0.4.7

mv lib/ /var/www/web1/phpids/

Now I change to the directory /var/www/web1/phpids/lib/IDS...


cd /var/www/web1/phpids/lib/IDS

... and make the tmp/ directory (which will hold the PHPIDS log file) writable for the Apache user and group:

chown -R www-data:www-data tmp/

Next we configure the PHPIDS configuration file (Config.ini):

cd Config/

vi Config.ini


I'm using the default configuration here, all I did was to adjust the paths:

; PHPIDS Config.ini

; General configuration settings

; !!!DO NOT PLACE THIS FILE INSIDE THE WEB-ROOT IF DATABASE CONNECTION DATA WAS ADDED!!!

[General]

filter_type = xml
filter_path = /var/www/web1/phpids/lib/IDS/default_filter.xml
tmp_path = /var/www/web1/phpids/lib/IDS/tmp
scan_keys = false

exceptions[] = __utmz
exceptions[] = __utmc

; If you use the PHPIDS logger you can define specific configuration here

[Logging]

; file logging
path = /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

; email logging

; note that enabling safemode you can prevent spam attempts,
; see documentation
recipients[] = test@test.com.invalid
subject = "PHPIDS detected an intrusion attempt!"
header = "From: <PHPIDS> info@php-ids.org"
safemode = true
allowed_rate = 15

; database logging

wrapper = "mysql:host=localhost;port=3306;dbname=phpids"
user = phpids_user
password = 123456
table = intrusions

; If you would like to use other methods than file caching you can configure them here

[Caching]

; caching: session|file|database|memcached|none
caching = file
expiration_time = 600

; file cache
path = /var/www/web1/phpids/lib/IDS/tmp/default_filter.cache

; database cache
wrapper = "mysql:host=localhost;port=3306;dbname=phpids"
user = phpids_user
password = 123456
table = cache

; memcached
;host = localhost
;port = 11211
;key_prefix = PHPIDS
;tmp_path = /var/www/web1/phpids/lib/IDS/tmp/memcache.timestamp


3 Using PHPIDS
We will now create the file /var/www/web1/web/phpids.php which will call PHPIDS for us (we will later on prepend that file to all our PHP files so that our PHP files can make use of PHPIDS automatically):


vi /var/www/web1/web/phpids.php

<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/web1/phpids/lib'
);

require_once 'IDS/Init.php';
$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init('/var/www/web1/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// Take a look at the result object
echo $result;
require_once 'IDS/Log/File.php';
require_once 'IDS/Log/Composite.php';

$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);
}
?>


Now when you call that file in a browser, (e.g. http://192.168.0.100/phpids.php), you will see a blank page. But if you try to append some malicious parameters to the URL (e.g. http://192.168.0.100/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E), PHPIDS will detect this and print its findings in the browser:


Now we have to find a way to make our PHP scripts use PHPIDS. Of course, you don't want to modify all your PHP scripts (you could have hundreds of them...). Fortunately, there's a better way: we can tell PHP to prepend a PHP script whenever a PHP script is called. For example, if we call the script info.php in a browser, PHP would first execute phpids.php and then info.php, and we don't even have to modify info.php.

We can do this by using PHP's auto_prepend_file parameter. We can either set this in our php.ini (this is a global setting which is valid for all PHP web sites on the server), or in an .htaccess file (this is a setting valid only for the web site in question):




php.ini
Open your php.ini (e.g. /etc/php5/apache2/php.ini), and set auto_prepend_file to /var/www/web1/web/phpids.php:

vi /etc/php5/apache2/php.ini

[...]
auto_prepend_file = /var/www/web1/web/phpids.php
[...]

Restart Apache afterwards:

/etc/init.d/apache2 restart

.htaccess
Instead of modifying php.ini (which is a global change, i.e., the change is valid for all web sites that use PHP on the server), you can instead use an .htaccess file (so the setting would be valid only for the web site for which you create the .htaccess file):

vi /var/www/web1/web/.htaccess

php_value auto_prepend_file /var/www/web1/web/phpids.php

Please make sure that the vhost for the web site in /var/www/web1/web contains something like this (otherwise the php_value line in the .htaccess file will be ignored) (if you have to modify the vhost, please don't forget to restart Apache):


<Directory /var/www/web1/web/>
AllowOverride All
</Directory>




Now we create a simple PHP file, /var/www/web1/web/info.php:


vi /var/www/web1/web/info.php

<?php
phpinfo();
?>


Call that file in a browser (http://192.168.0.100/info.php), and you should see the normal phpinfo() output.

Now append some malicious parameters to the URL (e.g. http://192.168.0.100/info.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E), and you should find a PHPIDS report before the phpinfo() output (because /var/www/web1/web/phpids.php was executed before /var/www/web1/web/info.php):


PHPIDS logs to /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt, so you should see something in the log now:

cat /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

"192.168.0.200",2008-06-04T17:36:08+02:00,54,"xss csrf id rfe lfi","REQUEST.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E GET.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E",
"%2Finfo.php%3Ftest%3D%2522%253EXXX%253Cscript%253Ealert%281%29%253C%2Fscript%253E"

Now by observing that log you learn what hackers are trying to do to your PHP applications, and you can try to harden your applications.

To add another level of security, we can stop our PHP scripts from executing if PHPIDS find that they are under attack: we simply add something like die('<h1>Go away!</h1>'); to the if (!$result->isEmpty()) {} section of the /var/www/web1/web/phpids.php script:


vi /var/www/web1/web/phpids.php

<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/web1/phpids/lib'
);

require_once 'IDS/Init.php';
$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init('/var/www/web1/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// Take a look at the result object
echo $result;
require_once 'IDS/Log/File.php';
require_once 'IDS/Log/Composite.php';

$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);

die('<h1>Go away!</h1>');
}
?>


If there's no attack, the scripts are executed, but if PHPIDS finds an attack, it prevents the scripts from being executed and displays a message to the hackers:


4 Links


Read more...