综述
在上一篇文章中,客户机可以借助路由机直接上网,并没有什么登录限制。接下来我们将加入上网登录验证,只有输入了正确的用户名和密码才可以通过验证,然后才可以访问互联网。 接下来,就跟随我用 PHP 来实现登录验证吧。
环境配置
在这之前,你需要配置一下 LAMP 环境,也就是 Apache,MySQL,PHP 开发环境,依次执行如下命令即可。
1 2 3 4 5 6 7
sudo apt-get install apache2 sudo apt-get install php5 php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell php5-recode php5-snmp php5-tidy php5-xmlrpc php5-sqlite php5-xsl sudo apt-get install mysql-server mysql-client sudo apt-get install libapache2-mod-php5 sudo apt-get install libapache2-mod-auth-mysql sudo apt-get install phpmyadmin sudo ln -s /usr/share/phpmyadmin/ /var/www/html/phpmyadmin
如果配置出现问题,请查阅相关资料。 apache 默认的目录为 /var/www/html,我们这时访问 localhost 或者 192.168.122.4 ,都可以出现 apache 的欢迎界面,就证明我们配置成功了。
路由初始设置
为了在登录之前限制主机的上网,我们需要利用 iptables 规则来对数据包的转发加以限制。同时,将网页重定向到本机的登录界面。 初始路由设置如下
1 2 3 4 5 6 7 8 9
iptables -F iptables -t nat -F iptables -t mangle -F iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t filter -A FORWARD -s 192.168.122.0/24 -o eth0 -j REJECT iptables -t filter -A FORWARD -s 192.168.122.0/24 -d 119.29.29.29/32 -j ACCEPT iptables -t nat -A PREROUTING -s 192.168.122.0/24 -p tcp -j DNAT --to 192.168.122.4
首先清除所有的 iptables 规则,然后设置前一篇我们说的 IP 伪装,这时可以客户机可以通过主机上网。 接下来的一条规则则禁用了来自 192.168.122.0 网段的所有 IP 的数据包转发,然后设置可访问 DNS 服务器,最后一条则设置了所有的 tcp 连接自动跳转到 192.168.122.4,也就是我们刚才配置的服务器。 可以把以上规则保存为脚本,比如叫 init.sh 来运行,也可以添加到 /etc/rc.local 中,开机自动运行。
登录页面
访问到 192.168.122.4 时,我们需要给用户呈现的当然不是刚才显示的 apache 欢迎页面,而是登录的输入框以及登录按钮界面。 所以,登录界面代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
<!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="utf-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1" > <title > Auth Login</title > <link rel ="stylesheet" href ="css/bootstrap.min.css" > </head > <body > <form id ="auth" method ="post" > <div class ="input-group" > <span class ="input-group-addon" id ="basic-addon1" > Username</span > <input type ="text" class ="form-control" placeholder ="Username" aria-describedby ="basic-addon1" name ="username" > </div > <div class ="input-group" > <span class ="input-group-addon" id ="basic-addon1" > Password</span > <input type ="text" class ="form-control" placeholder ="Password" aria-describedby ="basic-addon1" name ="password" > </div > <input type ="button" id ="login" class ="btn btn-primary" value ="Login" > <input type ="button" id ="logout" class ="btn btn-primary" value ="Logout" > </form > <script src ="js/jquery.min.js" > </script > <script src ="js/bootstrap.min.js" > </script > </body > <style > form { max-width :400px ; margin :0 auto ; } .input-group { margin-bottom :20px ; } </style > <script > $(function ( ) { $("#login" ).on("click" , function ( ) { $("#auth" ).attr("action" , "/login.php" ); $("#auth" ).submit(); }); $("#logout" ).on("click" , function ( ) { $("#auth" ).attr("action" , "/logout.php" ); $("#auth" ).submit(); }); }); </script > </html >
其中的 js,jquery 文件请大家自行引入。 预览一下效果 在这里我们设置了两个按钮,一个是登录,一个是下线。
数据库查询验证
接下来我们新建一个数据库,例如我新建了一个数据库叫 auth,然后数据表 user,里面有三个字段。分别是 id,username,password,我插入了一条数据。 接下来我们就尝试一下登录,提交到 login.php 文件验证一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
<?php $mysql_server_name = "localhost" ; $mysql_username = "root" ; $mysql_password = "123456" ; $mysql_database = "auth" ; $username = @$_POST['username' ]; $password = @$_POST['password' ]; $ip=$_SERVER["REMOTE_ADDR" ]; $conn=mysql_connect($mysql_server_name, $mysql_username, $mysql_password); if ($conn) { $sql = "select * from user where username = '" .$username."'" ; $result = mysql_fetch_array(mysql_db_query($mysql_database, $sql, $conn)); if ($result) { if ($result['password' ] == $password) { $status = -1 ; system("sudo ./bash/login.sh $ip" , $status); if ($status == 0 ) { echo "Login Successfully" ; } else { echo "Login Failed" ; } } else { echo "Wrong Password" ; } } else { echo "Not" ; } } else { die ("Could Not Connect" ); } ?>
其中,最重要的部分莫过于
1
system ("sudo ./bash/login.sh $ip" , $status);
这一行代码了,此处便是登录验证用户名和密码之后执行的一个 Linux 脚本命令。 在这里我把要执行的脚本写入了 login.sh 文件中,传入的参数便是 ip 地址。 那么 login.sh 里面发生了什么事情呢,我们来看一下。
1 2 3 4 5 6
iptables -t nat -D PREROUTING -s $1 /32 -j ACCEPT iptables -t nat -D PREROUTING -s $1 /32 -p tcp -j ACCEPT iptables -t filter -D FORWARD -s $1 /32 -o eth0 -j ACCEPT iptables -t nat -I PREROUTING -s $1 /32 -j ACCEPT iptables -t nat -I PREROUTING -s $1 /32 -p tcp -j ACCEPT iptables -t filter -I FORWARD -s $1 /32 -o eth0 -j ACCEPT
$1 的意思就是获取第一个参数,在这里就是 IP 地址,脚本主要做的事情就是放行来自这个 IP 地址的数据包,让其正常访问互联网。 保存脚本后,记得给脚本赋予权限
1
sudo chmod 777 login.sh
-D 的意思就是删除,因为 iptables 是可以添加多次相同的规则的,在添加之前删除一下,以防止多次添加。 在这里
1
sudo ./bash/login.sh $ip
执行命令脚本前,我们加了 sudo,意思就是管理员身份运行,但是仍然可能导致权限问题,因为命令的执行者是 PHP(其实是 www-data),而并不是 root 用户,所以我们需要修改一下执行权限。 首先通过 PHP 文件获取执行该命令的用户是叫什么,比如新建一个 info.php 文件,输入如下内容:
1 2 3
<?php echo shell_exec("id -a" ); ?>
看一下运行结果 嗯,果然,执行用户是 www-data,这样我们只需要给 www-data 添加一个执行权限就好了。 修改 /etc/sudoers 文件 添加一行
1
www-data ALL =(ALL ) NOPASSWD:ALL
意思是 www-data 以 root 身份运行并且不需要密码。 好,保存之后,我们尝试一下,就可以登录啦。
测试登录
在路由主机(Ubuntu Route)里面,初始化一下 iptables 规则,然后查看当前规则。 我们发现当前访问都是被阻止的,而且 tcp 连接会自动跳转到 192.168.122.4 现在我们登录客户机,随机打开一个网址,比如百度,就发现自动跳转到了登录界面 输入用户名密码,尝试登陆,比如之前插入数据库的是 cqc,123456,输入之后登录。 提示登录成功之后,我们便可以欢乐地上网啦。 好,这样我们就完成了验证之后上网啦。
下线操作
同样的,下线操作我们同样写一个 logout.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
<?php $mysql_server_name = "localhost" ; $mysql_username = "root" ; $mysql_password = "123456" ; $mysql_database = "auth" ; $username = @$_POST['username' ]; $password = @$_POST['password' ]; $ip=$_SERVER["REMOTE_ADDR" ]; echo $ip; $conn=mysql_connect($mysql_server_name, $mysql_username, $mysql_password); if ($conn) { $sql = "select * from user where username = '" .$username."'" ; $result = mysql_fetch_array(mysql_db_query($mysql_database, $sql, $conn)); if ($result) { if ($result['password' ] == $password) { $status = -1 ; system("sudo ./bash/logout.sh $ip" , $status); if ($status == 0 ) { echo "Login Successfully" ; } else { echo "Login Failed" ; } } else { echo "Wrong Password" ; } } else { echo "Not" ; } } else { die ("Could Not Connect" ); } ?>
登出的脚本如下,其实就是单纯去除了刚才添加的路由规则
1 2 3
iptables -t nat -D PREROUTING -s $1 /32 -j ACCEPT iptables -t nat -D PREROUTING -s $1 /32 -p tcp -j ACCEPT iptables -t filter -D FORWARD -s $1 /32 -o eth0 -j ACCEPT
配置方式和登录一样,大家可以尝试下。
源代码
在这里提供大家源代码下载 源码下载 如有问题,欢迎交流。