Tisztában vagyok vele, hogy a leírás alapján létrehozott szerver hemzseg a biztonsági hibáktól! (plaintext jelszavak ... stb.) Ezen okok miatt jelen formájában éles környezetben nem ajánlott használni a lent leírtakat!
A vas egy P4 Celeron 2GHz -es 3GB RAM-mal rendelkező "erőgép", két hálókártyával. Az eth0 a WAN felőli oldal, az eth1 a belső hálózat
Az alap rendszer egy Debian 5.0, alap telepítés.
Első lépésben állítsuk be a WAN oldalt, hogy szegény proxynak legyen mit szűrnie illetve szétosztania.
Ezt követően konfiguráljuk a LAN oldalt.
/etc/network/interfaces
auto eth1 allow-hotplug eth1 iface eth1 inet static address 10.10.10.1 netmask 255.255.255.0 network 10.10.10.0 broadcast 10.10.10.255 |
A proxynak DHCP szerver szerep is jut. A pehelysúlyú dnsmasq a megfelelő megoldás erre a feladatra.
$ apt-get install dnsmasq |
/etc/dnsmasq.conf
interface=eth1 dhcp-range=10.10.10.10,10.10.10.150,255.255.255.0,12h |
/etc/init.d/firewall.sh
#!/bin/bash echo 1 >> /proc/sys/net/ipv4/ip_forward iptables -F iptables -X iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth1 -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -j DROP iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -o eth1 -j ACCEPT iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -j DROP iptables -A FORWARD -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT iptables -A FORWARD -j DROP iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE |
Beállítjuk, hogy minden indulásnál automatikusan fusson.
$ update-rc.d firewall.sh defaults |
Szükségünk lesz valamilyen adatbázisra, hogy nyilvántartsuk a jogosult felhasználókat és a bejelentkezéseket. A több megoldási lehetőség közül válasszuk a mysql-t.
$ apt-get install mysql-server-5 |
A lementett adatbázis szerkezet:
auth.sql
-- -- Table structure for table `loggedin_users` -- DROP TABLE IF EXISTS `loggedin_users`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; CREATE TABLE `loggedin_users` ( `ip_address` varchar(100) NOT NULL, `logintime` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP ) ENGINE=MyISAM DEFAULT CHARSET=latin1; SET character_set_client = @saved_cs_client; -- -- Table structure for table `users` -- DROP TABLE IF EXISTS `users`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; CREATE TABLE `users` ( `name` varchar(100) NOT NULL, `password` varchar(100) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; SET character_set_client = @saved_cs_client; |
Visszatöltjük az adatbázist:
mysql> CREATE DATABASE auth_db; mysql> USE auth_db; mysql> source auth.sql |
Töltünk néhány tesztadatot az users táblába és továbblépünk a webszerver telepítéséhez.
$ apt-get install apache2 |
Létrehozzuk a jelszó bekérő oldalt:
/var/www/index.php
<?php session_start(); $sql_username = "root"; // a MySQL felhasználó $sql_password = "password"; // jelszó $sql_host = "localhost"; // a kiszolgáló $sql_db_name = "auth_db"; // adatbáis neve $sql_connection = mysql_connect($sql_host,$sql_username, $sql_password)or die("Sikertelen kapcsolódás: " . mysql_error()); mysql_select_db($sql_db_name, $sql_connection) or die("Sikertelen adatbáis kijelölés [$sql_db_name]: " . mysql_error()); mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET 'utf8'"); mysql_query("SET COLLATION_CONNECTION='utf8_unicode_ci'"); function addTime($_timestamp,$_amount) { $time= strtotime($_timestamp) + $_amount; return date('Y-m-d H:i:s', $time); } if ($_POST["user_name"] && $_POST["password"]) { $user_query = mysql_query("SELECT password FROM users WHERE name='".$_POST['user_name']."' && password='".$_POST['password']."'") or die(mysql_error()); $rows = mysql_num_rows($user_query); if ($rows == 1) { mysql_query("INSERT INTO loggedin_users (ip_address,logintime) VALUES ('".$_SERVER['HTTP_X_FORWARDED_FOR']."','".addTime(date('Y-m-d H:i:s'),3)."')")or die(mysql_error()); $url=$_GET['url']; $url=ltrim($url,"\x5c,\x27"); $url=rtrim($url,"\x27,\x5c"); header("Location:".$url); } else { $error = "<font color=red>A felhasználónév / jelszó hibás!</font>"; } } else { $error = "<font color=red>Nem adtál meg adatokat!</font>"; } print "<html><head><script type=\"text/javascript\"> function setfocus() { document.getElementById(\"usern\").focus(); }</script><meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-2\"><title>Login</title>\n </head>"; print "<body onLoad=\"setfocus();\">\n <BR><center><font face=\"Verdana, Arial, Helvetica, sans-serif\" size=\"-2\"> <form name=\"login\" action=\"index.php?url='".$_GET['url']."'\" method=\"post\">\n <table width=\"400\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\"><tr><td colspan=\"2\">\n <br><br><br><center>$error</center><br></b></div></td></tr>\n <tr><td><div align=\"right\">Felhasználó:</div></td><td>\n <input type=\"text\" id=usern name=\"user_name\" size=\"20\" value=\"$user_name\"></td></tr><tr>\n <td><div align=\"right\">Jelszó:</div></td><td><input type=\"password\" name=\"password\" size=\"20\"></td>\n </tr><tr><td colspan=\"2\"><div align=\"center\"><input type=\"submit\" name=\"Submit\" value=\"Belép\"></div></td>\n </tr></form></table></center></font></body></html>"; ?> |
A Squid használhat külső bejelentkezési modulokat. Mi pont ezt a tulajdonságát használjuk ki, mégpedig egy PHP nyelvű script-el. Ehhez telepíteni kell a PHP környezetet.
$ apt-get install php5 $ apt-get install php5-cli $ apt-get install php5-mysql |
A script dolga csak annyi, hogy ránézzen az adatbázisra, és egy ERR vagy OK üzenettel térjen vissza, a neki beadott IP cím alapján. Tehát a Squid küld egy kérést a script-nek, a script megnézi, hogy a kért IP bejelentkezett e már. Ha igen a válasz OK ha nem akkor ERR.
/etc/squid/auth.php
<? if (! defined (STDIN)) { define ("STDIN", fopen("php://stdin","r")); } mysql_connect("localhost","root","password") or die (mysql_error()); mysql_select_db("auth_db") or die (mysql_error()); while (!feof(STDIN)) { $passed=0; $line = trim(fgets(STDIN)); $ip_address = rawurldecode($line); mysql_query("DELETE FROM loggedin_users WHERE logintime < NOW()") or die (mysql_error()); $result = mysql_query("SELECT * FROM loggedin_users") or die (mysql_error()) ; while($row = mysql_fetch_array($result)) { if($ip_address == $row['ip_address']) { $passed=$row['ip_address']; } else { $passed=0; } } if($passed==$ip_address) { fwrite(STDOUT,"OK\n"); } else { fwrite(STDOUT,"ERR\n"); } } ?> |
Végül pedig jöjjön a Squid.
$ apt-get install squid |
Az első dolgunk ezután létrehozni a két listát. A bad_domains tartalma a teljesen tiltott oldalak, a grey_domains a jelszóval elérhető oldalak.
/etc/squid/bad_domains
porn xxx torrent |
/etc/squid/grey_domains
A bejelentkezési oldal működéséhez a Squid egyik hibaoldalát alakítjuk át. Mikor az ember egy tiltott oldalra téved nem a megszokott ACCESS DENIED fogadja, hanem egy némileg módosított változata, ami tartalmazza a hivatkozást a korábban létrehozott bejelentkező oldalunkra.
/usr/share/squid/errors/English/ERR_ACCESS_DENIED
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <TITLE>Bejelentkezés</TITLE> <STYLE type="text/css"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}PRE{font-family:sans-serif}--></STYLE> </HEAD><BODY> <CENTER> <H1>ACCESS DENIED</H1> <H2>Az oldal tiltott!!</H2> <HR noshade size="1px"> <P> <A HREF="%U">%U</A> <P> <STRONG> <A HREF='http://10.10.10.1/index.php?url=%U'>Ha van jogosultságod jelentkezz be!</A> </STRONG><BR> <P> </UL> </CENTER> |
Végül a Squid konfigurációs beállításaival működésbe hozzuk a proxy-t.
/etc/squid/squid.conf
... # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS # Example rule allowing access from your local networks. # Adapt localnet in the ACL section to list your (internal) IP networks # from where browsing should be allowed #http_access allow localnet http_access allow localhost external_acl_type time_auth ttl=5 %SRC /usr/bin/php /etc/squid/auth.php acl interval_auth external time_auth acl BAD_DOMAINS dstdom_regex -i "/etc/squid/bad_domains"; acl GREY_DOMAINS dstdom_regex -i "/etc/squid/grey_domains"; http_access deny BAD_DOMAINS http_access deny GREY_DOMAINS !interval_auth http_access allow all # And finally deny all other access to this proxy #http_access deny all ... # Squid normally listens to port 3128 http_port 3128 transparent ... |
A rendszer hozzáférést ad 3600 másodperc időtartamra a grey_domains fájlban található oldalakhoz az adatbázisban szereplő felhasználóknak, majd újra be kell jelentkezniük, ha folytatni szeretnék a munkát a közösségi oldalon. Az adatbázis bővítésével megoldható a jogosult felhasználók monitorozása is (pl.: ki mikor mennyi időt töltött el a félig tiltott oldalakon ... stb.)