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 ""; }
原因分析与解决方案
核心原因
- Semaphore服务运行用户为root:Semaphore默认以root用户启动systemd服务,因此它调用Ansible执行playbook时,全程使用root权限,WebGUI创建的用户仅用于界面操作权限控制,不影响底层执行的系统用户身份。
- localhost执行的特殊性:当playbook针对localhost执行时,Ansible默认使用当前运行Ansible的用户(即Semaphore服务的运行用户),不需要SSH连接,因此直接继承root权限。
- NFS配置可能未限制root:如果NFS挂载未启用
root_squash(默认通常启用,但可能被修改),客户端root用户可直接写入NFS目录,不会被映射为匿名用户。
解决方案
修改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
- 创建普通系统用户(如
在Semaphore中强制限制执行权限
- 在Semaphore的项目配置中,找到"Playbook Execution"相关设置,明确指定
remote_user为普通用户; - 禁用项目或任务的自动提权选项,确保未默认启用
become。
- 在Semaphore的项目配置中,找到"Playbook Execution"相关设置,明确指定
加固NFS挂载配置
- 检查NFS服务器的导出配置(
/etc/exports),确保添加root_squash选项,将客户端root用户映射为匿名用户:/nfs/share client_ip(rw,sync,root_squash) - 重新导出NFS并重新挂载客户端目录:
exportfs -ra mount -o remount /mnt/nfs
- 检查NFS服务器的导出配置(
Ansible全局配置限制
- 在
ansible.cfg的[defaults]段添加remote_user = your_normal_user,指定默认执行用户,但此设置仅针对远程主机,localhost仍依赖运行Ansible的系统用户。
- 在
内容的提问来源于stack exchange,提问作者dovla110010101
相关产品推荐
相关产品推荐

