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

Semaphore/Ansible默认以root执行命令的原因及解决方法问询

Ansible/Semaphore默认以root执行的原因及权限控制问题

我是Ansible/Semaphore新手,已完成Semaphore安装,服务正常运行并在WebGUI中创建了管理员及普通用户。测试时,同事编写的playbook执行写入无权限访问的NFS挂载目录操作,任务无报错完成,且文件属主和属组均为root。

按我的理解,Ansible应默认以运行playbook的用户执行,需提权时才使用become及become_user参数。为何会默认以root执行?如何阻止这种高权限操作以避免风险?


相关配置

ansible.cfg

# Since Ansible 2.12 (core):
# To generate an example config file (a "disabled" one with all default settings, commented out):
#               $ ansible-config init --disabled > ansible.cfg
#
# Also you can now have a more complete file by including existing plugins:
# ansible-config init --disabled -t all > ansible.cfg

# For previous versions of Ansible you can check for examples in the 'stable' branches of each version
# Note that this file was always incomplete  and lagging changes to configuration settings

# for example, for 2.9: https://github.com/ansible/ansible/blob/stable-2.9/examples/ansible.cfg
[defaults]
host_key_checking = false

主机与角色配置

  • hosts文件:所有内容均被注释
  • roles目录:为空

Semaphore的config.json

{
"mysql": {
    "host": "127.0.0.1:3306",
    "user": "root",
    "pass": "xxxxxxxxxxxx",
    "name": "ansible-db",
    "options": null
},
"bolt": {
    "host": "",
    "user": "",
    "pass": "",
    "name": "",
    "options": null
},
"postgres": {
    "host": "",
    "user": "",
    "pass": "",
    "name": "",
    "options": null
},
"dialect": "mysql",
"port": "",
"interface": "",
"tmp_path": "/opt/semaphore",
"cookie_hash": "xxxxxxxxxxxxxx=",
"cookie_encryption": "xxxxxxxxxxxxxx=",
"access_key_encryption": "xxxxxxxxxxxxxxx=",
"email_sender": "",
"email_host": "",
"email_port": "",
"email_username": "",
"email_password": "",
"ldap_binddn": "",
"ldap_bindpassword": "",
"ldap_server": "",
"ldap_searchdn": "",
"ldap_searchfilter": "",
"ldap_mappings": {
    "dn": "",
    "mail": "",
    "uid": "",
    "cn": ""
},
"telegram_chat": "",
"telegram_token": "",
"max_parallel_tasks": 0,
"email_alert": false,
"email_secure": false,
"telegram_alert": false,
"ldap_enable": false,
"ldap_needtls": false,
"ssh_config_path": "",
"demo_mode": false
 }

Nginx反向代理配置(不影响权限逻辑)

server {
listen 80;
server_name cyclops.hll.mpg.de;
client_max_body_size 0;
chunked_transfer_encoding on;

location / {
proxy_pass "http://127.0.0.1:3000/";
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
proxy_request_buffering off;
proxy_buffer_size 16k;
proxy_busy_buffers_size 24k;
proxy_buffers 64 4k;
}

location /api/ws {
    proxy_pass "http://127.0.0.1:3000/api/ws";
proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Origin "";
}

原因分析与解决方案

核心原因

  1. Semaphore服务运行用户为root:Semaphore默认以root用户启动systemd服务,因此它调用Ansible执行playbook时,全程使用root权限,WebGUI创建的用户仅用于界面操作权限控制,不影响底层执行的系统用户身份。
  2. localhost执行的特殊性:当playbook针对localhost执行时,Ansible默认使用当前运行Ansible的用户(即Semaphore服务的运行用户),不需要SSH连接,因此直接继承root权限。
  3. NFS配置可能未限制root:如果NFS挂载未启用root_squash(默认通常启用,但可能被修改),客户端root用户可直接写入NFS目录,不会被映射为匿名用户。

解决方案

  1. 修改Semaphore服务运行用户

    • 创建普通系统用户(如semaphore),并赋予必要的目录权限:
      useradd -r -s /sbin/nologin semaphore
      chown -R semaphore:semaphore /opt/semaphore
      
    • 修改Semaphore的systemd服务文件(通常为/etc/systemd/system/semaphore.service),将User和Group设置为semaphore:
      [Service]
      User=semaphore
      Group=semaphore
      
    • 重载systemd并重启服务:
      systemctl daemon-reload
      systemctl restart semaphore
      
  2. 在Semaphore中强制限制执行权限

    • 在Semaphore的项目配置中,找到"Playbook Execution"相关设置,明确指定remote_user为普通用户;
    • 禁用项目或任务的自动提权选项,确保未默认启用become。
  3. 加固NFS挂载配置

    • 检查NFS服务器的导出配置(/etc/exports),确保添加root_squash选项,将客户端root用户映射为匿名用户:
      /nfs/share  client_ip(rw,sync,root_squash)
      
    • 重新导出NFS并重新挂载客户端目录:
      exportfs -ra
      mount -o remount /mnt/nfs
      
  4. Ansible全局配置限制

    • 在ansible.cfg的[defaults]段添加remote_user = your_normal_user,指定默认执行用户,但此设置仅针对远程主机,localhost仍依赖运行Ansible的系统用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:55:12