Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sshd fails to create new entry if a match block already exists at the end #799

Open
davidc opened this issue Jan 9, 2023 · 3 comments
Open

Comments

@davidc
Copy link

davidc commented Jan 9, 2023

sshd lens won't create a PermitRootLogin entry if one doesn't exist and the file ends with a Match block.

Normal use is fine:

# echo > sshd_config
# augtool -At 'Sshd.lns incl /tmp/sshd_config' set /files/tmp/sshd_config/PermitRootLogin no
Saved 1 file(s)
# cat sshd_config

PermitRootLogin no

If a match block already exists it fails:

# cat > sshd_config
Match Group *,!adm
  ChrootDirectory %h
# augtool -At 'Sshd.lns incl /tmp/sshd_config' set /files/tmp/sshd_config/PermitRootLogin no
error: Failed to execute command
saving failed (run 'errors' for details)

But if PermitRootLogin already exists (so it only needs to update it), it works fine:

# cat > sshd_config
PermitRootLogin yes
Match Group *,!adm
  ChrootDirectory %h
# augtool -At 'Sshd.lns incl /tmp/sshd_config' set /files/tmp/sshd_config/PermitRootLogin no
Saved 1 file(s)
# cat sshd_config
PermitRootLogin no
Match Group *,!adm
  ChrootDirectory %h

This is causing my puppet to be non-deterministic since it fails if setting PermitRootLogin to no occurs after the Match has been inserted.

According to man sshd_config:

 Match   Introduces a conditional block.  If all of the criteria on the Match line are satis‐
         fied, the keywords on the following lines override those set in the global section
         of the config file, **until either another Match line or the end of the file**.  If a
         keyword appears in multiple Match blocks that are satisfied, only the first instance
         of the keyword is applied.

So I guess it needs to insert new entries before any Match blocks.

@davidc
Copy link
Author

davidc commented Jan 9, 2023

# augtool --version
augtool 1.12.0 <http://augeas.net/>

@AlphaZiege
Copy link

Same Problem.
The set command can only change values and cant insert any.
The ins command wont work until there are no Match Blocks in the config file

@georgehansper
Copy link
Member

The set command will create a new node, if it does not already exist.
The new node is always appended to existing nodes at the same level.

In this case:

> augtool -At 'Sshd.lns incl /etc/ssh/sshd_config.issue799'  
augtool> set /files/etc/ssh/sshd_config.issue799/PermitRootLogin no 
augtool> print /files
/files
/files/etc
/files/etc/ssh
/files/etc/ssh/sshd_config.issue799
/files/etc/ssh/sshd_config.issue799/Match
/files/etc/ssh/sshd_config.issue799/Match/Condition
/files/etc/ssh/sshd_config.issue799/Match/Condition/Group = "*,!adm"
/files/etc/ssh/sshd_config.issue799/Match/Settings
/files/etc/ssh/sshd_config.issue799/Match/Settings/ChrootDirectory = "%h"
/files/etc/ssh/sshd_config.issue799/PermitRootLogin = "no"
augtool> save
error: Failed to execute command
saving failed (run 'errors' for details)
augtool> 

We can get a better idea of what is acceptable by creating this file:

PermitRootLogin yes
Match Group *,!adm
  ChrootDirectory %h
  PermitRootLogin no

Which is valid according to man sshd_config

And then looking at the result:

> augtool -At 'Sshd.lns incl /etc/ssh/sshd_config.issue799'  print /files
/files
/files/etc
/files/etc/ssh
/files/etc/ssh/sshd_config.issue799
/files/etc/ssh/sshd_config.issue799/PermitRootLogin = "yes"
/files/etc/ssh/sshd_config.issue799/Match
/files/etc/ssh/sshd_config.issue799/Match/Condition
/files/etc/ssh/sshd_config.issue799/Match/Condition/Group = "*,!adm"
/files/etc/ssh/sshd_config.issue799/Match/Settings
/files/etc/ssh/sshd_config.issue799/Match/Settings/ChrootDirectory = "%h"
/files/etc/ssh/sshd_config.issue799/Match/Settings/PermitRootLogin = "no"

The solution is to ensure that PermitRootLogin is inserted before Match

There is no existing single command which will tell augeas to "update this node, but if you need to create it, put it (here)"
Admittedly, such a feature would be quite useful in real-world situations like this one

The simplest work-around I can suggest consists of 3 commands:

insert PermitRootLogin before /files/etc/ssh/sshd_config.issue799/Match
set /files/etc/ssh/sshd_config.issue799/PermitRootLogin[1] no 
rm /files/etc/ssh/sshd_config.issue799/PermitRootLogin[2]

To demonstrate:

> augtool -At 'Sshd.lns incl /etc/ssh/sshd_config.issue799'
augtool> print /files
/files
/files/etc
/files/etc/ssh
/files/etc/ssh/sshd_config.issue799
/files/etc/ssh/sshd_config.issue799/Match
/files/etc/ssh/sshd_config.issue799/Match/Condition
/files/etc/ssh/sshd_config.issue799/Match/Condition/Group = "*,!adm"
/files/etc/ssh/sshd_config.issue799/Match/Settings
/files/etc/ssh/sshd_config.issue799/Match/Settings/ChrootDirectory = "%h"
augtool> insert PermitRootLogin before /files/etc/ssh/sshd_config.issue799/Match
augtool> set /files/etc/ssh/sshd_config.issue799/PermitRootLogin[1] no 
augtool> rm /files/etc/ssh/sshd_config.issue799/PermitRootLogin[2]
rm : /files/etc/ssh/sshd_config.issue799/PermitRootLogin[2] 0
augtool> print /files
/files
/files/etc
/files/etc/ssh
/files/etc/ssh/sshd_config.issue799
/files/etc/ssh/sshd_config.issue799/PermitRootLogin = "no"
/files/etc/ssh/sshd_config.issue799/Match
/files/etc/ssh/sshd_config.issue799/Match/Condition
/files/etc/ssh/sshd_config.issue799/Match/Condition/Group = "*,!adm"
/files/etc/ssh/sshd_config.issue799/Match/Settings
/files/etc/ssh/sshd_config.issue799/Match/Settings/ChrootDirectory = "%h"
augtool> save
Saved 1 file(s)
augtool>

If the line PermitRootLogin already exists, a superfluous 2nd node is created, and then removed.
It is not a error to rm a node that does not already exist, so if insert has created the first PermitRootLogin line, the subsequent rm ... [2] will not remove anything, hence the response that 0 nodes were deleted (above)

Alternately, if your default /etc/ssh/sshd_config has the line:

Include /etc/ssh/sshd_config.d/*.conf

You could put all the Match blocks in to a separate file so Augeas does not need to deal with the combination of global settings and Match blocks in the same file. If you opt for such a solution, Augeas may no longer be the best tool for the job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants