如何在 ansible playbook 中干净地编辑 sshd_config 的基本安全选项?

Syn*_*ted 7 ansible

我正在尝试编写一个剧本,干净地编辑 /etc/ssh/sshd_config 以便它具有PasswordAuthentication noPermitRootLogin no.

我能想到的几个方法都是有问题的。

首先,我可以PasswordAuthentication|PermitRootLogin使用 lineinfile删除所有匹配的行,然后附加两个我想要的新行,但是 i) 这可能会以非原子方式失败并且 ii) 最后附加的行可以将它们与“匹配”块混合,这通常可以出现在最后。

我可以取代所有的线配套^(# *)?PasswordAuthentication使用PasswordAuthentication no,也使用lineinfile,但如果匹配行不存在就无法正常工作。另外,如果有多个匹配的行,我会有重复的PasswordAuthentication no行。

我可以为整个文件使用一个模板,但这意味着我需要指定所有内容,包括 HostKey,但我不想指定所有内容并希望保留其他选项的原始设置方式。

由于列出的问题,上述方法均不令人满意。是否有一种干净的方法可以可靠地进行所需的更改,是幂等的,并且如果系统中途失败也不会使系统处于不良状态?

Wol*_*ang 17

该解决方案仅需要一项任务,无需额外文件:

- name: Configure sshd
  lineinfile:
    path: "/etc/ssh/sshd_config"
    regex: "^(#)?{{item.key}}"
    line: "{{item.key}} {{item.value}}"
    state: present
  loop:
    - { key: "PermitRootLogin", value: "no" }
    - { key: "PasswordAuthentication", value: "no" } 
  notify:
    - restart sshd
Run Code Online (Sandbox Code Playgroud)

正如评论中指出的,这个解决方案是有风险的,因为它需要正则表达式匹配。如果没有匹配,则会在文件末尾生成一个新行,这可能与文件中的匹配部分发生冲突sshd_config


Zei*_*tor 8

我可以用 PasswordAuthentication no 替换匹配 ^(# *)?PasswordAuthentication 的每一行,也可以使用 lineinfile,但是如果匹配的行不存在,这将不起作用。此外,如果有多个匹配的行,我将有重复的 PasswordAuthentication 无行。

您只是没有得到/测试如何lineinfile有效地工作,因为这正是您正在寻找的解决方案。在您的特定情况下,如果没有反向引用,模块将:

  • 查看您要添加的行是否有效,在这种情况下它什么也不做
  • 如果该行不存在,请查找正则表达式以匹配它
  • 如果找到一个或多个匹配项,最后一个匹配项将被给定的行替换
  • 如果没有找到正则表达式,将在文件末尾添加该行
  • 如果您仍然需要在文件中的特定位置添加该行(如果该行不存在),您可以使用insertbeforeinsertafter

请参阅以下示例:

test.config具有多个匹配行的初始值:

# PasswordAuthentication no
# PermitRootLogin no
somevalue no
# PasswordAuthentication no
# PermitRootLogin no
othervalue yes
# PasswordAuthentication no
# PermitRootLogin no
Run Code Online (Sandbox Code Playgroud)

并且test2.config没有匹配

value none
othervalue no
yetanother yes
Run Code Online (Sandbox Code Playgroud)

测试手册:

---
- name: Line in file test
  hosts: localhost
  gather_facts: false

  tasks:
    - name: test replace
      lineinfile:
        path: "{{ item }}"
        regex: ^(# *)?PasswordAuthentication
        line: PasswordAuthentication no
      loop:
        - /path/to/test.config
        - /path/to/test2.config
Run Code Online (Sandbox Code Playgroud)

运行 playbook 会在第一次运行时更改文件,并在后续运行时报告正常(不再进行更改)。以下是模块修改过的文件。

test.config

# PasswordAuthentication no
# PermitRootLogin no
somevalue no
# PasswordAuthentication no
# PermitRootLogin no
othervalue yes
PasswordAuthentication no
# PermitRootLogin no
Run Code Online (Sandbox Code Playgroud)

test2.config

value none
othervalue no
yetanother yes
PasswordAuthentication no
Run Code Online (Sandbox Code Playgroud)


And*_*ndi 6

我认为你可以像这样lineinfile使用和使用state=absentstate=present

- name: deactivate PermitRootLogin
  lineinfile:
    path: "/etc/ssh/sshd_config"
    line: "PermitRootLogin no"
    state: present
  notify:
    - restart sshd

- name: ensure PermitRootLogin is not activated
  lineinfile:
    path: "/etc/ssh/sshd_config"
    line: "PermitRootLogin yes"
    state: absent
  notify:
    - restart sshd
Run Code Online (Sandbox Code Playgroud)

同样适用于PasswordAuthentication yes/no.


Vla*_*tka 3

如果模板不是一个选项,则应使用lineinfile 。要解决详细信息:

..附加我想要的两行新行,但是我)这可能会以非原子方式失败......

如果无法完成,请修复它并重复播放。

...如果有多个匹配行,我将有重复的PasswordAuthentication no 行。

验证配置,如果无法完成则修复并重复播放。

validate: "{{ sshd_path }} -t -f %s"
Run Code Online (Sandbox Code Playgroud)

以上方法均不能令人满意...

这样的期望是不现实的。这两个问题(任意失败、匹配行)都描述了模块不一定要解决的错误状态。lineinfile完全符合目的。例如,请参阅sshd.yml