拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Windows下忘记PostgreSQL密码?修改pg_hba.conf认证配置快速重置

说实话这问题我太有共鸣了。前段时间接了一个老项目的维护工作交接文档里什么都写了就是没写数据库密码。Windows服务器上装着的PostgreSQL默认超级用户postgres的密码在维修人员的脑子里而人已经联系不上了。当时第一反应是上服务器翻配置文件结果发现pg_hba.conf里规规矩矩写的都是scram-sha-256也就是必须输密码才能连完全没法绕过。更麻烦的是Windows环境和Linux不一样Linux下还能切换系统用户走peer认证进库Windows根本没有postgres这个系统账号常规那一套切用户操作全都不适用。折腾了半个多小时最后是靠改pg_hba.conf临时放行trust认证再重置密码搞定的。整个过程并不复杂核心思路就是“先让数据库暂时不校验密码进去把密码改掉再恢复原来的校验规则”。但这其中有几个细节非常容易踩坑配置文件路径找不到、改完trust后连接方式选错导致不生效、改完密码忘了恢复认证规则导致数据库裸奔等等。这篇就把整个排查和操作过程掰开揉碎讲清楚照着做基本十五分钟内能解决适用于Windows下通过官方安装包安装的PostgreSQL版本覆盖9.x到16.x文件路径和服务名可能略有差异但逻辑完全一致。1. 本质是要改的不是密码而是“身份验证规则”很多人在这一步容易迷茫总觉得忘记了密码就得靠什么后门工具去暴力破解或者直接改数据文件。实际上PostgreSQL并没有所谓的“万能密码”但它的认证机制给了我们一条非常实用的后门路径——修改认证方式。要理解这一点必须先搞明白PostgreSQL在Windows下是怎么验证身份的。PostgreSQL在建立连接时会读取数据目录下的pg_hba.conf文件HBA全称是Host-Based Authentication基于主机的认证配置这个文件定义了“谁可以从哪里连接哪个数据库采用什么方式验证身份”。默认安装完成后本机连接的规则大致长这样# TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 scram-sha-256 host all all ::1/128 scram-sha-256其中最后的METHOD字段就是认证方式常见的有以下几种认证方式含义密码错误时表现trust完全信任不需要密码直接放行不存在密码错误谁连都行scram-sha-256基于SCRAM-SHA-256算法的密码认证PostgreSQL 14之后默认报密码认证失败md5基于MD5的密码认证PostgreSQL 13及更早版本常见报密码认证失败password明文密码传输认证报密码认证失败peer操作系统用户认证仅Linux/Unix支持Windows下不可用reset密码的核心思路就清晰了把pg_hba.conf中本机连接的认证方式临时从scram-sha-256改成trust让数据库不再校验密码然后以postgres用户身份登录进去用SQL语句重置密码。完成后立刻把认证方式改回原来的值。为什么Windows下只能这么干因为PostgreSQL在Linux下还有一个杀手锏——peer认证。Linux上安装PostgreSQL时通常会创建一个名为postgres的系统用户以这个系统用户身份连接数据库时如果认证方式是peer数据库直接认为“你就是postgres”不用输密码。所以Linux下解决忘记密码问题通常是su到postgres系统用户用psql直接连进去改密码。Windows没有这个系统用户体系也没有su命令peer认证完全不可用所以才必须走改pg_hba.conf这条路线。这里也提醒一句如果你用的不是原生Windows安装包而是Docker Desktop运行PostgreSQL容器那解决问题的思路又不一样了。Docker容器里往往保留了postgres系统用户可以先docker exec -it容器名bash进入容器再用su postgres切换到数据库用户执行psql。Windows原生安装的PostgreSQL不存在这个入口老老实实改认证配置最靠谱。2. 动手术前先摸清现场服务名、配置文件、备份一个都不能少改配置虽然不复杂但准备工作没做好很容易搞出“把数据库搞得启动不了”的二次事故。我在实际处理中动手前会做三件事每一步都有明确目的。2.1 确认PostgreSQL服务名和运行状态Windows下PostgreSQL是以Windows服务的方式在后台运行的首先要把服务名和当前状态搞清楚。打开服务管理器的方式是Win R输入services.msc回车或者直接在任务管理器“服务”标签里找到它。服务名格式通常是postgresql-x64-15这种中间的版本号和你安装的PostgreSQL大版本一致。也可以用命令行确认sc query state all | findstr /i postgres这个命令会把所有名称里带postgres的服务列出来能同时看到服务名、状态和进程ID。如果服务没有启动先别急着启动先去检查配置文件和数据目录是否存在因为服务启动失败往往和配置有关。如果服务状态正常记下服务名后面重启时会用到。2.2 定位pg_hba.conf和postgresql.conf的位置这是整个过程中最容易卡住的一步。PostgreSQL的安装目录结构在不同版本和安装方式下略有差异但默认路径基本是C:\Program Files\PostgreSQL\15\data\pg_hba.conf其中15是主版本号data是数据目录。如果你安装时自定义了数据目录比如装到了D盘或者自定义路径记得去那个位置找。不确定的情况下可以在服务管理器里右键点击PostgreSQL服务选择“属性”查看“可执行文件的路径”里面会带 -D 参数后面跟的就是数据目录路径。举个例子服务属性的可执行文件路径可能是C:\Program Files\PostgreSQL\15\bin\pg_ctl.exe runservice -N postgresql-x64-15 -D C:\Program Files\PostgreSQL\15\data -w-D后面的路径就是数据目录pg_hba.conf就该在这个目录下面。另外提醒一句data目录默认对普通用户只读后面编辑文件的时候如果提示没有权限需要用管理员权限打开编辑器或者把文件复制到桌面改完再覆盖回去。2.3 备份pg_hba.conf这条不能省把原始pg_hba.conf文件复制一份出来命名为pg_hba.conf.bak存到一个安全的位置最好就在同一个目录下。为什么必须备份因为接下来的修改步骤中我们会在trust和scram-sha-256之间反复切换一旦写错、多写了一行、或者改了不该动的规则顺序数据库连接行为就可能完全失控。有了备份文件改回去的时候直接把备份内容复制粘贴一步到位。我见过有人改完trust之后忘记存原配置恢复的时候凭记忆写结果把IPv6行的认证方式漏改了数据库照样裸奔非常危险。备份之后用文本编辑器打开pg_hba.conf把文件里原有的内容大致看一遍确认当前的认证方式。下面的操作就在这里展开。3. 把认证从密码验证临时切换成trust并重启服务这一步是整个重置流程的核心操作改法很简单但有两个细节必须特别注意一是要改对行二是要改对认证方式字段。另外改完配置文件之后服务重启这一步不能省很多人在这里图省事用了reload结果连接行为没变化白白浪费时间排查。3.1 精确锁定要修改的认证规则行用编辑器打开pg_hba.conf后往下翻找到以host开头的那几行配置。Windows下通过psql连接本机时默认走的是TCP/IP协议对应的是IPv4的127.0.0.1/32和IPv6的::1/128这两行。也就是说至少要改这两行里的认证方式才能保证psql无论走IPv4还是IPv6都能免密连上。这里要特别强调一个容易犯的错很多人只改了host all all 127.0.0.1/32这一行改完之后用psql -h localhost去连接连不上因为localhost解析到了IPv6地址::1而被匹配到的还是原来那行的scram-sha-256。所以稳妥起见127.0.0.1/32和::1/128这两行全部改成trust。修改前这两行是host all all 127.0.0.1/32 scram-sha-256 host all all ::1/128 scram-sha-256修改后变成host all all 127.0.0.1/32 trust host all all ::1/128 trust注意只改最后一个字段认证方式前面的TYPE、DATABASE、USER、ADDRESS都不要动。不然可能出现更复杂的匹配问题。3.2 保存文件的编码陷阱在Windows上用记事本编辑pg_hba.conf有一个隐藏很深的坑编码格式。PostgreSQL对配置文件的编码要求是UTF-8不带BOM。如果直接用Windows自带的记事本保存大概率会存成带BOM的UTF-8格式或者如果你的系统区域设置是中文记事本甚至会默认存成ANSIGBK编码。这两种情况都可能导致PostgreSQL服务启动时报配置文件编码错误甚至直接拒绝启动。我的建议是不要用记事本用VS Code、Notepad、Sublime Text这类能控制编码的编辑器打开文件。保存时确认编码是UTF-8换行符保持原样LF或者CRLF都可以但最好和原来保持一致。如果手头实在没有第三方编辑器可以用记事本打开另存为时在“编码”下拉框里选择“UTF-8”这样至少能避开大部分编码问题。3.3 重启PostgreSQL服务别图省事用reload配置文件修改完成后必须让配置生效。pg_hba.conf这个文件其实是支持热加载的也就是不需要重启服务执行SELECT pg_reload_conf();或者用pg_ctl reload就能重新加载认证配置。既然能reload为什么我强烈建议直接重启服务原因有两点。第一reload虽然让新配置生效但已经建立的连接不会断开。如果在重置密码的过程中系统中还有旧的连接占着postgres用户可能会出现一些莫名其妙的并发问题。第二如果配置文件存在语法错误或编码问题reload不会报错而是悄悄地不加载你会发现trust根本不起作用还得回头去排查文件问题。而直接重启服务如果配置文件有问题服务启动会直接失败并给出日志提示问题暴露得又快又明确。重启服务推荐用net命令以管理员身份打开命令行net stop postgresql-x64-15 net start postgresql-x64-15服务名替换成你自己机器上的实际名称。如果net stop提示服务无法停止可能是数据目录下有会话正在频繁访问稍等几秒再试或者用taskkill /f /pid 进程号强制结束进程。不过正常情况下不要用强杀容易造成数据损坏能正常停止就正常停止。3.4 服务启动失败的排查入口如果重启后服务启动失败大概率出在配置文件上。Windows下服务启动失败的表现是启动时转圈然后弹窗提示“本地计算机上的postgresql-x64-15服务启动后停止”此时查看事件查看器Win R输入eventvwr.msc里的Windows日志-应用程序找到PostgreSQL相关的错误条目里面会指明具体错误行号和信息。最常见几种情况配置文件是UTF-8 with BOM报错信息类似invalid byte sequence for encoding UTF8某行规则语法写错比如字段数不对报错信息类似syntax error at or near scram端口被其他进程占用报错信息类似could not bind to address看到报错不要慌对照原始备份文件排查修改过的部分改回来就能恢复。这也是第一步要求备份的原因。4. 利用trust模式进入psql一条SQL改掉postgres密码服务成功启动并加载trust配置之后理论上此时不需要密码就能以postgres身份连进数据库。这一步重点说一下怎么进、进去了怎么改。4.1 找到psql入口并登录PostgreSQL的psql命令行工具位于安装目录的bin子目录下以PostgreSQL 15为例完整路径是C:\Program Files\PostgreSQL\15\bin\psql.exe如果你在命令行直接输入psql提示“不是内部或外部命令”说明bin目录没有加入系统的PATH环境变量这时候先cd到bin目录再执行cd C:\Program Files\PostgreSQL\15\bin然后连接数据库。这里建议把连接参数写全尤其不要省略-h指定主机psql -U postgres -h 127.0.0.1 -p 5432 -d postgres参数含义分别如下-U postgres 指定用户名-h 127.0.0.1 指定主机地址强制走IPv4避免localhost解析到IPv6-p 5432 指定端口如果你安装时改过端口这里填实际端口-d postgres 指定连接postgres数据库PostgreSQL自带的管理数据库由于认证方式是trust这一步不会要求输入密码会直接进入psql命令行提示符变成postgres#。如果这一步依然提示密码认证失败不用怀疑一定是配置文件没改对或者改完没重启服务成功回头检查第3步。顺便说一句连接的时候不要只用psql -U postgres而不加-h参数。这样在某些配置下可能会走Windows本地的Unix域套接字Windows 10及以上版本PostgreSQL也支持和pg_hba.conf里的127.0.0.1规则匹配不上。哪怕数据目录里同时有host all all 192.168.x.x的规则匹配顺序也是从上到下、第一条命中即停止所以明确指定-h 127.0.0.1是最省心的做法。4.2 执行ALTER USER并验证进入psql后直接执行下面的SQL语句完成密码重置ALTER USER postgres WITH PASSWORD YourNewStrongPassword;把YourNewStrongPassword替换成你想设置的新密码。这里有两个要注意的小细节。第一个是SQL语句里的密码需要用单引号包围。如果你的密码本身就包含单引号比如Im_admin这种那需要在SQL里把单引号写两次来转义ALTER USER postgres WITH PASSWORD Im_admin;第二个是Windows的命令行环境下如果密码包含中文、空格或者特殊字符建议先用简单的密码重置成功登录后再用alter user换成复杂的最终密码避免编码问题带来的二次困扰。虽然理论上psql可以处理UTF-8字符但Windows的cmd默认编码经常是GBK传输过程中可能出幺蛾子没必要冒这个险。验证这一步很多人会忽略但恰恰是最关键的。执行完成后退出psql\q然后重新用新密码尝试连接psql -U postgres -h 127.0.0.1 -p 5432 -d postgres这次由于trust模式还在依然不会要求输密码所以这种验证方式并不能真正验证密码是否生效。真正要验证的是下一步恢复scram-sha-256之后的连接这一步只需要确认能成功进入psql、执行ALTER USER没有报错就说明密码已经写入系统表了。5. 改回认证配置恢复安全基线密码重置完成最重要的一步来了把pg_hba.conf里的trust改回原来的scram-sha-256或者你原来是md5就改回md5。这一步绝对不可以省也不可以拖到“明天再说”。5.1 trust模式到底有多危险trust的意思是“完全信任不需要任何凭证”。在trust模式下只要网络能访问到PostgreSQL的端口任何人都可以免密连接数据库拥有全部操作权限。如果postgresql.conf里的listen_addresses设置的是所有网卡比如0.0.0.0那意味着整个局域网甚至公网的人都能直接登进来。即使listen_addresses是默认的localhost只要本机有别的用户能连接数据库端口也同样可以不输密码进来。我见过有人改trust模式重置完密码后忘记恢复第二天被运维同事打电话问“为什么数据库不用密码就能连”那一刻的尴尬和冷汗希望你别体验。所以良好的操作习惯是改之前就告诉自己trust只是临时的钥匙用完必须换回原来的锁。5.2 恢复配置并做双重验证把pg_hba.conf里刚才改过的那两行从trust改回scram-sha-256或md5。如果之前备份了原文件直接把备份内容覆盖回来最稳妥。这里需要留意一个细节如果原文件中还有其它host规则比如局域网其他网段的连接规则不需要动只关注你改过的那两行。改完后保存文件再次重启服务net stop postgresql-x64-15 net start postgresql-x64-15重启完成后做两个验证一是用新密码连接预期结果是成功psql -U postgres -h 127.0.0.1 -p 5432 -d postgres此时psql会提示输入密码输入新密码后能正常进入说明密码重置成功、认证配置恢复正确。二是可以故意输错一次密码预期结果是提示password authentication failed for user postgres。这个验证相当重要它证明数据库确实恢复了密码校验而不是仍然处于trust这种裸奔状态。修改前后的状态对比如下阶段pg_hba.conf认证方式连接时表现是否安全修改前scram-sha-256需要正确密码安全重置中trust无需密码直接连接危险仅临时重置后scram-sha-256需要新密码安全6. 这次操作中最容易翻车的几个环节整条链路走完之后再复盘一下实际操作中大家最容易翻车的地方。这些坑我自己全踩过写下来希望你能绕开。6.1 服务启动失败十有八九是文件编码和换行符问题前面说过Windows记事本保存UTF-8文件时会默认带上BOM头而PostgreSQL的配置解析器不认带BOM的UTF-8会直接报invalid byte sequence错误。这个坑在最开始改配置时最容易遇到因为你随手用记事本一存再启动服务数据库就起不来了。解决办法就是换用VS Code或Notepad编辑配置文件保存时编码选UTF-8。如果你手头实在没有这些工具用记事本打开文件选择“另存为”编码下拉框选“UTF-8”也能绕开BOM问题。还有一点保存时换行符尽量保持和原文件一致。虽然PostgreSQL对CRLF和LF都兼容但如果你在Windows下把LF改成CRLF某些情况下pg_hba.conf解析也会出现奇怪问题最稳妥的做法是“只改该改的字符其它一概不动”。6.2 psql命令找不到的N种情况Windows下输入psql提示“不是内部或外部命令”非常正常因为PostgreSQL安装时默认不会把bin目录加进PATH。解决办法也无非两种cd进bin目录再执行或者把bin目录手动加进系统环境变量。往PATH里加环境变量是长期开发更推荐的做法因为以后跑pg_dump、pg_restore这些工具都能直接用。操作路径是系统属性 - 高级系统设置 - 环境变量在Path里新增一条C:\Program Files\PostgreSQL\15\bin。另外提醒一下安装了多个PostgreSQL大版本比如同时存在14和15时PATH里不同的bin目录可能互相干扰。如果出现这种情况执行psql时直接用完整路径最稳妥别完全依赖环境变量。6.3 只改了IPv4行IPv6连接绕过了trust我在3.1节强调过Windows下psql连接localhost时很多情况会解析成IPv6地址::1。如果pg_hba.conf里只有IPv4那行改成了trustIPv6那行还是scram-sha-256连接就会失败。最保险的操作是把127.0.0.1/32和::1/128两行一起改别只改一半。同理恢复配置的时候这两行也要一起恢复。6.4 改完密码顺手做几件“防再忘”的小事密码重置成功不是终点真正该做的是防止再次陷入这种被动局面。我的实际经验是这么几件事第一把密码记录到密码管理工具里。不用复杂的自己习惯用的就行实在不行写在一个加密的文本里也比什么都不记强。但是别把密码明文贴在显示器底下或者放在桌面txt里这个见过太多反面教材了。第二在Windows的环境变量里配置PGPASSWORD可以免输密码但这种做法本质上等于明文存密码仅限个人开发机使用生产环境绝对不建议。第三给postgres设置一个密码永不过期属性防止哪天因为密码过期突然连不上。虽然默认情况下PostgreSQL的密码不会过期除非你在postgresql.conf里启用了密码有效期但这个知识点值得知道。第四如果你管理的不止一台机器把所有实例的连接信息整理成一份简明的清单包括IP、端口、服务名、认证方式、最近一次修改密码时间。有了这份清单下次再遇到类似“谁还记得密码”的情况不用再来一遍全套操作。说到底忘记数据库密码这种事谁都难免碰上但处理过一遍之后你会发现PostgreSQL的认证体系设计得其实相当灵活。只要掌握了pg_hba.conf这个总开关的原理很多凭密码没办法解决的场景都能找到突破口。希望这篇文章能帮你在Windows下解决这个棘手问题也欢迎你在实际操作中遇到奇怪的报错时回来交流毕竟数据库运维这条路踩坑才是常态交流多了才能真正进步。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门