Skip to content

PostgreSQL 用户账户管理

概述

PostgreSQL 作为一个可供外部访问的服务器守护程序,其安全运行的基础之一就是使用专门的系统用户账户。本章将深入探讨如何正确创建和管理 PostgreSQL 的运行用户账户,以及相关的安全最佳实践。

为什么需要专用用户账户

安全原则

PostgreSQL 需要在专用的用户账户下运行,这遵循了以下重要的安全原则:

INFO

最小权限原则

专用用户账户确保 PostgreSQL 进程只拥有完成其任务所需的最小权限,降低了安全风险。

风险隔离

使用专用账户使用共享账户(如 nobody)
✅ 数据隔离❌ 数据混杂
✅ 权限控制❌ 权限过度
✅ 审计清晰❌ 审计混乱
✅ 故障隔离❌ 影响其他服务

用户账户创建

自动创建

大多数 PostgreSQL 预打包版本(如通过包管理器安装)会自动处理用户账户的创建:

bash
# 安装时自动创建 postgres 用户
sudo apt update
sudo apt install postgresql postgresql-contrib

# 验证用户是否已创建
id postgres
bash
# 安装时自动创建 postgres 用户
sudo yum install postgresql-server postgresql-contrib

# 验证用户是否已创建
id postgres
bash
# 安装时自动创建 postgres 用户
brew install postgresql

# 验证用户是否已创建
id postgres

手动创建用户账户

如果需要手动创建 PostgreSQL 用户账户,可以使用以下方法:

使用 useradd 命令

bash
# 创建 postgres 用户(推荐方式)
sudo useradd -r -s /bin/bash -d /var/lib/postgresql -m postgres

# 参数解释:
# -r: 创建系统用户
# -s: 指定登录 shell
# -d: 指定家目录
# -m: 创建家目录

使用 adduser 命令(Debian/Ubuntu)

bash
# 在 Debian/Ubuntu 系统上使用 adduser
sudo adduser --system --group --home /var/lib/postgresql --shell /bin/bash postgres

验证用户创建

创建用户后,验证其配置是否正确:

bash
# 查看用户信息
id postgres

# 输出示例:
# uid=999(postgres) gid=999(postgres) groups=999(postgres)

# 检查用户的家目录
ls -la /var/lib/postgresql

# 检查用户的 shell
grep postgres /etc/passwd

用户账户配置最佳实践

目录权限设置

bash
# 设置数据目录的所有者和权限
sudo mkdir -p /var/lib/postgresql/data
sudo chown -R postgres:postgres /var/lib/postgresql
sudo chmod 700 /var/lib/postgresql/data

# 验证权限设置
ls -la /var/lib/postgresql/

WARNING

权限警告

数据目录必须设置为 700 权限(只有所有者可读写执行),这是 PostgreSQL 的安全要求。

可执行文件权限

bash
# 确保 postgres 用户不拥有可执行文件
ls -la /usr/bin/postgres

# 输出应显示 root 拥有可执行文件:
# -rwxr-xr-x 1 root root ... /usr/bin/postgres

