← [ BACK_TO_NOTES ]

在 Linux VM 上部署 PostgreSQL

在 Ubuntu/Debian 类 Linux VM 上安装 PostgreSQL、创建最小权限应用角色、按需开放远程连接、限制网络暴露面,并通过本机与远程连接验证部署结果。

#linux #howto #evergreen

[!info] related notes

在 Linux VM 上部署 PostgreSQL

目标与成功状态

完成后至少满足:

systemctl status postgresql
→ service active

sudo -u postgres psql
→ 本机管理连接成功

psql "postgresql://app_user@<db-host>/<app_db>"
→ 应用角色从允许的网络路径连接成功

ss -lntp
→ PostgreSQL 只监听预期接口

firewall
→ 只允许预期来源访问 5432

这篇 howto 关注单机 VM 部署闭环,不负责 PostgreSQL 原理、查询优化、HA/PITR 或云托管选型。

1. 先决定网络边界

部署前先回答:

  • 只有 VM 本机应用访问?
  • 同一私有 LAN / VPC 中的应用访问?
  • 需要跨公网访问?

默认最安全的是:

数据库不直接暴露公网
→ 本机 / 私网访问
→ 跨公网优先 VPN / SSH tunnel / private network

不要先把 5432/tcp 对 0.0.x.x/0 开放,再考虑安全。

2. 安装 PostgreSQL

Ubuntu / Debian 通常可以直接使用发行版包:

sudo apt update
sudo apt install postgresql

如果项目明确需要某个 PostgreSQL 主版本,再使用 PostgreSQL 官方 PGDG APT repository,并安装指定版本。

版本选择应来自项目兼容性与生命周期要求,不要把某个历史版本永久写死在通用部署笔记里。

安装后验证:

systemctl status postgresql
psql --version

3. 先验证本机数据库

进入管理 shell:

sudo -u postgres psql

查看基础信息:

SELECT version();
SHOW listen_addresses;

先证明本机实例健康,再处理远程连接;否则网络层和数据库层问题会混在一起。

4. 创建应用角色与数据库

不要让业务应用直接使用 PostgreSQL superuser。

示例:

CREATE ROLE app_user
  LOGIN
  PASSWORD 'replace-with-a-secret';

CREATE DATABASE app_db
  OWNER app_user;

然后退出:

\q

凭据应进入 secret manager / 环境变量,而不是提交到仓库。

5. 决定是否需要远程 TCP 连接

仅本机访问

保持只监听 loopback 即可,通常不需要开放防火墙端口。

私网远程访问

远程 TCP 连接需要同时满足两层:

postgresql.conf
listen_addresses
        +
pg_hba.conf
允许的 user / database / source network / auth method

只改其中一层都不够。

查看实际配置文件:

SHOW config_file;
SHOW hba_file;

不要假设路径一定是某个固定版本目录。

6. 配置监听地址

例如只监听 VM 的私网地址与 localhost:

listen_addresses = 'localhost,10.0.x.x'

如果使用 '*',必须依赖 pg_hba.conf 与主机/云防火墙进一步收窄来源;不要把 listen_addresses='*' 理解成完整访问控制。

修改后 reload/restart,并再次验证:

sudo systemctl restart postgresql
sudo ss -lntp | grep 5432

7. 配置 pg_hba.conf

例如只允许应用用户从私网子网连接指定数据库:

host    app_db    app_user    10.0.x.x/24    scram-sha-256

这里四个核心问题是:

连接类型是什么?
访问哪个 database?
哪个 role?
来自哪个 network?
用什么认证方法?

不要用:

host all all 0.0.x.x/0 ...

作为默认配置。

修改后可以 reload:

sudo systemctl reload postgresql

8. 配置主机 / 云防火墙

如果 VM 上使用 UFW,只允许实际应用来源:

sudo ufw allow OpenSSH
sudo ufw allow from 10.0.x.x/24 to any port 5432 proto tcp
sudo ufw enable
sudo ufw status

如果 VM 还位于云平台中,还要同时检查 Security Group / NSG / VPC firewall。

访问链通常是:

Client
→ cloud firewall
→ VM firewall
→ PostgreSQL listen socket
→ pg_hba.conf
→ role authentication
→ database privileges

任何一层拒绝都会表现成“连不上数据库”,所以排障要逐层验证。

9. 从客户端验证

先验证网络:

nc -vz <db-host> 5432

再验证 PostgreSQL 协议与认证:

psql "host=<db-host> port=5432 dbname=app_db user=app_user"

不要只用 ping 判断 PostgreSQL 是否可达;ICMP 成功不能证明 TCP 5432、认证或数据库权限正确。

10. 应用连接

应用连接字符串示例:

postgresql://app_user:<secret>@<db-host>:5432/app_db

生产环境还应明确:

  • TLS 要求;
  • connection pool;
  • statement / connection timeout;
  • secret rotation;
  • migration ownership;
  • backup / restore;
  • monitoring。

这些是下一层运维设计,不应全部塞进“安装数据库”步骤里。

验证矩阵

层验证
servicesystemctl status postgresql
local DBsudo -u postgres psql
listenerss -lntp
cloud / host firewall从真实 client 测 TCP 5432
HBA / authpsql 使用真实 app role
privileges执行最小 CREATE/SELECT 或应用 migration
application应用启动并完成 health check

常见失败路径

Connection refused

优先检查:

  1. PostgreSQL service 是否运行;
  2. listen_addresses;
  3. 实际监听 IP/port;
  4. firewall。

no pg_hba.conf entry

说明 TCP 已到达 PostgreSQL,但 HBA 没有匹配规则。

检查:

  • database;
  • role;
  • client CIDR;
  • SSL / non-SSL record 类型。

password authentication failed

网络和 HBA 已经基本通过,继续检查:

  • role 是否正确;
  • secret 是否正确;
  • role 是否允许 LOGIN;
  • 客户端是否连到了预期实例。

本机能连,远程不能连

把问题分层:

listen_addresses
→ host/cloud firewall
→ pg_hba.conf
→ authentication

不要反复重装 PostgreSQL。

不再推荐的旧习惯

  • 为“安全”单纯更换 5432 端口:只能减少部分扫描噪声,不是访问控制。
  • 为方便测试直接开放 0.0.x.x/0:5432。
  • 应用长期使用 postgres superuser。
  • 把固定配置文件路径写死到某个 PostgreSQL 主版本。
  • 在通用部署笔记中硬编码某一台 VMware 的 IP、账号和资源规格。

无提示执行检查

不看正文,在一台空 Linux VM 上说明并执行:

  1. 安装 PostgreSQL;
  2. 证明本机实例健康;
  3. 创建非 superuser 应用角色和数据库;
  4. 仅允许一个指定私网 CIDR 访问;
  5. 用 ss、firewall 和 psql 分层验证;
  6. 制造一次 HBA 拒绝,并根据错误定位到正确层;
  7. 解释 listen_addresses、firewall、pg_hba.conf、role privilege 四层为什么不能互相替代。
创建于 2025/1/1 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本