Copy updated and documented authorized_key_add from Tor
authorPeter Palfrader <peter@palfrader.org>
Sat, 14 Sep 2019 11:01:41 +0000 (13:01 +0200)
committerPeter Palfrader <peter@palfrader.org>
Sat, 14 Sep 2019 11:01:41 +0000 (13:01 +0200)
The interface changed slightly:
 - from_hosts is from
 - restrict is now an options array that defaults to ['restrict']

callers will be updated with the next commit.

modules/ssh/manifests/authorized_key_add.pp

index f1fccf8..aae3ed9 100644 (file)
@@ -1,15 +1,59 @@
-# store ssh authorized_keys snippets that roles on different hosts can then
-# collect using ssh::authorized_key_collect
-
+# export sshd's authorized_keys fragments
+#
+# This creates exported sshd `authorized_keys` snippets that different
+# hosts can then collect using `ssh::authorized_key_collect`.
+#
+# This is a replacement for the builtin ssh_authorized_keys, although
+# it requires exported resources to work.
+#
+# The builtin type had too many problems to overcome to be useful in
+# our environment. A short overview of known issues, some of which are
+# security-sensitive:
+#
+# * MODULES-7595: ssh_authorized_key should be able to take a ready-made OpenSSH public key
+# * MODULES-7596: puppet ssh_authorized_key not purged as expected
+# * MODULES-9726: allow read-only authorized_keys
+# * MODULES-7610: sshkey uses name instead of title for duplication check
+#
+# There are many more issues on the sshkeys module, which doesn't seem
+# to be very well maintained anyways:
+#
+# https://tickets.puppetlabs.com/browse/MODULES-9726?jql=project%20%3D%20MODULES%20AND%20component%20%3D%20sshkeys_core
+#
+# @param target_user the filename to save the key under
+#
+# @param collect_tag which tag to export this resource as
+#
+# @param options a list of options, defaults to ["restrict"]
+#
+# @param command the command to enforce for this keyfile
+#
+# @param from a list of IPv4 or IPv6 address to pass to the
+#                   key's `from=` parameter.
+#
+# @param key the actual public key, including ssh-*, the public key
+#            material and the comment
 define ssh::authorized_key_add(
   String $target_user,
-  String $command,
   Variant[Array[String], String] $collect_tag,
-  String $restrict = 'restrict',
-  Optional[String] $key,
-  Array[Stdlib::IP::Address] $from_hosts = $base::public_addresses,
+  Array[String] $options = ['restrict'],
+  Optional[String] $command = '',
+  Optional[Array[Stdlib::IP::Address]] $from = $base::public_addresses,
+  Optional[String] $key = undef,
 ) {
-  $from = $from_hosts.join(',')
+  $ssh_from_string = $from.join(',')
+  if $command {
+    $options_command = ["command=\"${command}\""]
+  } else {
+    $options_command = []
+  }
+  if $ssh_from_string {
+    $options_from = ["from=\"${ssh_from_string}\""]
+  } else {
+    $options_from = []
+  }
+  $real_options = $options_command + $options_from + $options
+  $options_string = $real_options.join(',')
 
   if ($key and size(split($key, "\n")) > 1) {
     fail('More than one line in key for ssh::authorized_key')
@@ -17,8 +61,8 @@ define ssh::authorized_key_add(
   if (size(split($command, '"')) > 1) {
     fail('command must not contain double quotes')
   }
-  if (size(split($from, '"')) > 1) {
-    fail('from_hosts must not contain double quotes')
+  if (size(split($ssh_from_string, '"')) > 1) {
+    fail('from must not contain double quotes')
   }
 
   if $collect_tag =~ String {
@@ -29,16 +73,15 @@ define ssh::authorized_key_add(
   $ssh_tags = $raw_tags.map |$t| { "ssh::authorized_key::fragment::${t}::${target_user}" }
   $ferm_tags = $raw_tags.map |$t| { "ssh::authorized_key::ferm::${t}::${target_user}" }
 
-  $from_space = $from_hosts.join(' ')
+  $ferm_from_string = $from.join(' ')
 
   if $key {
     @@concat::fragment { "ssh::authorized_key::${name} ${target_user} from ${::hostname}":
       tag     => $ssh_tags,
       target  => "/etc/ssh/puppetkeys/${target_user}",
-      order   => '200',
       content => @("EOF"),
                  # from ${::fqdn}
-                 command="${command}",from="${from}",${restrict} ${key}
+                 ${options_string} ${key}
                  | EOF
     }
   } else {
@@ -52,6 +95,6 @@ define ssh::authorized_key_add(
     description => "allow ssh for ssh to ${target_user}",
     domain      => '(ip ip6)',
     chain       => 'ssh',
-    rule        => "saddr (${from_space}) ACCEPT",
+    rule        => "saddr (${ferm_from_string}) ACCEPT",
   }
 }