综述
在上一篇文章中,客户机可以借助路由机直接上网,并没有什么登录限制。接下来我们将加入上网登录验证,只有输入了正确的用户名和密码才可以通过验证,然后才可以访问互联网。 接下来,就跟随我用 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
|
配置方式和登录一样,大家可以尝试下。
源代码
在这里提供大家源代码下载 源码下载 如有问题,欢迎交流。