破壳32小时 了解一个网站的部署与运行机制
文字资料
大家好,要想挖掘网站的漏洞,对于网站的架构和运行机制必须有一个了解。这节课我们使用市场上最常见的LNMP架构,搭建一个开源的博客程序wordpress,通过这个过程来让大家了解网站的部署和运行。
先来说说什么是LNMP架构
LNMP分别Linux、Nginx、MySQL、PHP四个单词的缩写。分别指的是Linux系统、Web服务Nginx软件、MySQL数据库系统、PHP编程语言
Linux就不用多解释了,上节课的Kali便是一个Linux系统。接下来我们看下Nginx
Nginx在Kali系统自带有了,如果没有的话,在命令行下执行一条 apt install nginx 命令便可安装
nginx的一些目录信息如下
/etc/nginx/配置文件夹/usr/share/nginx/默认显示页面路径/usr/lib/nginx/模块依赖路径/usr/sbin/nginx可执行文件
启动nginx的命令是
service nginx start
在启动nginx之后,打开浏览器访问127.0.0.1 应该能看到如下输出
如果你有一些服务端知识经验,可能看到这个页面会疑惑,是不是什么地方错了,为什么这里显示的是apache服务器的页面
这时候我们先看一看nginx的默认配置文件,
打开 /etc/nginx/nginx.conf, 可以发现访问日志和错误日志的路径分别是
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
接着我们去查看访问日志
tail -f /var/log/nginx/access.log
然后浏览器刷新一下,看到了新访问记录,就可以证明现在运行的确是nginx
看完了nginx,我们来看下mysql。
同样的,Kali也自带了mysql服务器。直接service mysql start就可以启动,默认没有密码
如果你的kali没有,那么可以运行命令 apt install default-mysql-server 进行安装
(屏幕当前启动mysql)
我们连接mysql看一下,运行命令
mysql -u root
可以看到直接进来了,不用输入密码
为了方便后续的使用,我们先给root账户设置一个密码,因为kali内置的mysql有些特殊,所以要用下面的命令来修改密码,这里我把密码修改为123456
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION; flush privileges;
因为Kali版本和MySQL版本的原因,上面的修改密码命令可能不能正确的执行。遇到这种情况时,你可以Google uninstall mysql,找到一个方式将MySQL从你的kali上移除。
改完之后ctrl + c退出mysql
接着用 mysql -u root -p 连接mysql,输入密码就可以进去了
show databases;
可以看到mysql里有3个数据库,其实这都是默认自带的,不要直接删除和修改。对于MySQL,暂时我们就只需要了解这么多。在学习Web安全的过程中,如果有遇到其他需要对MySQL知道更多的时候,我们会在后续的课程中,与大家分享。
了解PHP和LNMP架构的网站部署
我们来看下PHP
Kali作为对Web安全研究友好的系统,自带有PHP环境,我们输入php -v就可以得知自带的php版本是php7.2
但是,kali只默认安装了php cli环境,并没有自带php-fpm组件,php-fpm是搭建web系统常用的一个组件,需要我们输入 apt install php7.2-fpm进行安装
在安装完毕后,只需要输入 service php7.2-fpm start 便可以启动了
和nginx一样,配置文件放在/etc/下,具体是/etc/php/7.2/
由于我们现在使用的是php的fpm模式,所以主要看fpm下的配置
这里就不再详细说php的一些细节了,根据经验分析出fpm本身的配置在 /etc/php/7.2/fpm/pool.d/www.conf 文件里,而该文件开始位置的。
listen = /run/php/php7.2-fpm.sock
这段配置说明fpm现在用的是以UNIX Domain Socket的形式在监听,其它应用可以通过这个文件和php-fpm通讯,这行配置需要记住
还有一个要记住的配置是
user = www-data
group = www-data
这段配置是说明php-fpm是以用户组www-data的用户www-data运行的,这样做是为了限定php-fpm的权限,这样当php应用程序有漏洞的时候,对服务器的影响有所降低,起码不会是root级别的影响。
然后找一下日志相关的配置,在今后的使用中,我们可能经常需要打开日志,方便排错
# access.log = log/$pool.access.log
access.log 是访问php-fpm组件的日志,默认是被注释的,也就是没有启用日志功能
这里我们把注释符号删掉,让它起作用
改完之后我们重启一下php的fpm组件
service php7.2-fpm restart
接下来我们让nginx和php的fpm组件进行通讯,这里可以参考php官方文档
https://secure.php.net/manual/zh/install.unix.nginx.php
我们来配置Nginx,我们找到和打开/etc/nginx/nginx.conf
可以看到有2行配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
可以看到它的意思是分别是说
引入 /etc/nginx/conf.d/ 下所有扩展名是conf的文件
引入 /etc/nginx/sites-enabled/ 下所有文件
那么我们看一下 /etc/nginx/conf.d/ 文件夹,发现没有东西可以参考。我们再去到/etc/nginx/sites-enabled/
发现有一个default文件,这个是nginx默认站点配置,我们看一看,然后在上面改
可以看到一行配置
root /var/www/html;
这行配置的意思是站点根目录在 /var/www/html文件夹下
我们在下面加多一行
index index.php index.html;
这句配置是默认去寻找index.php文件,找不到index.php就去找index.html
为什么是这个文件呢,因为大部分php项目都是用index.php文件作为一个入口的,只是习惯而已
往下翻,能看到有一段被注释的php相关的配置
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
我们在下面把php官方文档的说明复制在下面,然后跟着改一下
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
这里把因为php的fpm组件现在是以socket文件通讯的,所以这里要修改的应该是
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; 这一段
还记得刚刚fpm里面的listen配置么,把我们把sock文件路径改成fpm里的sock文件路径,也就是
fastcgi_pass unix:/run/php/php7.2-fpm.sock; 以便?
然后执行 nginx -t 看一下配置有没有语法错误的地方
看到这里就应该知道配置没有语法错误,我们重启一下nginx
service nginx restart
接着我们怎么去验证nginx能和php通讯了呢?
我们去站点根目录创建一个php文件来测试
我们创建一个简单的php信息的页面,并保存为1.php
<?php
phpinfo();
?>
接下来我们访问 http://127.0.0.1/1.php 看到了一个显示php各种信息的页面,说明我们的nginx已经成功和php进行通讯了
接着我们去下载wordpress
访问
https://cn.wordpress.org/
下载代码
现在完成后,我把wordpress解压到/var/www/html文件夹下,
然后我们访问
http://127.0.0.1/wordpress/
发现已经可以看到wordpress的安装界面了
我们开始安装
我们填入数据库相关信息,其它默认
看到这个提示,指的是php现在不能创建文件,因为php-fpm现在是以www-data用户运行的。我们刚刚直接解压的行为,导致了文件夹所有权是当前用户,也就是root。要让php-fpm可以创建文件,我们要给wordpress文件夹修改一下权限。
root@kali:/var/www/html# ls -al
总用量 32
drwxr-xr-x 3 root root 4096 5月 31 16:17 .
drwxr-xr-x 3 root root 4096 4月 26 10:27 ..
-rw-r--r-- 1 root root 18 5月 31 16:12 1.php
-rw-r--r-- 1 root root 10701 4月 12 06:44 index.html
-rw-r--r-- 1 root root 612 4月 12 06:43 index.nginx-debian.html
drwxr-xr-x 5 root root 4096 2月 7 23:53 wordpress
我们给wordpress文件夹修改一下权限
chown -R www-data:www-data wordpress/
然后浏览器刷新一下,就可以开始安装了
填写之后就安装完毕了
到此,一个php博客系统wordpress就搭建完成
了解LNMP架构网站的运行
在上面的部分我们花费了很大的篇幅给大家介绍了如何部署一个Wordpress站点,那接下来我们来说说当你访问一个Wordpress站点的时候,为什么浏览器会给你访问对应的内容呢?
首先我们先来了解下Nginx的角色,Nginx或者你可能知道的IIS、Apache都是一种服务组件,他们的功能是什么呢?通俗的的解释就是,以服务形式运行,然后作为一个守护进程(守护进程的意思就是一直在执行,不退出),时刻监听着服务器指定端口(一般网站咱们采用的是80端口)的请求,当收到请求后,就根据请求的内容返回对应的内容,返回的内容就是我们前面课程已经了解的HTML、JS、CSS那些,然后由浏览器再去组织渲染展示给用户;所以你可以理解服务组件的功能一句话来解释就是监听并响应请求。
说到返回的内容,这里大家需要了解一个概念,静态网页和动态网页;像我们之前课程学到的HTML,HTML的内容都是直接写死的,这种是静态网页,Nginx在收到静态网页的请求后会直接读取静态网页的内容返回给浏览器进行渲染,这中间环节没有涉及到第三者,单单Nginx就可以完成了一个静态网页的部署;那么我们上文中花了那么大篇幅讲到的php、php-fpm、MySQL的部署呢?因为Wordpress使用的是动态网页的技术,是采用PHP这种动态脚本语言编写的,它的数据存储是使用MySQL;动态网页和静态网页有个很直观的感受差距就是:静态网页,你必须访问不同的路径,如/a和/b,你才能访问到不同的内容;而动态网页,你就只访问/a路径,后面加上个?id=数字,当数字不同,页面内容也就不同,而这里页面内容实际上就是根据数字的不同,然后去MySQL数据库中读取到的内容不同,id不同的情况下,页面由于id而导致不同的部分的内容是存储在数据库里的。
那么php-fpm是什么呢?Nginx是内容的分发者,刚才讲到,请求静态页面的时候,如index.html,会读取静态网页内容返回,那么如果请求的是index.php呢?,根据配置文件,nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器,Nginx会传哪些数据给PHP解析器呢?如URL、查询字符串(比如?id=1),Header头等,那么CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议;当Nginx收到index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器;接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以符合CGI规定的格式返回处理后的结果,退出进程;这中间还有一个叫做fastcgi的东西,是用来提供cgi性能的,而php-fpm你可以理解为一种实现了fastcgi的程序,PHP5.3.3版本里已经集成了php-fpm。
所以整体你可以这样理解:
静态网页:
用户通过浏览器向服务器提交请求->Nginx接收并响应请求->读取本地网页文件静态内容->返回浏览器
PHP动态网页:
用户通过浏览器向服务器提交请求->Nginx接收并响应请求->以CGI协议传递请求到php-fpm->php-fpm调用PHP进行动态解析->解析过程根据参数读取MySQL中内容->根据数据库返回内容生成静态网页内容->返回到浏览器
这大概就是一个网页的运行机制