基于ParrotSec从头开始搭建一个LEMP服务器环境

作为一个PHPer,对于Linux系统最需要的莫过于一个LNMP/LAMP/LNMPA的开发/生产环境,今天带大家从头开始搭建一个ParrotSec+Nginx+Mysql+PHP的运行环境。


本教程完全适用且测试安装于 debian + parrot-tools-full 环境下,未测试原生ParrotSec系统,故不保证完全使用,如果有ParrotSec下的任何LNMP安装配置问题,请在 Parrotsec中文社区联系我,或者在Parrotsec-china中文社区QQ群中咨询。


目录

前言

一、Parrot Security 系统的安装

二、Nginx 服务器的调试配置

三、MySQL 数据库的安装配置

  1. 修改默认MySQL密码

  2. 一个可能出现的问题

  3. 配置完成

四、PHP 的安装配置

  1. 检查PHP是否已经被正确安装

  2. 运行phpinfo()检测PHP文件是否可被正确解析

  3. 安装和配置php-fpm

  4. 安装必要扩展,并检查几个重要配置项

  5. PHP配置完成

附录

  1. Nginx.conf

  2. avaliable-sites/default

  3. php-fpm fpm.conf/www.conf


前言

先跟大家说一道我在百度面试的面试题:

  1. 你平时用什么服务器?
    答:Apache/Nginx。
  2. 这些服务器是干什么用的?或者说从在浏览器输入了url按下enter的一瞬间起,到页面加载完展示在你眼前,这个请求都经历了什么?
    答:不知道。

所以我立志深入研究下这块,希望大家能在完整看完整篇文章之后得到答案。


一、ParrotSecurity Linux 系统的安装

ParrotSec中文社区中已经有足够的安装教程,此处就不再赘述了。

二、Nginx服务器的调试配置

默认装上完整的ParrotSec系统,或者debian安装parrot源之后安装parrot-tools-full包之后,nginx都已经默认安装在/etc/nginx/文件夹下了,所以本章讨论的重点在于配置和调试Nginx,以便我们进行PHP的开发。

