PHPSTORM调试Docker项目

访客4年前黑客资讯1000

前言

在做一些CTF的审计题或者复现漏洞时,会得到 Docker 环境。需要我们在 Docker环境中进行代码调试。在 PHP 代码审计中,没有好的调试环境(如 xdebug这类调试工具),单单靠 var_dump 和 debug_print_backtrace 来手撕代码,效率十分低下。而要配好一个调试环境有时也是挺多坑的。俗话说“搭建环境两小时,漏洞复现两分钟”。本文就来简单说说如何使用 PHPSTORM 调试 Docker项目。


在开始之前,需要简单了解下 Docker。至少要会最基本的用法。不过由于主要是讲 PHPSTORM 调试的。所以 Docker介绍不会讲太多。若想了解更多的话建议看手册。


Docker基本用法

首先要知道 Docker 最基本的两样东西:imagecontainer

image 镜像,搭建一个 Docker 环境最基本的就是 image。可以简单理解为这就是创建虚拟机的那个镜像。

container 容器。即 依据 image,创建出来的虚拟环境。可以简单理解为就是运行着的虚拟机


Docker 的配置文件为 Dockerfile。该文件内容为构建 container 的命令。基本命令有:

FROM 设置 container 运行在哪个 image 上。必须写在 Dockerfile 的开头。可以在 Docker Hub里找适合的 image。

RUN 在 image build时执行命令。一般用于安装环境

CMD 在 container刚启动时执行命令。一般用于启动服务

COPY 将宿主机的文件拷贝到 container中

WORKDIR 设置工作目录。所有命令都会在这个目录的基础上进行工作


了解了上面的三个命令后,我们可以来简单写一个 Dockerfile了。

#基础 image 为 php:7.3-apache
FROM php:7.3-apache
#安装 xdebug 扩展 并开启
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
#将 宿主机的 phpinfo.php 拷贝到 container /var/www/html/phpinfo.php 中
COPY https://www.freebuf.com/articles/web/phpinfo.php /var/www/html/phpinfo.php

写完后在 Dockerfile 的目录里运行

docker build -t test/testmyphp .

等命令跑完,输入以下命令即可看到创建好的 image

$ docker image ls
REPOSITORY TAG IMAGE ID ......
test/testmyphp latest 4931b92274f2 ......

要想让 container 运行起来,使用如下命令。使用来指定映射端口,左边是宿舍机端口,右边是 container 端口

docker run -p 81:80 test/testmyphp

查看运行中的 container

$ docker container ls
CONTAINER ID ? ? ? IMAGE ? ? ? ? ? PORTS ? ? ? ? ? ......
10b8c28b2f69 ? ? ? test/testmyphp ? ? 0.0.0.0:81->80/tcp ? ......

进入 container 的 shell

$ docker exec -it CONTAINER_ID值 bash
root@10b8c28b2f69:/var/www/html#

至此,基本的 Docker 环境我们就建好了。接下来研究下如何让 PHPSTORM 调试 Docker 项目


调试方式一 - Docker挂载调试

这里做测试使用前文的 Dockerfile,需要按照实际情况进行配置添加。

配置Dockerfile

#基础 image 为 php:7.3-apache
FROM php:7.3-apache
#安装 xdebug 扩展 并开启
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
# !!! 使用一个启动脚本来启动服务 !!!
COPY https://www.freebuf.com/articles/web/start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]

start.sh 内容

#配置 Xdebug
echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.max_nesting_level=1000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.discover_client_host=true" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#重启 apache ssh
service apache2 restart

重建 image:

#更好先删掉之前的再重建
docker image rm IMAGE值 -f
docker build -t test/testmyphp .

重建完先不急着跑 container。先定位到我们的项目代码位置

1615973734_6051cd66e6a6171bdd105.png!small?1615973736272

使用 Docker 的 Bind mounts 技术。将宿主机的项目目录映射到 container 的网站目录下

docker run -p 81:80 --mount type=bind,source=/home/xp/test_docker/test_program,target=/var/www/html test/testmyphp

至此,调试环境所需要的服务就安装好了,接下来配置 PHPSTORM。


配置 PHPSTORM

直接使用打开项目


配置 目录映射

进入 File -> Settings -> Languages & Frameworks -> PHP -> Servers。配置目录映射

注意一定要把 Use path mappings 的勾勾上,才能配置目录映射

Absolute path on the server 是要手动打上服务器路径的

