Link to home
Start Free TrialLog in
Avatar of Cartell
Cartell

asked on

Adding iptables rules with PHP?

I'm trying to figure out a way to ban IPs with iptables automatically with PHP. Is it possible to use PHP to run iptables commands? I've tried this:

<?php
echo shell_exec('iptables --list');
?>

But it doesn't return anything. I've tried other commands like "ls" and it works fine, but anything related to iptables and it doesn't return anything (so I'm guessing it's not running the command).
Avatar of arober11
arober11
Flag of United Kingdom of Great Britain and Northern Ireland image

Hi, "iptables" needs to be run as root, so unless your web-server is running as root it isn't going to work, and if it is you have a security hole. Not to mention you'll probably find iptables is not in your Web servers $PATH.

Anyway if your planning to allow a user other than root to ban IP's / list rules, you'll want a wrapper script that only allows those specified action, and a /etc/sudoers rule to permit on or more ID's to call that script e.g.
--------
# Allow just the 'apache' user-id to run the iptables_wrapper.sh script:
apache ALL = (root) NOPASSWD: /usr/local/sbin/iptables_wrapper.sh *
---------

<?php
echo shell_exec('/usr/bin/sudo  /usr/local/sbin/iptables_wrapper.sh ');
?>

Where:  /usr/local/sbin/iptables_wrapper.sh
--
#!/bin/sh
# Name: iptables_list_wrapper.sh
# Purpose: Provide limited  access to IPtables, to permit rules to be listed of an IP blocked

usage (){
  echo "Usage: iptables_wrapper.sh [IP_TO_BAN]"
}

if [ $# -eq 0 ]
then
  /usr/sbin/iptables --list
else
   echo $1 | (egrep "^[0-9]+\.[0-9]+\.[0-9]+.[0-9]+$" > /dev/null && /usr/sbin/iptables -A INPUT -s $1 -j DROP )|| usage
fi
---

Don't forget to:

chmod 744 /usr/local/sbin/iptables_wrapper.sh
chown root /usr/local/sbin/iptables_wrapper.sh
Avatar of Cartell
Cartell

ASKER

For some reason, sudo doesn't seem to be working at all. I've been trying to get it work for the past 30 minutes. I've tried adding all sorts of different variations to sudoers file, including giving complete sudo access to "nobody" and "apache", but still doing any php command with sudo returns nothing.

I did a "whoami" command with php and it returns "nobody", and tried giving sudo access to that but no luck. I've tried at least 5 different variations to add to the sudoers file, still no luck.
Just to make sure you are going in the right direction,is the script you want going to be run from a web page,or periodically as a cron job?Because if it is going to be run as a cron,none of these above applie...Do you want IP to be banned based on some kind of cryteria,and if yes,which on?
Is there anything in the Apache error log?

Can you do a:
 ls -l `which sudo`  

 e.g.
-rwsr-xr-x 1 root root 190248 2010-03-01 11:26 /usr/bin/sudo

Is the sticky bit set '-rws' rather than '-rwx'?
Avatar of Cartell

ASKER

Nothing in the error log, and it's -rwx

I can use sudo fine when I'm on SSH, but not with PHP.

pingvinos:
I'm more interested in having it ban from a webpage, I made some PHP code to detect if it's a DoS bot, but I need it to ban the IP with iptables after it detects it.

If this could be easier with a cron job, I could make it save the IP in a text file and have a cron job check that text file to ban the ips, but the webpage one would be a lot more efficient considering it would ban right on the spot instead of the cronjob waiting 5-10 minutes to check if it should ban.
ASKER CERTIFIED SOLUTION
Avatar of arober11
arober11
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Cartell

ASKER

root@ragemachine [/usr/bin]# grep nobody /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
root@ragemachine [/usr/bin]# grep nobody /etc/sudoers
nobody ALL = (root) NOPASSWD: ALL
root@ragemachine [/usr/bin]# su nobody -c '/usr/bin/sudo  /usr/local/sbin/iptables_wrapper.sh'
This account is currently not available.


So I should edit /etc/passwd?
Ok, temporarily

usermod -s /bin/bash nobody

And give the script another go.
Avatar of Cartell

ASKER

Now the error is:
sudo: must be setuid root
Avatar of Cartell

ASKER

Fixed that error, but another one was waiting:


root@ragemachine [~]# sudo su root -c "/usr/bin/sudo whoami"
root
root@ragemachine [~]# sudo su nobody -c "/usr/bin/sudo whoami"
sudo: sorry, you must have a tty to run sudo
Your syntax is incorrect, try the following as root:

su nobody -c 'whoami'
su nobody -c '/usr/bin/sudo  whoami'
su nobody -c '/usr/bin/sudo  /usr/local/sbin/iptables_wrapper.sh'
/usr/local/sbin/iptables_wrapper.sh

Note:
"su nobody"             - creates a New shell owned by "nobody"
"-c  <command>"     - Details the command you want to be run in the newly created shell.
"/usr/bin/sudo"        - Try's to run a command, as root, from the newly created 'nobody' shell.
Avatar of Cartell

ASKER


root@ragemachine [/usr/local/sbin]# su nobody -c 'whoami'
nobody
root@ragemachine [/usr/local/sbin]# su nobody -c '/usr/bin/sudo  whoami'
sudo: sorry, you must have a tty to run sudo
root@ragemachine [/usr/local/sbin]# su nobody -c '/usr/bin/sudo  /usr/local/sbin/iptables_wrapper.sh'
sudo: sorry, you must have a tty to run sudo
root@ragemachine [/usr/local/sbin]# /usr/local/sbin/iptables_wrapper.sh
Chain INPUT (policy ACCEPT)
...etc [worked]...
Avatar of Cartell

ASKER

think i got it working..let me try some things on the PHP page and get back to you.
Avatar of Cartell

ASKER

alright. problem solved. got it 100% working.
Avatar of Cartell

ASKER

just as a quick question..should i make it do "service iptables save" every time it bans an ip or leave that out?
Re to save / not to save, it's up to you, how often do you re-boot your server? Do you want the bans to be permanent?

Oh, guessing it was your /etc/sudoers rules that were at fault, due to all the "sudo: sorry, you must have a tty to run sudo"