The way I understand this, if “PermitRootLogin no” does not appear in the sshd_config file, it’ll append that to the bottom of the file.
So in the scenario where Ansible finds “PermitRootLogin yes” in the file, it will append “PermitRootLogin no” at the end of the config file.
The problem is that when SSH reads “PermitRootLogin yes” earlier in the file THAT configuration setting it what it uses. So the ‘no’ setting
at the end of the file is ignored, and Ansible is not doing anything for me. (http://man.openbsd.org/sshd_config.5)
I think its common practice to "harden" SSH by running the following in one of your playbooks:
>
- name: Disallow root SSH access
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin no"
line: "PermitRootLogin no"
state: present
notify:
- restart sshd
>
The way I understand this, if "PermitRootLogin no" does not appear in the sshd_config file, it'll append that to the
bottom of the file.
So in the scenario where Ansible finds "PermitRootLogin yes" in the file, it will append "PermitRootLogin no" at the end
of the config file.
The problem is that when SSH reads "PermitRootLogin yes" earlier in the file THAT configuration setting it what it
uses. So the 'no' setting
at the end of the file is ignored, and Ansible is not doing anything for me. (http://man.openbsd.org/sshd_config.5)
Hello Jon,
you need to adjust the regexp so it covers both "yes" and "no" as configuration values. Or just drop "no" from the
end of the regexp.
I’m not sure how that helps? Ansible will still add the ‘no’ setting at the bottom of the sshd_config file and the ‘yes’ setting earlier in the sshd_config file is still active.
Kai, I tried removed the no from my regexp and retested. Ansible did replace that line! It did not add a new entry at the end of the config file.
Now I have to go figure out WHO changed the config file from no to yes.
Thank you.
Cyril,when I tried your regex and Ansible barked about the \s Both before and after PermitRootLogin I tried double bask-slash s (#|#\s|\s|) and that works.
If the entry isn’t there it will add it (who cares if a commented entry already exists). If it already exists and has a different value it will replace the line with the new value.
@Jon glad you found a solution that works for you. Strangely I don’t have issues with just one backslash. Might be due to the old python version that is used on macOS.
@SCRigler basically you are right. But if someone sees the line that is commented out she/he might think the setting fell back to the default setting and close the config file again without noticing that way down in the config file there is actually a working setting that does overwrite the default. Might make troubleshooting a bit more frustrating that way.
“S C Rigler” —05.09.2019 15:39:57—All of these regex’s seem a little too specific. Why not just: regexp: ‘^PermitRootLogin\b’
> regexp: "^(#|#\s|\s|)PermitRootLogin\s*(no|yes)"
Actually \s* is not *one or many*, but *zero or many*. There should be at
least one space so `\s+`
1) Searching for both commented and non-commented lines is risky. There
might be both present in the file and the result will be unpredictable.
It's better to ignore commented lines.
regexp: "^(\s*)PermitRootLogin\s+(no|yes)"
2) Searching for (no|yes) does not make any sense. We're going to replace it
anyway. This may make things even worse by preventing a potential syntax
error to be corrected. Replace it with general pattern.
Vlado, It’s my understanding that the validate step should be done once in the playbook. Not for each sshd action in the playbook. Is that what you are saying?
That is because you are using double quotes and not single quotes around the regexp.
You could also remove the quotes since you don't actually need them.
If you are going to do hardening and have some kind reliability that it work you should not be using the lineinfile module.
Instead go for the copy or template module that Jonathan mention previously in this thread.
The reason for that is that lineinfile _*only*_ changes the last line it find in the file and openssh only uses the first line it find.
So you Ansible code can easily be tricked by these lines.
"The validation command to run before copying into place..."
It works for me fine that way. The burden of the repeated validation is
present in the first run only (when idempotent). It's worth to be sure sshd
will keep running.