1615973820_6051cdbc84e3dd5aace0c.png!small?1615973821932


设置Xdebug端口

进入 File -> Settings -> Languages & Frameworks -> PHP -> Debug。设置 Xdebug Debug port 为 9003。和 php 配置一致。

1615973860_6051cde4eb0db1e553ccd.png!small?1615973862373


配置一个 Run/Debug Configuration

点击 PHPSTORM 右上角的 Add Configuration....。进入配置面,新增一个 PHP Web Page。并进行如下简单的配置即可(改名字设url 路径)

启动 PHP Debug Listening

直接点击 PHPSTROM 右上角的 小 *** ,即可开启监听


验证

在 php文件上打上断点,点击 右上角 甲壳虫样式的 Debug按钮。即可成功断点

调试方式二 - ssh 隧道

这种方式不仅仅可以用在 Docker 环境上,同样可以用在 远程服务器上。缺点就是要在 container 里头安装许多额外服务。


配置Dockerfile

  1. 安装ssh服务。 PHPSTORM需要 ssh 来进行目录映射,不然无法成功 Debug

  2. 安装 xdebug。这是调试的基础扩展组件

  3. 设置 ssh 允许 root 登陆。毕竟只是个 docker 调试环境,就不弄那么麻烦了。当然如果是线上业务啥的当然要做好权限分配。

  4. 修改 root密码。毕竟不知道密码也无法连接

  5. 启动 ssh 服务

  6. 重启 apache 服务

这里做测试使用前文的 Dockerfile,需要按照实际情况进行配置添加。

修改前文的 Dockerfile。

#基础 image 为 php:7.3-apache
FROM php:7.3-apache
?
ENV APACHE_DOCUMENT_ROOT /var/www/html
#安装 ssh 服务
RUN apt-get update && \
apt-get install ssh -y
#安装 xdebug 扩展 并开启
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
#将宿主机的 phpinfo.php 拷贝到 container /var/www/html/phpinfo.php 中
COPY https://www.freebuf.com/articles/web/phpinfo.php /var/www/html/phpinfo.php
# !!! 使用一个启动脚本来完成流程 3 4 5 的工作 !!!
COPY https://www.freebuf.com/articles/web/start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]

start.sh 内容

#!/bin/bash
#设置 ssh 允许 root 登录
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
#修改root密码
echo root:123456 | chpasswd
#配置 Xdebug。Xdebug 3 的配置如下,和 Xdebug 2不太一样
echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.max_nesting_level=1000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
echo "xdebug.discover_client_host=true" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#重启 apache ssh
service apache2 restart
service ssh restart
#要加上这个,不然 container 运行完就停止了。
sleep infinity

重建 image:

#更好先删掉之前的再重建
docker image rm IMAGE值 -f
docker build -t test/testmyphp .

启动 container:

docker run -p 81:80 -p 2222:22 test/testmyphp

至此,调试环境所需要的服务就安装好了,接下来配置 PHPSTORM。


配置 PHPSTORM

打开 PHPSTORM,新建一个 Project。选择 New Project from Existing Files

选择 Web server is on remote host。

一路 Next。走到配置 Remote Server

然后又是一路 Next 即可。

配置完成后,将能看到我们的项目。

此时是不能直接进行代码调试的。我们要做以下工作

  1. 配置 CLI Interpreter

  2. 配置目录映射

  3. 设置Xdebug端口

  4. 配置一个 Run/Debug Configuration

  5. 启动 PHP Debug Listening

ps:由于有些步骤是一样的,就直接拉上文的截图过来了。


配置 CLI Interpreter

进入 File -> Settings -> Languages & Frameworks -> PHP。设置 CLI Interpreter

新建一个 CLI Interpreter。选择 From Docker, Vagrant, VM, WSL,Remote....

这里我们可以填 SSH,也可以直接选择 Docker。我这里用的是 SSH

设置 PHP executable 路径。不知道可以进入 container 中使用进行搜索


配置 目录映射

进入 File -> Settings -> Languages & Frameworks -> PHP -> Servers。配置目录映射

注意一定要把 Use path mappings 的勾勾上,才能配置目录映射

Absolute path on the server 是要手动打上服务器路径的

设置Xdebug端口

进入 File -> Settings -> Languages & Frameworks -> PHP -> Debug。设置 Xdebug Debug port 为 9003。和 php 配置一致。

配置一个 Run/Debug Configuration