# 如果发现问题,修正权限:
sudo chown root:root /usr/bin/postgres*
sudo chown root:root /usr/lib/postgresql/*/bin/*

环境变量配置

为 postgres 用户配置适当的环境变量:

bash
# 切换到 postgres 用户
sudo -u postgres bash

# 编辑 .bashrc 文件
cat >> ~/.bashrc << 'EOF'
# PostgreSQL 环境变量
export PGDATA=/var/lib/postgresql/data
export PGLOG=/var/log/postgresql/postgresql.log
export PATH=/usr/lib/postgresql/14/bin:$PATH
EOF

# 使配置生效
source ~/.bashrc

实际应用场景

场景一:初始化数据库集群

bash
# 以 postgres 用户身份初始化数据库
sudo -u postgres initdb -D /var/lib/postgresql/data

# 启动 PostgreSQL 服务
sudo -u postgres pg_ctl -D /var/lib/postgresql/data -l /var/log/postgresql/postgresql.log start

场景二:安全检查脚本

创建一个脚本来验证 PostgreSQL 用户账户的安全配置:

bash
#!/bin/bash
# 文件名: check_postgres_security.sh

echo "=== PostgreSQL 用户安全检查 ==="

# 检查 postgres 用户是否存在
if id postgres &>/dev/null; then
    echo "✅ postgres 用户存在"

    # 检查用户的 UID
    uid=$(id -u postgres)
    if [ $uid -lt 1000 ]; then
        echo "✅ postgres 是系统用户 (UID: $uid)"
    else
        echo "⚠️  postgres 不是系统用户 (UID: $uid)"
    fi
else
    echo "❌ postgres 用户不存在"
    exit 1
fi

# 检查数据目录权限
if [ -d "/var/lib/postgresql/data" ]; then
    perms=$(stat -c "%a" /var/lib/postgresql/data)
    if [ "$perms" = "700" ]; then
        echo "✅ 数据目录权限正确 ($perms)"
    else
        echo "❌ 数据目录权限不正确 ($perms),应该是 700"
    fi
else
    echo "⚠️  数据目录不存在"
fi

# 检查可执行文件所有者
postgres_bin=$(which postgres)
if [ -n "$postgres_bin" ]; then
    owner=$(stat -c "%U" "$postgres_bin")
    if [ "$owner" = "root" ]; then
        echo "✅ PostgreSQL 可执行文件由 root 拥有"
    else
        echo "❌ PostgreSQL 可执行文件由 $owner 拥有,应该由 root 拥有"
    fi
fi

echo "=== 检查完成 ==="

场景三:服务管理

使用 systemd 管理 PostgreSQL 服务时的用户配置:

ini
# /etc/systemd/system/postgresql.service
[Unit]
Description=PostgreSQL database server
After=network.target

[Service]
Type=notify
User=postgres
Group=postgres
ExecStart=/usr/bin/postgres -D /var/lib/postgresql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0

[Install]
WantedBy=multi-user.target

常见问题与解决方案

问题 1:权限被拒绝

错误信息:

FATAL: data directory "/var/lib/postgresql/data" has wrong ownership

解决方案:

bash
# 修正数据目录所有权
sudo chown -R postgres:postgres /var/lib/postgresql/data
sudo chmod 700 /var/lib/postgresql/data

问题 2:用户无法登录

错误信息:

su: Authentication failure

分析过程:

  1. 检查用户是否设置了密码
  2. 验证用户的 shell 配置
  3. 确认用户账户是否被锁定

解决方案:

bash
# 检查用户状态
sudo passwd -S postgres

# 如果需要,为用户设置密码
sudo passwd postgres

# 或者使用 sudo 切换用户
sudo -u postgres -i

问题 3:多个 PostgreSQL 版本

当系统中安装了多个 PostgreSQL 版本时:

bash
# 查看所有 PostgreSQL 相关用户
grep postgres /etc/passwd

# 为不同版本创建不同用户(如果需要)
sudo useradd -r -s /bin/bash -d /var/lib/postgresql-12 -m postgres12
sudo useradd -r -s /bin/bash -d /var/lib/postgresql-14 -m postgres14

安全注意事项

DANGER

重要安全提醒

  1. 永远不要以 root 用户运行 PostgreSQL
  2. 永远不要让 postgres 用户拥有可执行文件
  3. 永远不要使用 nobody 或其他共享的系统用户

监控用户活动

sql
-- 在 PostgreSQL 中监控用户连接
SELECT
    usename,
    application_name,
    client_addr,
    backend_start,
    state
FROM pg_stat_activity
WHERE usename IS NOT NULL;

总结

PostgreSQL 用户账户的正确配置是数据库安全的基础。通过使用专用的用户账户,我们可以:

  1. 最小化安全风险 - 限制进程权限,防止权限滥用
  2. 实现服务隔离 - 避免与其他服务产生冲突
  3. 简化管理维护 - 清晰的权限边界便于管理
  4. 提高系统稳定性 - 减少因权限问题导致的服务中断

遵循本章介绍的最佳实践,可以确保 PostgreSQL 在安全可靠的环境中运行,为整个数据库系统的安全奠定坚实基础。