【问题标题】:Is it safe to edit /etc/sudoers with the Ansible "lineinfile" module?使用 Ansible“lineinfile”模块编辑 /etc/sudoers 是否安全?
【发布时间】:2021-03-15 18:09:49
【问题描述】:

我想根据this的回答来更改sudo会话超时。我可以编辑普通文件:

lineinfile:
  path: /etc/sudoers
  regexp: ^Defaults  env_reset
  line: Defaults  env_reset,timestamp_timeout=60

但是在我/etc/sudoers的第一行写着:# This file MUST be edited with the 'visudo' command as root.怎么处理呢?
P.S.
尽管简短的回答是肯定的,但人们必须阅读 Konstantin Suvorov answer 关于使用 lineinfile 的正确方法以及非常有趣的 techraf answer 关于这种方式可能存在的陷阱

【问题讨论】:

  • visudo 只在 vi 中打开 sudoers 文件... 为什么需要它?
  • @cricket_007 我想用 ansible 设置 timestamp_timeout=60 而不是 5
  • @cricket_007 它不是手动修改的 - 它正在由他指定的正则表达式编辑?这正是 Red Hat 建议的方式 - docs.ansible.com/ansible/latest/lineinfile_module.html
  • @ElRuso,...我同意 OP 的要求是愚蠢的,但这很可能是公司政策合规性的事情(在某处使用规则“对 /etc/sudoers 的所有编辑必须使用visudo”,并尝试在遵守该规则的同时实现自动化)。

标签: ansible


【解决方案1】:

对于这种情况有一个安全网选项:validate

在复制到位之前运行的验证命令。要验证的文件的路径通过“%s”传入,该路径必须如下例所示。该命令是安全传递的,因此扩展和管道等 shell 功能将不起作用。

如果您查看lineinfile 模块的示例部分,您会确切地看到您需要什么:

# Validate the sudoers file before saving
- lineinfile:
    path: /etc/sudoers
    state: present
    regexp: '^%ADMIN ALL='
    line: '%ADMIN ALL=(ALL) NOPASSWD: ALL'
    validate: '/usr/sbin/visudo -cf %s'

【讨论】:

  • 这很好用。我必须对正则表达式进行一项更改:'^%ADMIN\s+ALL='。这允许一行上有多个空格。否则我会得到一个重复的行。
【解决方案2】:

如果您已测试语法是否正确,那是安全的。

鼓励visudo 的目的是防止有人通过创建无效的/etc/sudoers 来阻止自己管理系统,无论是打字错误还是想法。

当您使用 Ansible 执行编辑时,您可以在推出之前测试执行该编辑的代码,以便使用您的实际配置文件、环境和 sudo 版本做正确的事情。因此,人们对手工打错字或语法错误的担忧并不立即相关。

【讨论】:

  • 我非常感谢“thinko”。我将开始使用它。
【解决方案3】:

虽然this answer 正确定义了事物,this one 提供了对潜在问题的缓解措施,但让我们看看您的代码。

您要求 Ansible(可能)替换以下方式定义的行:

regexp: ^Defaults  env_reset

这显然是一种不好的做法,如果在sudoers 文件中对Defaults 以外的参数重复,可能会导致严重问题。


一般Defaults是配置参数,env_reset是可能的值之一。

你不能假设实际的配置文件总是包含^Defaults env_reset字符串。

如果设置了不同的值,则正则表达式将不匹配,您最终会添加以 Defaults 开头的第二行。


所以使用lineinfile 的正确方法是使用regexp 参数只匹配配置参数,而不是它的值。在你的情况下:

regexp: ^Defaults
line: Defaults  env_reset,timestamp_timeout

另一个潜在的缺陷是sudoers 包含应按正确顺序编写的部分。如果您修改的文件不包含正则表达式指定的行,lineinfile 将在文件末尾添加一个新行,它可能会被忽略或导致错误(但这应该通过验证发现),如果人们稍后查看文件,很可能会引起混淆。所以最好指定insertafterinsertbefore

【讨论】:

  • ^^这个。但是 - 仔细测试。如果您的 insert(before|after) 逻辑不正确,它将掉到文件的末尾和/或您最终会得到重复。请注意,特别是在“Jr SysAdmin Elmo”喜欢编辑配置的大量机器和/或系统上工作时,它可能并不总是与您期望的完全一样。谨防简单化的假设。 ...测试,测试,测试。抛出和错误,让您的系统保持一致等;不惜一切代价。
  • 我?对不起,你误会我了。一般是在讨论花生画廊,说在编写正则表达式时要确保你的逻辑是正确的。对于不涉及此特定测试的案例,我只是在摘要中同意您的观点。你是王牌。
  • 好吧,抱歉,我确实误会了。
【解决方案4】:

我认为您缺少的是为了编辑 /etc/sudoers 您需要 sudo-access。要在 Ansible 中执行此操作,您只需添加 become 标志。

name: Change Sudo Timeout
become: yes
lineinfile:
  path: /etc/sudoers
  regexp: ^Defaults  env_reset
  line: Defaults  env_reset,timestamp_timeout=60

【讨论】:

  • @cricket_007 正确!这就是为什么您需要将 become 标志添加到 Ansible!
  • visudo 与您建议的“sudo-access”无关。
  • visudo/etc/sudoers 的副本上运行 vi,并在保存前对结果进行语法检查。它的中心目的是语法检查,而不是权限提升;如果这个答案不提供所说的语法检查,那就是离题了。
  • @CharlesDuffy 我不确定提问者的意思——但我们会发现的。这是 Red Hat 建议的方式(没有提到验证),所以我认为这是正确的方法。
  • 顺便说一句,我想说visudo 尊重EDITOR 环境变量(因此名称中的vi 有点误导),所以如果你设置EDITOR 来调用(仅)执行您所需的单个编辑的脚本,就在这里。
【解决方案5】:

您可以将所需的设置放入/etc/sudoers.d 目录中,而不是直接编辑/etc/sudoers,如下所示:

- name: Change sudo session timeout
  lineinfile:
    dest: /etc/sudoers.d/ssh_session_timeout
    line: 'Defaults  env_reset,timestamp_timeout=60K'
    create: yes
    owner: root 
    group: root 
    mode: "0440"
    state: present
    validate: 'visudo -c -f %s'

【讨论】:

  • 为什么更安全? (除了验证,也可以验证单个文件,如Konstantin's answer
  • 实际上,您提出的解决方案更容易出错,因为您只验证单个文件,而忽略了文件之间的冲突设置可能会发生错误这一事实。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
相关资源
最近更新 更多