Yesterday we got the key creation working, today we'll lock the server down properly by preventing root login and adding a user to the sudoers file. Let's start with the latter.


First we need a group of administrators, for the sake of ease and self-documentation I called it sudo. Well ubuntu called it sudo, but we still need to ensure it exists, because it won't on all operating systems.
import "*" class sudo { include sudo::install, sudo::sudoers group{"sudo": ensure => "present"} }
All we did here was very simply ensure that the puppet group existed. Next we need to update our sudoers file to allow members of the sudo group to sudo.
# /etc/sudoers # # This file MUST be edited with the 'visudo' command as root. # # See the man page for details on how to write a sudoers file. # Defaults env_reset # Uncomment to allow members of group sudo to not need a password # %sudo ALL=NOPASSWD: ALL # Host alias specification # User alias specification # Cmnd alias specification # User privilege specification root ALL=(ALL) ALL %sudo ALL=(ALL) ALL
All we did here was add the last line which allows members of the sudo group to do everything. We do require a user's password. The next and final step is to ensure our user module allows us to specify additional groups.
import "*" class user { define create ($groups = "") { group{$title: ensure => "present"} user { "$title": ensure => "present", gid => "$title", groups => $groups, home => "/home/$title", shell => "/bin/bash", managehome => true, require => [Group["$title"]], } file { "/home/$title": ensure => "directory", mode => 700, owner => "$title", group => "$title", } file { "/home/$title/.ssh": ensure => "directory", mode => 600, owner => "$title", group => "$title", } ssh::auth::key{"$title":} } define client_key ($ensure = "", $filename = "") { ssh::auth::client{"$title": ensure=>$ensure, filename=>$filename} } define server_key ($ensure = "", $user = "") { ssh::auth::server{"$title": ensure=>$ensure, user=>$user} } }
On line 4 I added a parameter $groups which defaults to empty and on line 9 I pass that parameter into the user creation step. There you have it, run puppet and your user will get added to the sudo group and should be able to sudo themselves up a sandwich.


The next step in securing our server is to prevent logins with passwords and prevent root logins. I can't stress enough how important it is here that you test you can login with your key and that you can sudo or at least you know your root password. If you go ahead without being able to do these things you may be left unable to login to your machine. Our sshd module is a lot like the original sudoers module. We're simply copying a file into /etc. Start by creating our module directories
# mkdir -p modules/sshd/files modules/sshd/manifests
Next we create the init.pp file for the ssh module. I've taken inspiration from the example on the puppet wiki
class sshd { package {"openssh-server": ensure=> "installed"} file { "/etc/ssh/sshd_config": owner => "root", mode => 644, notify => Service["ssh"], require => Package["openssh-server"], source => "puppet:///modules/sshd/sshd_config" } service { "ssh": enable => true, ensure => running, require => [ File["/etc/ssh/sshd_config"], Package["openssh-server"] ] } }
Next copy your current sshd_config into the files directory of your module
# cp /etc/ssh/sshd_config modules/sshd/files
Then I edited the following lines to deny root logins and password authentication:
PermitRootLogin no ... PasswordAuthentication no
Finally I updated my node.pp to include the new module
node build { include sudo, user, sshd, ssh::auth, user::keystore user::create{"andrewmccall": groups => "sudo"} user::client_key{"andrewmccall":} user::server_key{"andrewmccall":} }
Execute puppet and your sshd_config should now be properly set.