点击 PHPSTORM 右上角的 Add Configuration....。进入配置面,新增一个 PHP Web Page。并进行如下简单的配置即可(改名字设url 路径)


启动 PHP Debug Listening

直接点击 PHPSTROM 右上角的 小 *** ,即可开启监听

验证

在 php文件上打上断点,点击 右上角 甲壳虫样式的 Debug按钮。即可成功断点

扩展 - 远程服务器调试

这里可以扩展以一下,如果调试目标是远程服务器而不是本地 Docker,该如何配置?

其实和上面的步骤一样的,只是 Xdebug 监听的流量我们要做修改下。

简单说说 Xdebug 监听的原理:

当 php-xdebug 接收到带有 XDEBUG_SESSION_START 的请求时,将会把当前的 Debug信 息发送给 xdebug 中配置的 client_host 和 cilent_port。

在我们的 start.sh 启动文件中,设置如下:

xdebug.client_host=host.docker.internal
xdebug.client_port=9003

值在 Xdebug 中是自动将请求端的 ip 设置为 调试端,即自动将 Debug信息 发送给任何请求IP。

而的值是 Debug信息 被发送至的端口。


我们可以想下,在本地,xdebug端是能访问到到我们请求端的 ip 和 端口 的,因为都是同一局域网。

但若调试的是远程服务器,由于公网和内网的原因,公网服务器是无法发送 Debug信息 调试端的(除非调试端也在公网上。。)


所以我们需要将设置为,让 xdebug 转发 Debug信息 到本地的 9003 端口中。

接着使用 ssh 隧道进行端口转发,把调试端监听的 9003 端口映射到 服务端的 9003 上。这样就能接收到 xdebug 转发的 Debug信息了。这一点使用 ssh 隧道是可以做到的。


我们来测试下,首先修改 php.ini。让值为

进行 ssh隧道端口转发

ssh -N -R 远程IP:远程端口:127.0.0.1:9003 root@远程IP

这样就能使用调试远程程序了。


Reference:

https://docs.docker.com/engine/reference/builder/

https://hub.docker.com/_/php

相关文章

美国纽约市卫生专获利盘员新冠病毒检测呈阳性

  美国纽约市卫生专员大卫·乔克希当地时间2月3日在一份声明中说,他的新冠病毒检测呈阳性,目前有轻微症状。他一直在与纽约市的检测和追踪部门保持联系,以确保任何可能因为他接触到病毒的人都能得到服务和照顾...

淘宝找号黑客暗语(淘宝上找黑客的暗语)

一、淘宝盗号黑客暗语(淘宝上找黑客的暗语)方法总结 1、网上找盗淘宝店铺密码黑客靠谱吗解决办法只有立即更换淘宝账号密码。另在使用淘宝时请注意以下几点:请不要在网吧等公共场所登录淘宝或支付宝帐户,以免...

入侵手机的黑客软件安卓版(安卓手机被黑客锁了)-那些曾经大名鼎鼎的黑客现在

入侵手机的黑客软件安卓版(安卓手机被黑客锁了)-那些曾经大名鼎鼎的黑客现在

入侵手机的黑客软件安卓版(安卓手机被黑客锁了)(tiechemo.com)一直致力于黑客(HACK)技术、黑客QQ群、信息安全、web安全、渗透运维、黑客工具、找黑客、黑客联系方式、24小时在线网络黑...

飞鹤星飞帆怎么样(飞鹤星飞帆这款奶粉怎么样)

  飞鹤星飞帆如何(飞鹤星飞帆这款婴儿奶粉如何)奶粉智库是一个致力于“比婴儿奶粉、查知名品牌、看测评”的网络平台,?已建立技术专业的高级营养师精英团队为千万宝妈妈处理婴儿奶粉喂哺疑惑。因为常常会接到顾...

不动产单元号是什么?不动产登记:什么是不动产单元?

湘潭在线10月28日讯(湘潭日报记者符瑶 通讯员 李勇)“不动产单元”一词,许多人对此很陌生。《不动产登记暂行条例》中规定:“不动产以不动产单元为基本单位进行登记,不动产单元具有唯一编码。”不动产单元...

防不胜防什么意思(防不胜防是形容什么)

防不胜防什么意思(防不胜防是形容什么)

前两年老有人给我推荐一种叫做LCF平安116系统的。可能是因为我身处北方的原因,恐怕南方地区早就被推荐好几轮了,我这个人从来是身经百战、百毒不侵的,所以任何时候有任何人给我推荐任何项目,我第一反应就是...