docker部署nginx+php+mysql开发环境

# 信安之路-第一关

静中藏了一个争字,稳中藏了一个急字,忙中藏了一个亡字,忍中藏了一个刀字,越想争心越要静。越急心越要稳。越忙越要照顾好自己。越忍越要看清事态

本次目的:熟悉Linux+Nginx+PHP-fpm-Mysql开发环境的搭建。从基本开始,一步一步来。搭建完成后,进行加固,熟悉基础加固的思路。

linux

linxu采用centos虚拟机安装 最小化安装。安装完成后换源.

换源

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup #备份
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo #下载阿里云的源
yum makecache   #生成缓存

加固

从互联网收集的加固手册,按着流程来一遍。先来一个自己总结的思维导图

image-20220618181545539

账号管理

账号
用户口令设置
  1. 由于虚拟机搭建使用简单口令,root/root,对口令进行加强
  2. 执行:more /etc/login,检查PASS_MAX_DAYS/PASS_MIN_LEN/PASS_MIN_DAYS/PASS_WARN_AGE参数
  3. awk -F: '($2 == "") { print $1 }' /etc/shadow 检查是否存在空口令账号

思考:弱口令 空口令 密码复杂度

检查是否存在除root之外UID为0的用户
awk -F: '($3 == 0) { print $1 }' /etc/passwd #

只允许root一个uid为0

root用户环境变量的安全性
echo $PATH | egrep '(^|:)(\.|:|$)' #检查是否包含父目录
find `echo $PATH | tr ':' ' '` -type d \( -perm -002 -o -perm -020 \) -ls 检查是否包含组目录权限为777的目录

思考:确保root用户的系统路径中不包含父目录,在非必要的情况下,不应包含组权限为777的目录

认证
远程连接的安全性配置
执行:find / -name .netrc,检查系统中是否有.netrc文件
执行:find / -name .rhosts ,检查系统中是否有.rhosts文件

有文件则低于要求

用户的umask安全配置
执行:  more /etc/csh.login  more /etc/csh.cshrc  more /etc/bashrc检查是否包含umask值  默认的低于要求
重要目录和文件的权限设置
ls  –l  /etc/
ls  –l  /etc/rc.d/init.d/
ls  –l  /tmp
ls  –l  /etc/inetd.conf
ls  –l  /etc/passwd
ls  –l  /etc/shadow
ls  –l  /etc/group
ls  –l  /etc/security
ls  –l  /etc/services
ls  -l  /etc/rc*.d # 权限过低,则低于安全要求

重要目录需要 chmod -R 750 file 只有root可以读、写和执行这个目录下的脚本

查找未授权的SUID/SGID文件
for PART in `grep -v ^# /etc/fstab | awk '($6 != "0") {print $2 }'`; do
find  /  \( -perm -04000 -o -perm -02000 \) -type f -xdev -print
Done #非空低于要求
检查任何人都有写权限的目录
for PART in `awk '($3 == "ext2" || $3 == "ext3") \
{ print $2 }' /etc/fstab`; do
find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print
Done #非空低于要求
查找任何人都有写权限的文件
for PART in `grep -v ^# /etc/fstab | awk '($6 != "0") {print $2 }'`; do
find $PART -xdev -type f \( -perm -0002 -a ! -perm -1000 \) -print
Done #非空低于要求
查找没有属主的文件
for PART in `grep -v ^# /etc/fstab | awk '($6 != "0") {print $2 }'`; do
find $PART -nouser -o -nogroup -print
done  #非空低于要求
检查异常隐含文件
find  / -name ".. *" -print –xdev
find  / -name "…*" -print -xdev | cat -v   #非空低于要求

日志审计

日志
more /etc/syslog.conf  查看参数authpriv值 对所有登录事件都记录
审计
more /etc/syslog.conf
#需设置
kern.warning;*.err;authpriv.none\t@loghost
*.info;mail.none;authpriv.none;cron.none\t@loghost
*.emerg\t@loghost
local7.*\t@loghost 

系统文件

系统core dump状态
more /etc/security/limits.con
#需要包含一下项
* soft core 0
* hard core 0

其他思考

1. 指定IP可以远程登录,设置远程登录超时
2. 禁止直接登录root账户,需要从普通账户su到root;结合前边的禁止su到root,就只能本地root账户登录了 
3. 开启防火墙
4. 对web业务开启防ddos攻击防护
5. 更改主机解析地址顺序,防止IP欺骗。
6. 补丁更新,防止被提权
7. 一些系统的指纹信息屏蔽 比如ftp  ssh等等

nginx+php+mysql-docker部署

docker pull nginx
docker pull php:7.1-fpm
docker pull mysql:5.7

创建文件夹

# 网站目录
mkdir -p /data/www
# nginx 配置
mkdir -p /data/nginx/conf.d
 
# mysql数据
mkdir -p /data/mysql/data
# mysql配置
mkdir -p /data/mysql/conf.d

创建 Nginx 容器

docker run --rm nginx cat /etc/nginx/nginx.conf > /data/nginx/nginx.conf
#将nginx配置文件nginx.conf复制到主机/data/nginx目录中
docker run --name nginx \
-v /data/www:/usr/local/html \
-v /data/nginx/conf.d:/etc/nginx/conf.d \
-v /data/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
--net=host \
-d nginx
#创建nginx
docker run --name php-fpm \
-v /data/www:/var/www/html \
-d php:7.1-fpm
#创建php
#查看php ip
docker inspect php-fpm --format='{{.NetworkSettings.IPAddress}}'
 