需要注意的并且影响最大的三处文件

  • nginx.conf
    这个文件是Nginx的主配置文件,他会引入modules-enable/文件夹的所有模块和sites-enabled/文件夹下所有虚拟域名配置

  • site-enabled/*
    上面说nginx.conf会引入这个文件夹下的所有虚拟域名配置,其实相当于lnmp一键安装包的vhost/文件夹,和apache的vhost.conf文件,但是注意:
    按照官方意愿,此处最好只是一个软连接,所有vhost配置,不管有没有在使用,都应该建立在site-avaliable/文件夹下,并应按照每一个站点单独一个文件的单元式方法建立,软链接建立方法ln -s 源文件 新路径

  • site-avaliable/*
    由上可知,这里是所有nginx虚拟主机的配置文件的存放位置,配置方法可以参照随nginx附带的该文件夹下的default文件

后面附了nginx.conf和default的翻译和增补过的完整示例,如果想了解下详细内容的大佬们可以参考下

配置步骤

  1. 首先检查Nginx是否存在,nginx -t,如果不存在肯定会说命令不存在,则需要sudo apt update && sudo apt install nginx,具体nginx包叫什么还真不知道,应该直接用就可以,未经测试,如果有大佬发现问题,可以在下方回复我。

  2. 默认default文件需要改以下几处:

    • server中的监听端口,给第二句添加上ipv6only=on,或者直接把第二句注释掉,具体写法可以参见下方附录,不加的话会报错说“绑定失败,80端口已被占用”,修改依据是这篇博客
    • location的PHP解析处需要打开一个注释,我打开的是cgi的,具体差异可参考这篇讨论
  3. 使用sudo service nginx start启动,如果失败,去找日志文件,parrot里nginx的缺省日志文件保存位置在nginx.conf中可查,我的是在/var/logs/nginx/error.log,nginx.conf缺省安装在/etc/niginx/目录下。nginx.conf缺省参数的配置在本文后面的附1中可查。

    • 可能出现的一个问题:80端口被占用,无法启动,如果检查了上述2中强调的两个问题还没有解决的话,可以通过使用netstat -anp | grep 80 来查找下占用的进程,然后通过 killall -9 进程名 来强行终止进程,之后再通过 service nginx restart 来重启nginx
  4. 正常的话现在外部直接访问 http://你的ip 就可以访问以下页面了,恭喜你,nginx已完成配置!

三、Mysql数据库的安装配置

  1. 请首先按照 更改mysql密码的方式这篇文档来配置默认的数据库密码;
  2. 出现不需要密码可以直接登录的情况,请检查gsad是否占用80端口,占用了的话killall -9 gsad杀掉这个进程。(目前没有发现重启后gsad自动占用80端口的原因,援引sid大佬的话,这是一个openvas的进程,但是没有找到相关启动项,和相关解决方案);
  3. 开箱即用。

四、PHP的安装配置

到此为止,我们已经可以访问web根目录下的静态文件了,但是我们最终的目的是访问PHP文件,所以我们来放一个写了<? phpinfo(); ?>的名为index.php的PHP文件,并尝试访问。

  1. 检查下PHP有没有安装:

php -v

PHP 7.2.4-1 (cli) (built: Apr  5 2018 08:50:27) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.4-1, Copyright (c) 1999-2018, by Zend Technologies

本系统已安装PHP,并为7.2.4版本。
在输入了php之后tab的时候发现还安装php7.2;
既然已经确定了php已经被正确安装,那么直接运行下我们刚才的PHPinfo文件。

  1. 运行PHPINFO文件,并根据结果检查问题原因(一定要看日志!!!)

我这里出现了502Bad Gate,nginx的error.log上写的是connect() failed (111: Connection refused) while connecting to upstream,查了下是php-fpm没有生效,查了下并没有php-fpm,所以进行了安装。如果你的程序可以正确的被解析,你可以跳过下面这一步。

  1. php-fpm安装及配置

apt update && apt dist-upgrade -y && apt install php-fpm7.2

这里说明下nginx/php-fpm/php-cgi之间的关系,参考了这篇博客,感谢博主

#### Nginx是什么
Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。
#### Php-fpm是什么
1. cgi、fast-cgi协议

#### cgi的历史

早期的webserver只处理html等静态文件,但是随着技术的发展,出现了像php等动态语言。 
webserver处理不了了,怎么办呢?那就交给php解释器来处理吧! 
交给php解释器处理很好,但是,php解释器如何与webserver进行通信呢?

为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。如php-cgi程序。

#### fast-cgi的改进

有了cgi协议,解决了php解释器与webserver通信的问题,webserver终于可以处理动态语言了。但是,webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。这样有10000个请求,就需要fork、kill php-cgi进程10000次。

有没有发现很浪费资源?

于是,出现了cgi的改良版本,fast-cgi。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。这样每次就不用重新fork一个进程了,大大提高了效率。

2. php-fpm是什么

#### php-fpm即php-Fastcgi Process Manager. 
php-fpm是 FastCGI 的实现,并提供了进程管理的功能。 
进程包含 master 进程和 worker 进程两种进程。 
master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。

说了这么多,我们来展示下具体 如何配置和使用

  • 首先确定nginx配置文件中,我们到底选择了哪种监听fast-cgi的方式,如果你是按照我上面的流程配置的,那么应该在sites-available/文件夹下查找你的default或者其他vhost配置文件,查看location ~ \.php$中你是如何选择的fastcgi_pass参数,我这里选择了fastcgi_pass 127.0.0.1:9000,这是通过web的tcp协议进行监听,当然你也可以选择unix sockets的监听方式,记住这里的参数值就好;
  • 确定好之后去php-fpm的配置文件中进行排查,搜索listen关键字,没有搜到的话,查看有没有include别的配置文件,如果有,找到并编辑它。
    我这里引入了include=/etc/php/7.2/fpm/pool.d/*.conf这个目录,找了之后发现只有一个名为www.conf的配置文件,打开之后可以搜索到listen参数,并且参数值为listen = /run/php/php7.2-fpm.sock,相关官方描述也附在下面作为附3。
  • 选择套接口模式:TCP sockets & Unix sockets
    这里我选择了tcp,因为我的nginx中fastcgi_pass选择了监听9000端口,这里 一定 要统一socket,不然就会出现502。

Unix Sockets未经测试,推断同样应该把这两部分统一。

  1. 检查必要组件

    • apt install php7.2-xml php7.2-gd
    • 检查/etc/php/7.2/fpm/php.ini配置,重点检查以下几项
      file_uploads = On
      upload_max_filesize = 2M
      post_max_size = 8M
      

  1. 配置完成



附1:nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	use epoll;
	worker_connections 51200;
	multi_accept on;
}

http {

	##
	# Basic Settings
	# 基础设置
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;
	# 解开后将隐藏nginx版本号

	server_names_hash_bucket_size 128;
	client_header_buffer_size 32k;
	large_client_header_buffers 4 32k;
	client_max_body_size 50m;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;


	##
	# SSL Settings
	# SSL设置
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;


	##
	# Logging Settings
	# 日志设置
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;


	##
	# FastCgi configs
	# HTTP server和动态脚本语言间通信的可伸缩、高速接口配置
	# 在default中有引入,所以此处注释了
	##

	# fastcgi_connect_timeout 300;
	# fastcgi_send_timeout 300;
	# fastcgi_read_timeout 300;
	# fastcgi_buffer_size 64k;
	# fastcgi_buffers 4 64k;
	# fastcgi_busy_buffers_size 128k;
	# fastcgi_temp_file_write_size 256k;


	##
	# Gzip Settings
	# 在线实时压缩输出数据流设置
	##

	gzip on;

	gzip_min_length  1k;
	gzip_vary on;
	gzip_proxied expired no-cache no-store private auth;
	gzip_comp_level 6;
	gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
	gzip_disable   "MSIE [1-6]\.";


	##
	# Virtual Host Configs
	# 虚拟域名配置
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

 
#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
# 
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}


附2:avaliable-sites/default

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# 查看下面的文档,可以方便对掌握NGiNX配置文件的完整理解,以便充分利用Nginx的能力。
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
# 在大多数情况下,管理员应该从启用/可问站点文件夹中删除该文件。
# 因为本文件由NGNX包装团队持续更新,但只作为网站配置的参考。
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
# 该文件将自动加载其他应用程序提供的配置文件,例如Drupal或WordPress。
# 这些应用程序将在具有包名称(如/drupal8)的路径下可用。
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
# 如需获得更多信息,请自行查阅/usr/share/doc/nginx-doc/example/
##

##
# Default server configuration
# 默认服务器配置
##

server {
	listen 80 default_server;
	listen [::]:80  ipv6only=on default_server;
	# 这里一定要加上 ipv6only=on,不然会报错说   bind() to 0.0.0.0:80 failed (98: Address already in use)
	# 可以参考这篇blog:https://blog.csdn.net/yusiguyuan/article/details/20565337


	##
	# SSL configuration
	# SSL配置
	##

	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	
	# Note: You should disable gzip for SSL traffic.
	# 提示:为了SSL通讯,你应该关闭gzip
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# 为确保配置安全,请检查ssl_ciphers配置项。
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# 签名证书由ssl-cert包自动生成
	# Don't use them in a production server!
	# 不要在生产环境(正式环境)中使用上述证书
	
	# include snippets/snakeoil.conf;


	##
	# root
	# 项目运行根目录
	##

	root /var/www/html;


	##
	# default index
	# 默认主页解析
	##
	
	# Add index.php to the list if you are using PHP
	# 如果你使用世界上最好的语言PHP的话,请在下方列表中添加index.php
	index.nginx-debian.html index index.html index.htm index.nginx-debian.html;


	##
	# Server Host/Server Virtual Host
	# 服务器域名/虚拟域名
	##
	server_name _;


	##
	# 匹配到所有请求
  	# 但是和最长字符串会优先匹配
	##

	location / {

		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		# 依次将请求当作文件和文件夹顺序进行请求,
		# 都无法请求到的话将返回404页面

		try_files $uri $uri/ =404;
	}

	##
	# pass PHP scripts to FastCGI server
	# 通过FastCGI服务器调用PHP脚本
	##

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	
		# With php-fpm (or other unix sockets):
		# 配合php-fpm(或者其他unix插口/接口)

		# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;

		# With php-cgi (or other tcp sockets):
		# 配合php-cgi(或者其他tcp插口/接口)

		fastcgi_pass 127.0.0.1:9000;
	}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	#location ~ /\.ht {
	#	deny all;
	#}
}


##
# Virtual Host configuration for example.com
# 为example.com域名配置虚拟域名
##

# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
# 你可以将以下部分单独写入一个文件放在sites-available/目录下,
# 并且在sites-enabled/ 目录下创建一个软链接来启用它

#server {
#	listen 80;
#	listen [::]:80;
#
#	server_name example.com;
#
#	root /var/www/example.com;
#	index index.html;
#
#	location / {
#		try_files $uri $uri/ =404;
#	}
#}


附3:/etc/php/7.2/fpm/pool.d/www.conf中listen参数的相关说明

; The address on which to accept FastCGI requests.
; 这里是接受FastCGI请求的地址。
; Valid syntaxes are:
; 有效的语法结构如下:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   'ip/域名:端口号'        - 监听一个基于TCP协议的指定IPv4地址的端口;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   '[IPv6的端口/域名]:端口号' 
;                          - 监听一个基于TCP协议的指定IPv6地址的端口;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '端口号'                - 监听所有地址中的一个基于TCP协议的指定端口(IPv4/IPv6皆可)
;   '/path/to/unix/socket' - to listen on a unix socket.
;   '/unix套接字的路径'     - 监听一个unix域套接字
; Note: This value is mandatory.
; 提示:这个值不能为空!!!
; listen = /run/php/php7.2-fpm.sock
; listen = 127.0.0.1:9000
listen = 9000
3 个赞

第二个问题有一个很经典的文章

https://blog.csdn.net/a2796749/article/details/48032353

4 个赞

大佬666 :rofl:

发现极品文章一枚,收入公众号啦,届时会以大佬作者身份推送,大佬加油~w(゚Д゚)w


服务器资源由ZeptoVM赞助

Partners Wiki Discord