Hi Spike,
I’m not an Augeas developer, but I want to contribute my opinion to the discussion anyway. J > But how do I know to issue this 'ins' command or not? This usually is handled by the defnode command, which will define a variable pointing to a tree node, creating it if necessary[1]. But, then you are back to the original problem, where Augeas will create new nodes at the end of the tree by default. Only the insert command is able to put new nodes elsewhere. And, because the Augeas language does not support conditionals, I’m afraid you cannot solve this problem within Augeas only. In case you try to address this problem with Puppet, you can make use of the onlyif parameter for the augeas resource type[2]. Maybe something like [3] will succeed for you? Note that I chose to delete a potentially existing PermitRootLogin node, in case there are any Match blocks. That’s because you cannot check on two conditions at the same time with the onlyif parameter, so we cannot define three augeas resources in order to cover each possible situation. An alternative solution that checks for PermitRootLogin might define a Match node with “dummy” as default content, which is used only for inserting missing PermitRootLogin nodes and will be deleted afterwards again[4]. The former solution is still more useful to you, in case you want to set more than just a single parameter for sshd. Hopefully I was able to help you in some way. Best regards, Xavier. 1) This should select your PermitRootLogin node, if it exists, otherwise it will be created at the end of the file (“no” is only set when the node is created) defnode prl $sshd/PermitRootLogin “no” 2) https://puppet.com/docs/puppet/5.5/types/augeas.html#augeas-attribute-onlyif 3) ```puppet augeas { default: incl => '/etc/ssh/sshd_config', lens => 'Sshd.lns', ; 'Set PermitRootLogin w/o Match blocks': onlyif => 'match Match size == 0', changes => [ 'defnode prl PermitRootLogin ""', 'set $prl "no"', ], ; 'Set PermitRootLogin w/ Match blocks': onlyif => 'match Match size > 0', changes => [ 'rm PermitRootLogin', 'defnode fstMatch Match[1] ""', 'ins PermitRootLogin before $fstMatch', 'set PermitRootLogin "no"', ], } ``` 4) augeas { default: incl => '/etc/ssh/sshd_config', lens => 'Sshd.lns', ; 'Set PermitRootLogin': onlyif => 'match PermitRootLogin size > 0', changes => [ 'defnode prl PermitRootLogin ""', 'set $prl "no"', ], ; 'Add PermitRootLogin': onlyif => 'match PermitRootLogin size == 0', changes => [ 'defnode fstMatch Match[1] "dummy"', 'ins PermitRootLogin before $fstMatch', 'set PermitRootLogin "no"', 'rm Match[. = "dummy"]', ], } From: [email protected] <[email protected]> On Behalf Of Spike White Sent: Friday, September 11, 2020 11:57 PM To: [email protected] Subject: [augeas-devel] augeas against sshd_config failing with Match blocks... Augeas aficionados, I've been using augeas for years. Both with puppet and stand-alone. Also, I’ve been using Augeas to manipulate /etc/ssh/sshd_config file for years. Now with the advent of Match blocks in the sshd_config files, I'm having challenges. David Lutterkort calls out this exact problem in the sshd.aug lens file: About: CAVEATS In sshd_config, Match blocks must be located at the end of the file. This means that any new "global" parameters (i.e. outside of a Match block) must be written before the first Match block. By default, Augeas will write new parameters at the end of the file. I.e. if you have a Match section and no ChrootDirectory parameter, this command: > set /files/etc/ssh/sshd_config/ChrootDirectory "foo" will be stored in a new node after the Match section and Augeas will refuse to save sshd_config file. To create a new parameter as the right place, you must first create a new Augeas node before the Match section: > ins ChrootDirectory before /files/etc/ssh/sshd_config/Match Then, you can set the parameter > set /files/etc/ssh/sshd_config/ChrootDirectory "foo" So I understand what this lens author is saying. Here's my augeas code, doing basic SSH hardening (per CIS recommendations): defnode sshd /files/etc/ssh/sshd_config set $sshd/PermitRootLogin no set $sshd/UsePrivilegeSeparation sandbox set $sshd/Ciphers/1 aes128-ctr … save This code works great -- if no Match blocks in the sshd_config file. A particular server needs these Match blocks: Match User ServicePPTDEVVRA MaxSessions 250 Match User ServicePPTDEVDCA MaxSessions 250 Let's take 'PermitRootLogin' line as an example. If I know there's no PermitRootLogin line, I should be able to do this: defnode sshd /files/etc/ssh/sshd_config ins $sshd/PermitRootLogin before $sshd/Match set $sshd/PermitRootLogin no save or possibly this: defnode sshd /files/etc/ssh/sshd_config ins $sshd/PermitRootLogin before $sshd/Match[1] set $sshd/PermitRootLogin no save But how do I know to issue this 'ins' command or not? (How do I know if there's a pre-existing PermitRootLogin line or not?). If I issue a 'ins' command and there's an existing PermitRootLogin file, it will error out I believe. Need your assistance to re-code my augeas code, to handle the case where Match blocks exist.
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ augeas-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/augeas-devel
