0%

计算机网络探究二之利用PHP实现登录验证之后上网

综述

在上一篇文章中,客户机可以借助路由机直接上网,并没有什么登录限制。接下来我们将加入上网登录验证,只有输入了正确的用户名和密码才可以通过验证,然后才可以访问互联网。 接下来,就跟随我用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>

<!-- Bootstrap -->
<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>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<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文件请大家自行引入。 预览一下效果 20151008151728 在这里我们设置了两个按钮,一个是登录,一个是下线。

数据库查询验证

接下来我们新建一个数据库,例如我新建了一个数据库叫auth,然后数据表user,里面有三个字段。分别是id,username,password,我插入了一条数据。 20151008152059 接下来我们就尝试一下登录,提交到 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");
?>

看一下运行结果 20151008153424 嗯,果然,执行用户是www-data,这样我们只需要给www-data添加一个执行权限就好了。 修改 /etc/sudoers 文件 添加一行

1
www-data ALL=(ALL) NOPASSWD:ALL

意思是www-data以root身份运行并且不需要密码。 20151008153700 好,保存之后,我们尝试一下,就可以登录啦。

测试登录

在路由主机(Ubuntu Route)里面,初始化一下iptables规则,然后查看当前规则。 我们发现当前访问都是被阻止的,而且tcp连接会自动跳转到 192.168.122.4 20151008154216 现在我们登录客户机,随机打开一个网址,比如百度,就发现自动跳转到了登录界面 20151008154629 输入用户名密码,尝试登陆,比如之前插入数据库的是cqc,123456,输入之后登录。 20151008162712 提示登录成功之后,我们便可以欢乐地上网啦。 20151008162926 好,这样我们就完成了验证之后上网啦。

下线操作

同样的,下线操作我们同样写一个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

配置方式和登录一样,大家可以尝试下。

源代码

在这里提供大家源代码下载 源码下载 如有问题,欢迎交流。