Might run SSH on several ports
Pamplemousse opened this issue · 3 comments
Actually, if we change the ssh_port
variable, it ends up adding a line containing port <ssh_port value>
to the sshd_config
file. Thus, the daemon is listening on several ports, and the related ufw rules are added.
IMHO, the expected behaviour would be to have the daemon listening on a single port. It is actually a bit misleading: reading the config, we can expect ssh to be accessible on a single port, which might not be the case based on the "history" of the changes...
Thank you! Your'e right. Unfortunately this is hard to fix correctly. If we use a regexp for this only the last occurrence of "^Port\ " will be overwritten with the specified port, leaving other port definitions untouched. I can't estimate how often people are using multiple ports.
My best idea at the moment is:
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " state=absent
lineinfile: dest=/etc/ssh/sshd_config line="Port 22" state=present
or for multiple ports
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " state=absent
lineinfile: dest=/etc/ssh/sshd_config line="{{ item }}" state=present
with_items:¬
- "Port 22"¬
- "Port 42"
Both of these solutions are not idempotence.
Under the assumption that only one port is set in sshd_config
(for a new server) and we don't want multiple ports the simplest solution would be:
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " line="Port 22" state=present
This should allow setting more ports via a separate task with insertbefore="^Port 22"
?
Another options would be to remove the possibility to set the SSH port as it is not completely in the scope of a secure OpenSSH server. In this case its hard to open SSH port(s) via ufw.
I think this fits perfectly in the scope of a secure OpenSSH server. It helps avoiding bots trying to bruteforce your ssh endpoint, mislead quick scans based on default ports list, etc.
Case 1: users have only one port open
This is heavily opinionated, but can be implemented waiting to see of multiple ports is a requested feature. I agree with your quickest and simplest solution:
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " line="Port 22" state=present
But need to think about updating the ufw rules though, as it needs to not respond on the old port and accept connections on the new one.
Case 2: allow to configure multiple ports
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " state=absent
lineinfile: dest=/etc/ssh/sshd_config line="{{ item }}" state=present
with_items: "{{ ssh_ports }}" # ssh_ports being defined in the user's task calling the role
I do not understand how this is breaking idempotence: as is, users defined a list of ports, and the role is responsible of implementing them the right way.
However, this solution needs as well to update ufw rules.
I do not understand how this is breaking idempotence: as is, users defined a list of ports, and the role is responsible of implementing them the right way.
Lets assume ports are already set correctly. In the first step you delete all occurrences of "^Port\ ", this is a change. After that these ports are added again to the sshd config which is also a change.
I will fix this issue with
lineinfile: dest=/etc/ssh/sshd_config regexp="^Port\ " line="Port 22" state=present
the problem with ufws remains. But I think this is a common problem of ansible and other configuration management tools in contrast to e.g. NixOS.