You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible执行postgresql_query模块切换postgres用户报chmod错误

问题场景

编写的Ansible Playbook代码如下:

- name: Check if postgres is running
  community.postgresql.postgresql_ping:
    db: "{{ stl_database }}"
    port: "{{ stl_postgres_port }}"
    login_host: "{{ db_host }}"
    login_password: "{{ postgres_password }}"
  register: postgres_availabe

- name: Check the database versions
  postgresql_query:
    db: "{{ stl_database }}"
    port: "{{ stl_postgres_port }}"
    login_host: "{{ db_host }}"
    login_user: postgres
    login_password: "{{ postgres_password }}"
    query: "{{ get_db_version }}"
  become: yes
  become_user: postgres
  register: db_version_return
  when: postgres_availabe.is_available == true

已通过ansible-galaxy collection install community.postgresql命令安装依赖的社区集合。其中第一个任务用于检测远程服务器{{ db_host }}上的PostgreSQL服务是否正常运行,第二个任务调用postgresql_query模块,配置become: yes切换为postgres用户,执行{{ get_db_version }}定义的查询语句获取数据库版本,任务设置为仅在PostgreSQL服务可用时触发。

报错现象

执行Playbook时第一个任务运行正常,第二个任务执行失败,报错信息如下:

fatal: [localhost]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chmod: invalid mode: ‘A+user:postgres:rx:allow’\nTry 'chmod --help' for more information.\n}). For information on working around this, see https://docs.ansible.com/ansible-core/2.12/user_guide/become.html#risks-of-becoming-an-unprivileged-user"}

添加-vvv参数查看详细执行日志,可发现Ansible在上传模块临时文件后,依次尝试执行setfacl赋权、chmod加执行权限、chown修改文件属主为postgres后,额外尝试执行chmod +a 'postgres allow read,execute'、chmod A+user:postgres:rx:allow命令为临时文件配置权限,最终在执行该chmod命令时失败。手动在服务器上执行相同chmod命令,同样返回chmod: invalid mode: ‘A+user:postgres:rx:allow’错误。

完全相同的Playbook代码在旧Ansible服务器上可长期正常运行,仅在新部署的、刚安装完community.postgresql集合的Ansible服务器上执行时出现上述错误。

问题根因
  • 报错中提到的chmod A+user:postgres:rx:allow和chmod +a 'postgres allow read,execute'分别是AIX系统、BSD/macOS系统的chmod ACL语法,Linux系统默认使用的GNU版本chmod不支持这两种语法,直接执行必然报错。
  • Ansible切换到非特权用户执行任务时,会按固定优先级顺序尝试多种方式给上传的临时模块文件赋权:优先使用setfacl配置POSIX ACL给目标用户授权,若setfacl执行失败,则依次尝试BSD风格chmod ACL、AIX风格chmod ACL,所有方式都失败就抛出上述错误。
  • 新部署的服务器多为最小化安装环境,默认未安装提供setfacl命令的acl工具包,导致Ansible第一步setfacl赋权失败,才会回退到后续不兼容的chmod语法分支,最终报错。旧服务器可正常运行是因为环境中已预装acl包,Ansible直接通过setfacl完成赋权,不会走到后续错误分支。
修复方案

按优先级从高到低可选以下方案:

  • 方案1(推荐,无安全风险):在被管理的目标服务器上安装acl工具包,对应不同发行版的安装命令:
    • Debian/Ubuntu系列:执行apt update && apt install -y acl
    • RHEL/CentOS/Rocky/AlmaLinux系列:执行dnf install -y acl(CentOS 7等老版本用yum install -y acl)
      安装完成后重新执行Playbook即可,Ansible会优先调用setfacl完成临时文件赋权,不会再触发不兼容的chmod命令。
  • 方案2(适合无法安装软件包的场景,有轻微安全风险):修改Ansible控制节点的ansible.cfg配置,在[defaults]段添加如下配置,关闭ACL赋权逻辑,允许临时文件设为全局可读:
    allow_world_readable_tmpfiles = True
    
    该配置会让Ansible直接给临时文件加全局可读权限,无需单独给postgres用户赋权,仅适合服务器全为可信内网主机的场景使用,避免多用户主机上的临时文件信息泄露。
  • 方案3(针对当前PostgreSQL场景的最优解,完全规避become逻辑):去掉第二个任务中的become: yes和become_user: postgres配置。第一个任务未切换用户、仅通过密码连接PostgreSQL已经执行成功,说明数据库已允许对应账号通过TCP方式认证,第二个任务同样可以直接通过传入的连接参数完成查询,不需要切换到系统的postgres用户,从根源上避开临时文件赋权逻辑。

内容的提问来源于stack exchange,提问作者Philip Shangguan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:57:37