# 返回 IP
172.17.0.2
vim /data/nginx/conf.d/default.conf
 
server {
    listen       80;
    server_name  localhost;
    
    location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
    }
    
    location ~ \.php(.*)$ {
        root            /var/www/html;           # php 容器的目录,进 php 容器查看
        fastcgi_pass    172.17.0.2:9000;         # php 容器的IP
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
 
}# 创建 Nginx 配置文件
docker restart nginx    #重启nginx容器

docker ps

image-20220618215744707

测试

echo "<?php phpinfo(); ?>" > /data/www/info.php
curl http://127.0.0.1/info.php

创建 MySQL 容器

docker run --name mysql \
-p 3306:3306 \
-v /data/mysql/conf.d:/etc/mysql/conf.d \
-v /data/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
安装php扩展
# 进入容器
docker exec -it php-fpm /bin/bash
 
# 安装 pdo_mysql mysqli
docker-php-ext-install pdo_mysql mysqli
 
# CTRL + D 退出容器
docker restart php-fpm

连接 MySQL测试

docker inspect mysql --format='{{.NetworkSettings.IPAddress}}'
查看mysql的ip
# 返回 IP
172.17.0.3

编辑连接测试文件

vim /data/www/conn.php
<?php
        $serve = '172.17.0.3:3306';
        $username = 'root';
        $password = '123456';
        $dbname = 'mysql';
 
        $mysqli = new Mysqli($serve,$username,$password,$dbname);
        
        if ($mysqli->connect_error) {
                die('connect error:'.$mysqli->connect_errno);
        }
 
        $mysqli->set_charset('UTF-8');
        $result = $mysqli->query('select * from user');
        $data = $result->fetch_all();
        print_r($data);
 
?>
curl http://127.0.0.1/conn.php #测试

image-20220618220150884

nginx加固

nginx作为优秀的正反向代理web服务器,多线程,高并发等特点。顺便记下正反向代理,代理客户端就是正向,反之代理服务端就是反向代理。另外正向代理可以作为上网行为管理;反向代理除了负载均衡,暴露的是代理服务器在公网的IP,隐藏了内网web服务器

image-20220618190102382

限制目录访问

vi /etc/nginx/nginx.conf 在HTTP模块增加 autoindex off; 因为nginx会自动下载web目录下的文件,增加威胁暴露面。

隐藏版本信息

vi /etc/nginx/nginx.conf 在HTTP模块增加server_tokens off 隐藏版本信息,如HTTP响应里就看不到了。这里得重启,重新载入配置不管用。

限制HTTP请求方法

vi /etc/nginx/conf.d/default.conf 在server模块增加

if ($request_method !~* GET|POST|HEAD) {
    return 403;
    } //拒绝除了get|post|head外的请求方式

nginx权

vi /etc/nginx/nginx.conf 增加 user nobody; 这样就算web服务权限失陷,也不会是root权限。这还涉及运维知识,nobody是Linux用来执行服务主进程之外进程的用户,为了达到失少不失全效果,若一开始用root部署的nginx,做好了负载均衡,后边重启服务每次都要root,麻烦;而且想换了,还会导致缓存访问权限不足进而进程缓慢,服务瘫痪等后患。

限制IP访问

编辑nginx.conf配置文件(vi /etc/nginx/nginx.conf ),在server标签内添加如下内容:

location / {
deny ip;  
allow ip;
}

防盗链

编辑nginx.conf配置文件(vi /etc/nginx/nginx.conf ),在server标签内添加如下内容:

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
    valid_referers none blocked server_names *.nsfocus.com http://localhost baidu.com;
    if ($invalid_referer) {
        rewrite ^/ [img]http://www.XXX.com/images/default/logo.gif[/img];
      #return 403;
     }
}

补丁更新

nginx -v #查看版本信息
nginx -t #查看配置文件
然后选择补丁

php加固

php-fpm降权

修改/etc/php-fpm.d/www.conf,将 user = apache group = apache,改为 user = nobody group = nobody

安全模式

5.3以后没有了

禁用不安全的PHP函数

vi /etc/php.ini  
disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,phpinfo 
#这样之前测试php nginx连通用的phpinfo函数就失效了。

关闭错误日志

vi /etc/php.ini  

display_errors = Off  

#避免报错暴露物理路径造成的文件上传或者sql报错注入、getshell。之前i春秋的ctf初级训练营里有一个就是利用PHP报错查看到数据库版本吧好像。

启用HTTPOnly

vi /etc/php.ini  

session.cookie_httponly = 1

通过document盗用cookie预防XSS,但是可以在socket层抓包程序进阶攻击。

关闭PHP信息

vi /etc/php.ini  
expose_php = Off
这样设置在http请求里就看不到x-powered-by:php/5.4.16了

限制目录访问

vi /etc/php.ini  
open_basedir = ./:/tmp:/home/www/配置的目录 坏处就是影响IO流

限制上传目录

vi /etc/php.ini  
upload_tmp_dir = /tmp定义的上传目录,防止目录穿越。

image-20220618191715130

image-20220618191757423

image-20220618193249442

posted @ 2022-06-20 14:34  木捏牛  阅读(709)  评论(0编辑  收藏  举报