作为一个PHPer,对于Linux系统最需要的莫过于一个LNMP/LAMP/LNMPA的开发/生产环境,今天带大家从头开始搭建一个ParrotSec+Nginx+Mysql+PHP的运行环境。
本教程完全适用且测试安装于 debian + parrot-tools-full
环境下,未测试原生ParrotSec系统,故不保证完全使用,如果有ParrotSec下的任何LNMP安装配置问题,请在 Parrotsec中文社区联系我,或者在Parrotsec-china中文社区QQ群中咨询。
目录
前言
一、Parrot Security 系统的安装
二、Nginx 服务器的调试配置
三、MySQL 数据库的安装配置
四、PHP 的安装配置
-
检查PHP是否已经被正确安装
-
运行phpinfo()检测PHP文件是否可被正确解析
-
安装和配置php-fpm
- php-fpm与nginx之间的关系
-
配置和使用php-fpm
- 确定Nginx中Fast-cgi监听方式:TCP & Unix
- 确定php-fpm监听方式
- 修改php-fpm.conf中的监听方式
-
安装必要扩展,并检查几个重要配置项
-
PHP配置完成
附录
前言
先跟大家说一道我在百度面试的面试题:
- 你平时用什么服务器?
答:Apache/Nginx。 - 这些服务器是干什么用的?或者说从在浏览器输入了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的翻译和增补过的完整示例,如果想了解下详细内容的大佬们可以参考下
配置步骤
-
首先检查Nginx是否存在,
nginx -t
,如果不存在肯定会说命令不存在,则需要sudo apt update && sudo apt install nginx
,具体nginx包叫什么还真不知道,应该直接用就可以,未经测试,如果有大佬发现问题,可以在下方回复我。 -
使用
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
- 可能出现的一个问题:80端口被占用,无法启动,如果检查了上述2中强调的两个问题还没有解决的话,可以通过使用
三、Mysql数据库的安装配置
- 请首先按照 更改mysql密码的方式这篇文档来配置默认的数据库密码;
- 出现不需要密码可以直接登录的情况,请检查gsad是否占用80端口,占用了的话
killall -9 gsad
杀掉这个进程。(目前没有发现重启后gsad自动占用80端口的原因,援引sid大佬的话,这是一个openvas的进程,但是没有找到相关启动项,和相关解决方案);
- 开箱即用。
四、PHP的安装配置
到此为止,我们已经可以访问web根目录下的静态文件了,但是我们最终的目的是访问PHP文件,所以我们来放一个写了<? phpinfo(); ?>
的名为index.php的PHP文件,并尝试访问。
-
检查下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文件。
-
运行PHPINFO文件,并根据结果检查问题原因(一定要看日志!!!)
我这里出现了502Bad Gate
,nginx的error.log上写的是connect() failed (111: Connection refused) while connecting to upstream
,查了下是php-fpm没有生效,查了下并没有php-fpm,所以进行了安装。如果你的程序可以正确的被解析,你可以跳过下面这一步。
-
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未经测试,推断同样应该把这两部分统一。
-
检查必要组件
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
-
配置完成
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;
# }
#}
##
# 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