
DVWADamn Vulnerable Web Application玩过Web安全测试的人基本都认识它。不管是为了练习SQL注入、XSS还是熟悉CSRF、文件包含本地搭一套DVWA都是最省事的路子。但搭建过程中最劝退的环节往往不是漏洞利用而是环境本身——十个人有七八个会栽在数据库连接这一步。我第一次搭DVWA也在这块折腾了整整一个晚上。PHP、Apache装得飞快MySQL建好库和用户config/config.inc.php按教程改好浏览器一刷新红字弹出来Could not connect to the database。后来排查得多了才发现所谓“数据库连接失败”其实是一大类问题的总称背后可能是服务没启动、驱动缺失、配置写错、权限不足、认证插件不兼容每一条都能单独把你卡死。下面就把这条排查链路完整梳理一遍从现象到根因从命令到配置按步骤来基本十分钟内能定位。1. 先分清报错类型同样是数据库连不上原因可能完全不同第一次撞上这类问题的人最容易做的事就是不断改密码、改config、重装MySQL折腾一通还是原来的红字。其实报错本身已经给了足够的线索只是大多数人只看第一句话忽略了后半段的错误码。DVWA连接数据库失败常见的有三种表现每种对应完全不同的排查方向。1.1 安装页面红字直接指向配置与服务状态DVWA首次访问时脚本会尝试用config里的账号密码连接MySQL连不上就显示一段很笼统的提示大概长这样Could not connect to the database Please check the settings in the config file.这句提示本身没什么价值有价值的是它下面那段详细信息里面通常带着SQLSTATE错误码。我列一个对照表方便大家一眼定位错误码/提示实际含义优先排查方向SQLSTATE[HY000] [1045] Access denied for user ... (using password: YES)用户名或密码不对或者host权限不匹配config账号、MySQL用户表SQLSTATE[HY000] [2002] Connection refusedMySQL没监听这个端口或者服务没启动服务状态、端口占用SQLSTATE[HY000] [2002] No such file or directory连接的是Unix socket但路径找不到PHP与MySQL的socket配置SQLSTATE[HY000] [2002] Connection timed out网络不通或防火墙拦截防火墙、bind-address先看SQLSTATE后面属于哪一类再决定往哪个方向排查。第1045种情况最多后面几节重点展开2002和No such file这两类属于环境配置问题按照第2节处理。1.2 安装阶段通过登录时却提示Login Failed另一种情况更加隐蔽打开setup.php页面时数据库连接状态明明是正常的点“Create / Reset Database”也没报错但回到首页用默认账号admin/password登录页面却提示Login Failed。问题通常不在数据库连接而在DVWA的初始化数据没有真正写进去。点击Create / Reset Database时DVWA会建表并插入初始用户数据如果config里配置的数据库账号只有SELECT权限、没有CREATE和INSERT权限这个操作可能部分成功、部分失败表面不报错实际users表是空的。遇到这种情况先用命令行确认dvwa库里有没有users表USE dvwa; SHOW TABLES; SELECT * FROM users;没表或没数据就回头检查数据库账号的权限GRANT ALL PRIVILEGES ON dvwa.* TO ...再回到setup.php重新执行一次Reset。另外浏览器里的旧session也可能导致登录后立刻退出换无痕窗口试试往往能当场解决。1.3 白屏或500先翻日志再动配置如果打开DVWA页面直接白屏或者收到500 Internal Server Error很多人下意识认为是config没配置好开始反复改配置。实际上白屏和500通常是PHP层面的错误比如mysqli扩展缺失、PHP版本与代码不兼容日志里基本都有明确答案。Debian/Ubuntu下可以这样看日志Apachetail -f /var/log/apache2/error.logNginx PHP-FPMtail -f /var/log/nginx/error.log以及/var/log/php*-fpm.logWindows phpStudy面板上的日志入口也可以临时把php.ini里的display_errors设为On让错误直接显示在页面上。我遇到过花半小时改配置没进展最后发现就是php-mysql扩展没装的案例日志里一行Call to undefined function mysqli_connect()直接就把问题说明白了。先看日志往往比猜快十倍。2. 服务层排查MySQL到底有没有真正跑起来不要一上来就改代码和配置。第一步永远是确认MySQL服务端本身是活的、可连接的。这个检查五秒钟的事但能省掉后面一大堆疑神疑鬼。2.1 查看服务状态没有的话手动拉起来在Linux上用systemd管理服务的环境里查看状态即可sudo systemctl status mysql如果提示Unit mysql.service not found那可能是因为很多发行版已经把MySQL替换成兼容的MariaDB服务名是mariadbsudo systemctl status mariadb sudo systemctl start mariadb sudo systemctl enable mariadbenable那一步很容易被忽略但很重要。不然你这次手动启动了下次重启机器后服务又没起来数据库又连不上了你会误以为是配置问题其实只是没设开机自启。Windows环境下在服务管理器里确认MySQL服务名称并启动。如果用的是phpStudy这类集成环境直接在面板上点启动MySQL即可。注意集成环境切换PHP版本或者改端口后有时面板显示“已启动”实际进程已经退出重启面板一般能解决。2.2 用命令行做最小验证排除一切中间环节检查服务端最好的办法是用mysql客户端直连mysql -u root -p输入密码后能进入交互界面就说明服务端是好的。接着执行SELECT VERSION(); SHOW DATABASES;看看库列表里有没有dvwa库。如果你在命令行用root能登录但在网页里连不上说明问题不在服务端而在PHP驱动或者config配置。如果你在命令行连都连不上比如Access denied那是MySQL用户本身有问题先解决账号再说。端口层面也值得确认尤其是环境复杂的时候sudo netstat -ntlp | grep 3306看到监听列表里有3306才算正常。如果3306被其他程序占用MySQL可能启动失败这时要么改掉冲突程序端口要么给MySQL指定其他端口并同步修改config文件里的端口配置。另外有时MySQL进程启动了但因为端口被占用实际进程起了一半就退出看一下端口监听状态比只看进程存在与否更准确。2.3 监听地址与socket文件两个容易被忽略的元凶MySQL默认的bind-address是127.0.0.1本地搭建没问题。但如果DVWA不是部署在本机而是跑在容器里或远程服务器上这个地址就要改成0.0.0.0或者对应的网卡地址否则外部请求根本进不来。另一个坑是Unix socket路径。PHP连接MySQL有两种通道TCPhost为127.0.0.1或IP和Unix Sockethost为localhost。有的环境里PHP配置的socket路径和MySQL实际的socket路径不一致比如PHP默认找/var/run/mysqld/mysqld.sock而MySQL的实际位置不同就会报“No such file or directory”这种看起来不太像数据库连接错误的错误。解决办法是统一路径要么在config里把db_server写成127.0.0.1强制走TCP要么在php.ini里修正mysqli.default_socket和pdo_mysql.default_socket这两个配置项。我的经验是直接写127.0.0.1最省心能少踩一个socket相关的坑。3. 驱动层PHP版本变了连接方式也得跟着变DVWA是个PHP项目PHP到底用什么方式连MySQL取决于PHP的数据库扩展。这一步出问题代码配置全对照样连不上而且报错方式五花八门。3.1 三代数据库接口兼容性差别很大PHP连MySQL历史上主要有三类接口接口活跃时期当前状态与DVWA的关系mysql_* 函数PHP 3~5.6PHP 7.0起已彻底移除DVWA 1.9及更早使用新环境直接报致命错误mysqli 扩展PHP 5.0起广泛使用官方维护DVWA 2.x主要使用PDO_MySQLPHP 5.1起推荐使用跨数据库DVWA 2.x也支持这里最大的坑是版本错位。DVWA 1.9及以前的代码用的是mysql_connect这类老接口在PHP 7.0以上的环境里会直接报Call to undefined function mysql_connect()这根本不是数据库的问题而是代码已经被PHP版本淘汰了。网上大量教程的截图还是老界面新手照着下载了DVWA 1.9然后在新环境里反复折腾数据库配置永远无法解决。遇到这种情况直接用新版DVWA 2.x即可代码已经切到mysqli/PDO兼容PHP 7和8。3.2 PHP 7/8环境缺少mysqli扩展的症状与修复就算是新版DVWAPHP环境缺少mysqli扩展也一样会出问题。症状通常是页面报错提示未定义函数mysqli_connect或者PDO driver不存在。Ubuntu/Debian安装扩展很简单sudo apt install php-mysql sudo systemctl restart apache2如果你用的是Nginx PHP-FPM把restart apache2换成对应的php8.1-fpm服务名。Windows下如果用phpStudy或手动安装的PHP需要在php.ini里去extensionmysqli这一行前面的分号同时确认extension_dir配置指向了正确的ext目录改完一定要重启PHP或Web服务不然不生效。验证扩展是否生效最快的方式php -m | grep mysqli或者在Web目录放一个phpinfo.php文件内容写?php phpinfo();浏览器打开后搜索mysqli。有输出就说明扩展正常。phpinfo这个工具在排错时非常好用能一次性看到PHP版本、加载的模块、各种配置路径比到处翻文档靠谱。3.3 驱动层的快速自查清单到这一步驱动层的排查其实是套固定动作列个清单执行php -v确认PHP版本DVWA 2.x建议PHP 7.0及以上。执行php -m确认mysqli和pdo_mysql都在加载列表里。打开phpinfo检查MySQL相关配置项比如mysqli.default_socket路径。确认下载的DVWA是2.x新版不是1.9老版本。我的经验是如果在Linux上搭建直接装系统源里的PHP 7.4或8.0配合php-mysql基本不用为驱动操心。反而是Windows下手动配PHP容易漏掉extension_dir这个配置报错千奇百怪优先用集成环境最省事。4. 配置层config文件里的默认账号密码为什么这么容易踩坑DVWA的数据库连接配置集中在config/config.inc.php文件里。这个文件默认不存在需要先复制一份config/config.inc.php.dist为config/config.inc.php很多新手第一步就漏了页面直接报找不到配置文件的错误。4.1 默认配置解读DVWA用的不是root账号看一段典型的默认配置$_DVWA[ db_server ] 127.0.0.1; $_DVWA[ db_database ] dvwa; $_DVWA[ db_user ] dvwa; $_DVWA[ db_password ] pssw0rd; $_DVWA[ db_port ] 3306;这里有个关键点默认账号是dvwa密码是pssw0rd数据库是dvwa而不是root。很多人按老教程改成root和自己的密码也不是不行但要注意MySQL里root账号的host匹配规则。MySQL账号是由“用户名主机”共同决定的rootlocalhost和root127.0.0.1在授权表里是两条独立记录如果config里host写127.0.0.1MySQL按TCP连接匹配的可能是root127.0.0.1这条如果你只授权了rootlocalhost那就会Access denied。最简单稳妥的做法是不用root按DVWA默认创建一个专用账号config保持默认不去改减少出错概率。4.2 建库建用户的标准SQL一步到位下面这段SQL可以把库和账号一次性准备好CREATE DATABASE IF NOT EXISTS dvwa CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER IF NOT EXISTS dvwalocalhost IDENTIFIED BY pssw0rd; GRANT ALL PRIVILEGES ON dvwa.* TO dvwalocalhost; FLUSH PRIVILEGES;注意字符集用utf8mb4对后面练习时存储中文字符内容更友好。创建完账号后再回到setup.php页面点击Create / Reset DatabaseDVWA会自动完成建表和初始数据写入。如果你改了MySQL端口别忘了同步改config里的db_port端口不一致的报错是Connection refused很容易和服务没启动混淆。改完端口后重启MySQL并在命令行用-P参数测试新端口连通性。4.3 改完配置不生效可能是session和PHP-FPM在捣乱配置改对了数据库账号也没问题但页面仍然报错这种情况我见过不少常见原因有三个第一PHP-FPM或Apache没重启。config文件是PHP代码每次请求都会重新读取按理说不需要重启但如果开了opcache扩展某些环境下会缓存文件内容重启一下服务最保险。第二浏览器残留旧session。DVWA会把数据库连接状态写进session之前失败的状态会影响后续判断清cookie或者换无痕窗口重试可以当场验证是不是这个问题。第三文件路径搞错。确认你改的是config/config.inc.php而不是config.inc.php.dist。有人复制文件后把.dist误删了导致每次请求都读不到配置报错信息却指向数据库连接非常迷惑。提示修改config文件前先备份原文件可以cp config.inc.php config.inc.php.bak。改坏了随时能回退比重新下载整个项目省事。5. MySQL 8.x 的认证插件隐藏最深的一个大坑这个坑大概是最折磨人的。现象是命令行里用mysql -u dvwa -p能正常登录授权看起来也全对config也没问题但PHP这边连数据库就是Access denied错误信息一模一样。为什么会这样因为MySQL 8.x默认的认证插件变了。5.1 caching_sha2_password和旧版PHP驱动的不兼容MySQL 5.7时代默认认证插件是mysql_native_passwordPHP的mysqli和PDO驱动对这个插件支持得很成熟。MySQL 8.0起默认改成了caching_sha2_password安全性是提升了但问题来了较老版本的PHP mysqli扩展和libmysqlclient库对caching_sha2_password支持不完整连接时会被MySQL拒绝报Access denied。给人的感觉就像是密码写错了但其实密码完全正确。这个坑最麻烦的地方在于错误信息里完全没有“认证插件不支持”这样的字眼就是标准的SQLSTATE[HY000] [1045] Access denied。你可能会反复检查密码、检查用户权限、检查host匹配就是想不到是插件兼容问题。5.2 一条SQL把认证插件改回兼容模式解决办法很直接把目标用户的认证插件手动改回mysql_native_passwordALTER USER dvwalocalhost IDENTIFIED WITH mysql_native_password BY pssw0rd; FLUSH PRIVILEGES;如果新建用户可以直接在创建时指定插件CREATE USER dvwalocalhost IDENTIFIED WITH mysql_native_password BY pssw0rd;需要注意的是在MySQL 8.4及更新版本里mysql_native_password插件开始被标记为废弃。所以我的建议是本地搭DVWA如果没必要直接用MariaDB就行了。MariaDB默认认证插件就是mysql_native_password跟老PHP兼容性很好不用折腾。5.3 host匹配localhost和127.0.0.1很容易给人下马威前面提到过MySQL账号是由“用户名主机”共同决定的dvwalocalhost和dvwa127.0.0.1是两条完全不同且独立的记录。PHP里config的db_server如果写127.0.0.1MySQL按TCP连接处理优先匹配的host可能是127.0.0.1或%而不是localhost那条记录。如果你只创建了localhost的账号就可能出现“命令行能连、PHP连不上”的怪象。排查时可以查一下用户表一目了然SELECT user, host, plugin FROM mysql.user WHERE userdvwa;想省心的话直接用host为%的账号CREATE USER dvwa% IDENTIFIED WITH mysql_native_password BY pssw0rd; GRANT ALL PRIVILEGES ON dvwa.* TO dvwa%; FLUSH PRIVILEGES;这样不管config里写localhost还是127.0.0.1基本都能连上。测试环境这样放开没问题生产环境千万别这么干。6. 一套可复现的零到一搭建流程照这个做基本不会翻车前面几节都在讲排查这一节给出一套完整、可照抄的流程。新手不熟悉环境不一定有耐心逐项排查用这套组合拳能少踩几个坑。6.1 推荐的环境组合与选型理由我试过很多组合总体感受是Ubuntu 22.04 PHP 7.4/8.1 MariaDB 10.x DVWA 2.x最省心Windows phpStudy集成面板 PHP 7.4 MySQL 5.7/MariaDB次之Docker方式一条命令能跑起来但要稍微理解端口映射和容器数据卷为什么首推MariaDB因为它兼容MySQL协议但默认认证插件就是mysql_native_password省去了MySQL 8.x认证插件不兼容老PHP驱动的折腾。DVWA是学习用途追求的是快速跑起来没必要在认证插件上浪费时间。6.2 Ubuntu下的完整步骤以Ubuntu 22.04为例从零开始安装Web环境sudo apt update sudo apt install -y apache2 php php-mysql php-mbstring mariadb-server unzip确认MariaDB服务sudo systemctl enable --now mariadb sudo systemctl status mariadb下载部署DVWAcd /var/www/html sudo wget https://github.com/digininja/DVWA/archive/refs/heads/master.zip sudo unzip master.zip sudo mv DVWA-master dvwa sudo chown -R www-data:www-data dvwa如果网络环境下载这个包比较吃力可以从其他镜像或者国内软件源找DVWA 2.x的包只要是新版就行。配置config文件cd /var/www/html/dvwa/config sudo cp config.inc.php.dist config.inc.php sudo nano config.inc.php确认db_server、db_database、db_user、db_password四个值符合预期一般默认就是dvwa / pssw0rd。创建数据库和账号sudo mysql -u rootCREATE DATABASE IF NOT EXISTS dvwa CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER IF NOT EXISTS dvwalocalhost IDENTIFIED BY pssw0rd; CREATE USER IF NOT EXISTS dvwa127.0.0.1 IDENTIFIED BY pssw0rd; GRANT ALL PRIVILEGES ON dvwa.* TO dvwalocalhost; GRANT ALL PRIVILEGES ON dvwa.* TO dvwa127.0.0.1; FLUSH PRIVILEGES;这里同时创建两个host的账号就是为了直接绕开第5.3节说的host匹配问题。打开安装页面浏览器访问http://你的服务器IP/dvwa/setup.php点击“Create / Reset Database”。页面显示数据库连接正常基本就成功了。登录系统回到首页用admin/password登录。登录后可以在DVWA Security选项卡把难度调成Low或Medium开始正常练习。6.3 建完库之后顺手做的状态核验登录成功后建议进数据库看一眼SHOW TABLES FROM dvwa;应该能看到guestbook和users等表。users表里应有admin、gordonb、1337等默认测试账号。确认这些表和数据存在后续做题时登录和注入功能才不会出现莫名的异常。同时检查防火墙如果是在云主机或虚拟机上搭别人要访问的话80端口需要在防火墙或安全组里放行。如果是本机自测这一步可以跳过。6.4 后续使用中会碰到的几个小问题页面提示没有初始化重新访问setup.php并再点一次Reset Database即可。某几个题目模块报错但页面整体能用大多是数据库用户权限不足确认GRANT ALL已经执行。文件包含模块可能需要修改php.ini里的allow_url_include配置等玩到那一节课再调就行。登录成功后想切换难度级别时如果提示session异常清一下浏览器cookie再登录。把这条链路走通之后DVWA基本不会再因为数据库连不上而耽误时间了。最后再分享一个实际经验我后来搭DVWA基本固定用MariaDB很少再碰认证插件不兼容的坑。如果实在要用MySQL 8.x记住一个排查顺序——先看服务在不在跑再确认扩展装没装然后核对config和账号权限最后检查用户认证插件。按这个顺序走十分钟内基本能定位。排错还有一个心得永远先看完整错误行而不是只看第一句SQLSTATE后面的错误码才是真正的路由。