aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README230
-rw-r--r--lib/puppet/parser/functions/ssh_keygen.rb23
-rw-r--r--manifests/client.pp2
-rw-r--r--manifests/client/base.pp3
-rw-r--r--manifests/debian.pp3
-rw-r--r--manifests/init.pp192
-rw-r--r--manifests/nagios.pp24
-rw-r--r--spec/spec.opts6
-rw-r--r--spec/spec_helper.rb16
-rw-r--r--spec/unit/parser/functions/ssh_keygen.rb104
-rw-r--r--templates/sshd_config/CentOS.erb13
-rw-r--r--templates/sshd_config/Debian_etch.erb17
-rw-r--r--templates/sshd_config/Debian_lenny.erb18
-rw-r--r--templates/sshd_config/Debian_sid.erb207
-rw-r--r--templates/sshd_config/Debian_squeeze.erb17
l---------templates/sshd_config/Debian_wheezy.erb1
-rw-r--r--templates/sshd_config/Gentoo.erb12
-rw-r--r--templates/sshd_config/OpenBSD.erb13
l---------templates/sshd_config/Ubuntu.erb1
19 files changed, 689 insertions, 213 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..9cf253f
--- /dev/null
+++ b/README
@@ -0,0 +1,230 @@
+Introduction
+============
+
+This puppet module manages OpenSSH configuration and services.
+
+Dependencies
+------------
+
+This module requires puppet => 2.6, and the following modules are required
+pre-dependencies:
+
+- shared-common: git://labs.riseup.net/shared-common
+- shared-lsb: git://labs.riseup.net/shared-lsb
+
+OpenSSH Server
+==============
+
+On a node where you wish to have an openssh server installed, you should
+'include sshd' on that node. If you need to configure any aspects of
+sshd_config, set the variables before the include. See 'Configurable Variables'
+below for what you can set.
+
+Nagios
+------
+
+To have nagios checks setup automatically for sshd services, simply set
+$use_nagios = true before the class is included. If you want to disable ssh
+nagios checking for a particular node (such as when ssh is firewalled), then you
+can set $nagios_check_ssh to false and that node will not be monitored.
+
+Nagios will automatically check the ports defined in $sshd_ports, and the
+hostname specified by $nagios_check_ssh_hostname.
+
+NOTE: this requires that you are using the shared-nagios puppet module which
+supports the nagios native types via nagios::service:
+git://labs.riseup.net/shared-nagios
+
+Firewall
+--------
+
+If you wish to have firewall rules setup automatically for you, using shorewall,
+you will need to set: $use_shorewall = true. The $sshd_ports that you have
+specified will automatically be used.
+
+NOTE: This requires that you are using the shared-shorewall puppet module:
+git://labs.riseup.net/shared-shorewall
+
+
+Configurable variables
+----------------------
+
+Configuration of sshd is strict, and may not fit all needs, however there are a
+number of variables that you can consider configuring. The defaults are set to
+the distribution shipped sshd_config file defaults.
+
+To set any of these variables, simply set them as variables in your manifests,
+before the class is included, for example:
+
+ $sshd_listen_address = ['10.0.0.1 192.168.0.1']
+ $sshd_use_pam = yes
+ include sshd
+
+If you need to install a version of the ssh daemon or client package other than
+the default one that would be installed by 'ensure => installed', then you can
+set the following variables:
+
+ $sshd_ensure_version = "1:5.2p2-6"
+ $ssh_ensure_version = "1:5.2p2-6"
+
+The following is a list of the currently available variables:
+
+ $sshd_listen_address
+ specify the addresses sshd should listen on set this to ['10.0.0.1
+ 192.168.0.1'] to have it listen on both addresses, or leave it unset to
+ listen on all Default: empty -> results in listening on 0.0.0.0
+
+ $sshd_allowed_users
+ list of usernames separated by spaces. set this for example to "foobar
+ root" to ensure that only user foobar and root might login. Default: empty
+ -> no restriction is set
+
+ $sshd_allowed_groups
+ list of groups separated by spaces. set this for example to "wheel sftponly"
+ to ensure that only users in the groups wheel and sftponly might login.
+ Default: empty -> no restriction is set Note: This is set after
+ sshd_allowed_users, take care of the behaviour if you use these 2 options
+ together.
+
+ $sshd_use_pam
+ if you want to use pam or not for authenticaton. Values: no or yes; Default:
+ no
+
+ $sshd_permit_root_login
+ If you want to allow root logins or not. Valid values: yes, no,
+ without-password, forced-commands-only; Default: without-password
+
+ $sshd_password_authentication
+ If you want to enable password authentication or not. Valid values: yes or
+ no; Default: no
+
+ $sshd_kerberos_authentication
+ If you want the password that is provided by the user to be validated
+ through the Kerberos KDC. To use this option the server needs a Kerberos
+ servtab which allows the verification of the KDC's identity. Valid values:
+ yes or no; Default: no
+
+ $sshd_kerberos_orlocalpasswd
+ If password authentication through Kerberos fails, then the password will be
+ validated via any additional local mechanism. Valid values: yes or no;
+ Default: yes
+
+ $sshd_kerberos_ticketcleanup
+ Destroy the user's ticket cache file on logout? Valid values: yes or no;
+ Default: yes
+
+ $sshd_gssapi_authentication
+ Authenticate users based on GSSAPI? Valid values: yes or no; Default: no
+
+ $sshd_gssapi_cleanupcredentials
+ Destroy user's credential cache on logout? Valid values: yes or no; Default:
+ yes
+
+ $sshd_challenge_response_authentication
+ If you want to enable ChallengeResponseAuthentication or not When disabled,
+ s/key passowords are disabled Valid values: yes or no; Default: no
+
+ $sshd_tcp_forwarding
+ If you want to enable TcpForwarding. Valid Values: yes or no; Default: no
+
+ $sshd_x11_forwarding
+ If you want to enable x11 forwarding. Valid Values: yes or no; Default: no
+
+ $sshd_agent_forwarding
+ If you want to allow ssh-agent forwarding. Valid Values: yes or no; Default:
+ no
+
+ $sshd_pubkey_authentication
+ If you want to enable public key authentication. Valid Values: yes or no;
+ Default: yes
+
+ $sshd_rsa_authentication
+ If you want to enable RSA Authentication. Valid Values: yes or no; Default:
+ no
+
+ $sshd_rhosts_rsa_authentication
+ If you want to enable rhosts RSA Authentication. Valid Values: yes or no;
+ Default: no
+
+ $sshd_hostbased_authentication
+ If you want to enable HostbasedAuthentication. Valid Values: yes or no;
+ Default: no
+
+ $sshd_strict_modes
+ If you want to set StrictModes (check file modes/ownership before accepting
+ login). Valid Values: yes or no; Default: yes
+
+ $sshd_permit_empty_passwords
+ If you want enable PermitEmptyPasswords to allow empty passwords. Valid
+ Values: yes or no; Default: no
+
+ $sshd_port
+ Deprecated, use sshd_ports instead.
+
+ $sshd_ports
+ If you want to specify a list of ports other than the default 22; Default:
+ [22]
+
+ $sshd_authorized_keys_file
+ Set this to the location of the AuthorizedKeysFile
+ (e.g. /etc/ssh/authorized_keys/%u). Default: AuthorizedKeysFile
+ %h/.ssh/authorized_keys
+
+ $sshd_hardened_ssl
+ Use only strong SSL ciphers and MAC.
+ Values: no or yes; Default: no.
+
+ $sshd_sftp_subsystem
+ Set a different sftp-subystem than the default one. Might be interesting for
+ sftponly usage. Default: empty -> no change of the default
+
+ $sshd_head_additional_options
+ Set this to any additional sshd_options which aren't listed above. Anything
+ set here will be added to the beginning of the sshd_config file. This option
+ might be useful to define complicated Match Blocks. This string is going to
+ be included, like it is defined. So take care! Default: empty -> not added.
+
+ $sshd_tail_additional_options
+
+ Set this to any additional sshd_options which aren't listed above. Anything
+ set here will be added to the end of the sshd_config file. This option might
+ be useful to define complicated Match Blocks. This string is going to be
+ included, like it is defined. So take care! Default: empty -> not added.
+
+
+Defines and functions
+---------------------
+
+Deploy authorized_keys file with the define sshd::ssh_authorized_key.
+
+Generate a public/private keypair with the ssh_keygen function. For example, the
+following will generate ssh keys and put the different parts of the key into
+variables:
+
+$ssh_keys = ssh_keygen("${$ssh_key_basepath}/backup/keys/${fqdn}/${backup_host}")
+$public_key = split($ssh_keys[1],' ')
+$sshkey_type => $public_key[0]
+$sshkey => $public_key[1]
+
+
+Client
+======
+
+On a node where you wish to have the ssh client managed, you can do 'include
+sshd::client' in the node definition. This will install the appropriate package.
+
+
+License
+=======
+
+# Copyright 2008-2011, Riseup Labs micah@riseup.net
+# Copyright 2008, admin(at)immerda.ch
+# Copyright 2008, Puzzle ITC GmbH
+# Marcel Härry haerry+puppet(at)puzzle.ch
+# Simon Josi josi+puppet(at)puzzle.ch
+#
+# This program is free software; you can redistribute
+# it and/or modify it under the terms of the GNU
+# General Public License version 3 as published by
+# the Free Software Foundation.
+#
diff --git a/lib/puppet/parser/functions/ssh_keygen.rb b/lib/puppet/parser/functions/ssh_keygen.rb
new file mode 100644
index 0000000..09b3d3b
--- /dev/null
+++ b/lib/puppet/parser/functions/ssh_keygen.rb
@@ -0,0 +1,23 @@
+Puppet::Parser::Functions::newfunction(:ssh_keygen, :type => :rvalue, :doc =>
+ "Returns an array containing the ssh private and public (in this order) key
+ for a certain private key path.
+ It will generate the keypair if both do not exist. It will also generate
+ the directory hierarchy if required.
+ It accepts only fully qualified paths, everything else will fail.") do |args|
+ raise Puppet::ParseError, "Wrong number of arguments" unless args.to_a.length == 1
+ private_key_path = args.to_a[0]
+ raise Puppet::ParseError, "Only fully qualified paths are accepted (#{private_key_path})" unless private_key_path =~ /^\/.+/
+ public_key_path = "#{private_key_path}.pub"
+ raise Puppet::ParseError, "Either only the private or only the public key exists" if File.exists?(private_key_path) ^ File.exists?(public_key_path)
+ [private_key_path,public_key_path].each do |path|
+ raise Puppet::ParseError, "#{path} is a directory" if File.directory?(path)
+ end
+
+ dir = File.dirname(private_key_path)
+ Puppet::Util.recmkdir(dir,0700) unless File.directory?(dir)
+ unless [private_key_path,public_key_path].all?{|path| File.exists?(path) }
+ output = Puppet::Util.execute(['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', '-f', private_key_path, '-P', '', '-q'])
+ raise Puppet::ParseError, "Something went wrong during key generation! Output: #{output}" unless output.empty?
+ end
+ [File.read(private_key_path),File.read(public_key_path)]
+end
diff --git a/manifests/client.pp b/manifests/client.pp
index b650244..31785e9 100644
--- a/manifests/client.pp
+++ b/manifests/client.pp
@@ -2,7 +2,7 @@
class sshd::client {
case $operatingsystem {
- debian: { include sshd::client::debian }
+ debian,ubuntu: { include sshd::client::debian }
default: {
case $kernel {
linux: { include sshd::client::linux }
diff --git a/manifests/client/base.pp b/manifests/client/base.pp
index 33d9f9e..64d4f6f 100644
--- a/manifests/client/base.pp
+++ b/manifests/client/base.pp
@@ -1,7 +1,6 @@
class sshd::client::base {
# this is needed because the gid might have changed
- file { '/etc/ssh/ssh_known_hosts':
- owner => root, group => 0, mode => 0644;
+ config_file { '/etc/ssh/ssh_known_hosts':
}
# Now collect all server keys
diff --git a/manifests/debian.pp b/manifests/debian.pp
index 0cc4ede..43dc26c 100644
--- a/manifests/debian.pp
+++ b/manifests/debian.pp
@@ -9,8 +9,7 @@ class sshd::debian inherits sshd::linux {
$sshd_restartandstatus = $lsbdistcodename ? {
etch => false,
- lenny => true,
- default => false
+ default => true
}
Service[sshd]{
diff --git a/manifests/init.pp b/manifests/init.pp
index f37a051..e933a46 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,169 +1,3 @@
-#
-# ssh module
-#
-# Copyright 2008-2009, micah@riseup.net
-# Copyright 2008, admin(at)immerda.ch
-# Copyright 2008, Puzzle ITC GmbH
-# Marcel Härry haerry+puppet(at)puzzle.ch
-# Simon Josi josi+puppet(at)puzzle.ch
-#
-# This program is free software; you can redistribute
-# it and/or modify it under the terms of the GNU
-# General Public License version 3 as published by
-# the Free Software Foundation.
-#
-# Deploy authorized_keys file with the define
-# sshd::ssh_authorized_key
-#
-# sshd-config:
-#
-# The configuration of the sshd is rather strict and might not fit all
-# needs. However there are a bunch of variables, which you might
-# consider configuring.
-#
-# To set any of the following, simply set them as variables in your manifests
-# before the class is included, for example:
-#
-# $sshd_listen_address = ['10.0.0.1 192.168.0.1']
-# $sshd_use_pam = yes
-# include sshd
-#
-# If you need to install a version of the ssh daemon or client package other than
-# the default one that would be installed by 'ensure => installed', then you can
-# set the following variables:
-#
-# $sshd_ensure_version = "1:5.2p2-6"
-# $ssh_ensure_version = "1:5.2p2-6"
-#
-# To have nagios checks setup automatically for sshd services, simply
-# set $use_nagios = true before the class is included. If you want to
-# disable ssh nagios checking for a particular node (such as when ssh
-# is firewalled), then you can set $nagios_check_ssh to false and that
-# node will not be monitored.
-# NOTE: this requires that you are using the nagios puppet module
-# which supports the nagios native types via nagios::service
-#
-# The following is a list of the currently available variables:
-#
-# sshd_listen_address: specify the addresses sshd should listen on
-# set this to ['10.0.0.1 192.168.0.1'] to have it listen on both
-# addresses, or leave it unset to listen on all
-# Default: empty -> results in listening on 0.0.0.0
-#
-# sshd_allowed_users: list of usernames separated by spaces.
-# set this for example to "foobar root"
-# to ensure that only user foobar and root
-# might login.
-# Default: empty -> no restriction is set
-#
-# sshd_allowed_groups list of groups separated by spaces.
-# set this for example to "wheel sftponly"
-# to ensure that only users in the groups
-# wheel and sftponly might login.
-# Default: empty -> no restriction is set
-# Note: This is set after sshd_allowed_users,
-# take care of the behaviour if you use
-# these 2 options together.
-#
-# sshd_use_pam: if you want to use pam or not for authenticaton
-# Values: no or yes.
-# Default: no
-#
-# sshd_permit_root_login: If you want to allow root logins or not.
-# Valid values: yes, no, without-password, forced-commands-only
-# Default: without-password
-#
-# sshd_password_authentication: If you want to enable password authentication or not
-# Valid values: yes or no
-# Default: no
-#
-# sshd_kerberos_authentication: If you want the password that is provided by the user to be
-# validated through the Kerberos KDC. To use this option the
-# server needs a Kerberos servtab which allows the verification of
-# the KDC's identity.
-# Valid values: yes or no
-# Default: no
-#
-# sshd_kerberos_orlocalpasswd: If password authentication through Kerberos fails, then the password
-# will be validated via any additional local mechanism.
-# Valid values: yes or no
-# Default: yes
-#
-# sshd_kerberos_ticketcleanup: Destroy the user's ticket cache file on logout?
-# Valid values: yes or no
-# Default: yes
-#
-# sshd_gssapi_authentication: Authenticate users based on GSSAPI?
-# Valid values: yes or no
-# Default: no
-#
-# sshd_gssapi_cleanupcredentials: Destroy user's credential cache on logout?
-# Valid values: yes or no
-# Default: yes
-#
-# sshd_challenge_response_authentication: If you want to enable ChallengeResponseAuthentication or not
-# When disabled, s/key passowords are disabled
-# Valid values: yes or no
-# Default: no
-#
-# sshd_tcp_forwarding: If you want to enable TcpForwarding
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_x11_forwarding: If you want to enable x11 forwarding
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_agent_forwarding: If you want to allow ssh-agent forwarding
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_pubkey_authentication: If you want to enable public key authentication
-# Valid Values: yes or no
-# Default: yes
-#
-# sshd_rsa_authentication: If you want to enable RSA Authentication
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_rhosts_rsa_authentication: If you want to enable rhosts RSA Authentication
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_hostbased_authentication: If you want to enable HostbasedAuthentication
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_strict_modes: If you want to set StrictModes (check file modes/ownership before accepting login)
-# Valid Values: yes or no
-# Default: yes
-#
-# sshd_permit_empty_passwords: If you want enable PermitEmptyPasswords to allow empty passwords
-# Valid Values: yes or no
-# Default: no
-#
-# sshd_port: If you want to specify a different port than the default 22
-# Default: 22
-#
-# sshd_authorized_keys_file: Set this to the location of the AuthorizedKeysFile (e.g. /etc/ssh/authorized_keys/%u)
-# Default: AuthorizedKeysFile %h/.ssh/authorized_keys
-#
-# sshd_sftp_subsystem: Set a different sftp-subystem than the default one.
-# Might be interesting for sftponly usage
-# Default: empty -> no change of the default
-#
-# sshd_head_additional_options: Set this to any additional sshd_options which aren't listed above.
-# Anything set here will be added to the beginning of the sshd_config file.
-# This option might be useful to define complicated Match Blocks
-# This string is going to be included, like it is defined. So take care!
-# Default: empty -> not added.
-#
-# sshd_tail_additional_options: Set this to any additional sshd_options which aren't listed above.
-# Anything set here will be added to the end of the sshd_config file.
-# This option might be useful to define complicated Match Blocks
-# This string is going to be included, like it is defined. So take care!
-# Default: empty -> not added.
-
class sshd {
# prepare variables to use in templates
case $sshd_listen_address {
@@ -232,12 +66,20 @@ class sshd {
case $sshd_permit_empty_passwords {
'': { $sshd_permit_empty_passwords = 'no' }
}
- case $sshd_port {
- '': { $sshd_port = 22 }
+ if ( $sshd_port != '' ) and ( $sshd_ports != []) {
+ err("Cannot use sshd_port and sshd_ports at the same time.")
+ }
+ if $sshd_port != '' {
+ $sshd_ports = [ $sshd_port ]
+ } elsif ! $sshd_ports {
+ $sshd_ports = [ 22 ]
}
case $sshd_authorized_keys_file {
'': { $sshd_authorized_keys_file = "%h/.ssh/authorized_keys" }
}
+ case $sshd_hardened_ssl {
+ '': { $sshd_hardened_ssl = 'no' }
+ }
case $sshd_sftp_subsystem {
'': { $sshd_sftp_subsystem = '' }
}
@@ -265,11 +107,21 @@ class sshd {
if $use_nagios {
case $nagios_check_ssh {
false: { info("We don't do nagioschecks for ssh on ${fqdn}" ) }
- default: { nagios::service{ "ssh_port_${sshd_port}": check_command => "check_ssh_port!$sshd_port" } }
+ default: {
+ sshd::nagios{$sshd_ports:
+ check_hostname => $nagios_check_ssh_hostname ? {
+ '' => 'absent',
+ undef => 'absent',
+ default => $nagios_check_ssh_hostname
+ }
+ }
+ }
}
}
if $use_shorewall{
- include shorewall::rules::ssh
+ class{'shorewall::rules::ssh':
+ ports => $sshd_ports,
+ }
}
}
diff --git a/manifests/nagios.pp b/manifests/nagios.pp
new file mode 100644
index 0000000..7742cdb
--- /dev/null
+++ b/manifests/nagios.pp
@@ -0,0 +1,24 @@
+define sshd::nagios(
+ $port = 'absent',
+ $ensure = 'present',
+ $check_hostname = 'absent'
+) {
+ $real_port = $port ? {
+ 'absent' => $name,
+ default => $port,
+ }
+ case $check_hostname {
+ 'absent': {
+ nagios::service{"ssh_port_${name}":
+ ensure => $ensure,
+ check_command => "check_ssh_port!$real_port"
+ }
+ }
+ default: {
+ nagios::service{"ssh_port_host_${name}":
+ ensure => $ensure,
+ check_command => "check_ssh_port_host!${real_port}!${check_hostname}"
+ }
+ }
+ }
+}
diff --git a/spec/spec.opts b/spec/spec.opts
new file mode 100644
index 0000000..91cd642
--- /dev/null
+++ b/spec/spec.opts
@@ -0,0 +1,6 @@
+--format
+s
+--colour
+--loadby
+mtime
+--backtrace
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..6ba62e1
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,16 @@
+require 'pathname'
+dir = Pathname.new(__FILE__).parent
+$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib')
+require 'puppet'
+gem 'rspec', '>= 1.2.9'
+require 'spec/autorun'
+
+Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each do |support_file|
+ require support_file
+end
+
+# We need this because the RAL uses 'should' as a method. This
+# allows us the same behaviour but with a different method name.
+class Object
+ alias :must :should
+end
diff --git a/spec/unit/parser/functions/ssh_keygen.rb b/spec/unit/parser/functions/ssh_keygen.rb
new file mode 100644
index 0000000..f830065
--- /dev/null
+++ b/spec/unit/parser/functions/ssh_keygen.rb
@@ -0,0 +1,104 @@
+#! /usr/bin/env ruby
+
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'mocha'
+require 'fileutils'
+
+describe "the ssh_keygen function" do
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("ssh_keygen").should == "function_ssh_keygen"
+ end
+
+ it "should raise a ParseError if no argument is passed" do
+ lambda { @scope.function_ssh_keygen }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is more than 1 arguments" do
+ lambda { @scope.function_ssh_keygen("foo", "bar") }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if the argument is not fully qualified" do
+ lambda { @scope.function_ssh_keygen("foo") }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if the private key path is a directory" do
+ File.stubs(:directory?).with("/some_dir").returns(true)
+ lambda { @scope.function_ssh_keygen("/some_dir") }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if the public key path is a directory" do
+ File.stubs(:directory?).with("/some_dir.pub").returns(true)
+ lambda { @scope.function_ssh_keygen("/some_dir") }.should( raise_error(Puppet::ParseError))
+ end
+
+ describe "when executing properly" do
+ before do
+ File.stubs(:directory?).with('/tmp/a/b/c').returns(false)
+ File.stubs(:directory?).with('/tmp/a/b/c.pub').returns(false)
+ File.stubs(:read).with('/tmp/a/b/c').returns('privatekey')
+ File.stubs(:read).with('/tmp/a/b/c.pub').returns('publickey')
+ end
+
+ it "should fail if the public but not the private key exists" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(true)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false)
+ lambda { @scope.function_ssh_keygen("/tmp/a/b/c") }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should fail if the private but not the public key exists" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(false)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(true)
+ lambda { @scope.function_ssh_keygen("/tmp/a/b/c") }.should( raise_error(Puppet::ParseError))
+ end
+
+
+ it "should return an array of size 2 with the right conent if the keyfiles exists" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(true)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(true)
+ File.stubs(:directory?).with('/tmp/a/b').returns(true)
+ Puppet::Util.expects(:execute).never
+ result = @scope.function_ssh_keygen('/tmp/a/b/c')
+ result.length.should == 2
+ result[0].should == 'privatekey'
+ result[1].should == 'publickey'
+ end
+
+ it "should create the directory path if it does not exist" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(false)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false)
+ File.stubs(:directory?).with("/tmp/a/b").returns(false)
+ Puppet::Util.expects(:recmkdir).with("/tmp/a/b",0700)
+ Puppet::Util.expects(:execute).returns("")
+ result = @scope.function_ssh_keygen('/tmp/a/b/c')
+ result.length.should == 2
+ result[0].should == 'privatekey'
+ result[1].should == 'publickey'
+ end
+
+ it "should generate the key if the keyfiles do not exist" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(false)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false)
+ File.stubs(:directory?).with("/tmp/a/b").returns(true)
+ Puppet::Util.expects(:execute).with(['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', '-f', '/tmp/a/b/c', '-P', '', '-q']).returns("")
+ result = @scope.function_ssh_keygen('/tmp/a/b/c')
+ result.length.should == 2
+ result[0].should == 'privatekey'
+ result[1].should == 'publickey'
+ end
+
+ it "should fail if something goes wrong during generation" do
+ File.stubs(:exists?).with("/tmp/a/b/c").returns(false)
+ File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false)
+ File.stubs(:directory?).with("/tmp/a/b").returns(true)
+ Puppet::Util.expects(:execute).with(['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', '-f', '/tmp/a/b/c', '-P', '', '-q']).returns("something is wrong")
+ lambda { @scope.function_ssh_keygen("/tmp/a/b/c") }.should( raise_error(Puppet::ParseError))
+ end
+ end
+end
diff --git a/templates/sshd_config/CentOS.erb b/templates/sshd_config/CentOS.erb
index e1c8419..859759a 100644
--- a/templates/sshd_config/CentOS.erb
+++ b/templates/sshd_config/CentOS.erb
@@ -16,14 +16,12 @@
# only protocol 2
Protocol 2
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
<%- end -%>
# Use these options to restrict which interfaces/protocols sshd will bind to
@@ -206,6 +204,11 @@ AllowUsers <%= sshd_allowed_users %>
AllowGroups <%= sshd_allowed_groups %>
<%- end -%>
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
<%- end %>
diff --git a/templates/sshd_config/Debian_etch.erb b/templates/sshd_config/Debian_etch.erb
index 746a447..23559fc 100644
--- a/templates/sshd_config/Debian_etch.erb
+++ b/templates/sshd_config/Debian_etch.erb
@@ -6,14 +6,12 @@
<%- end %>
# What ports, IPs and protocols we listen for
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
<%- end -%>
# Use these options to restrict which interfaces/protocols sshd will bind to
@@ -159,16 +157,12 @@ UsePAM yes
UsePAM no
<%- end -%>
-HostbasedUsesNameFromPacketOnly yes
-
<%- if sshd_tcp_forwarding.to_s == 'yes' then -%>
AllowTcpForwarding yes
<%- else -%>
AllowTcpForwarding no
<%- end -%>
-ChallengeResponseAuthentication no
-
<%- unless sshd_allowed_users.to_s.empty? then -%>
AllowUsers <%= sshd_allowed_users -%>
<%- end -%>
@@ -178,6 +172,11 @@ AllowGroups <%= sshd_allowed_groups %>
PrintMotd no
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
<%- end %>
diff --git a/templates/sshd_config/Debian_lenny.erb b/templates/sshd_config/Debian_lenny.erb
index 3c3d562..65befdc 100644
--- a/templates/sshd_config/Debian_lenny.erb
+++ b/templates/sshd_config/Debian_lenny.erb
@@ -6,14 +6,12 @@
<%- end %>
# What ports, IPs and protocols we listen for
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
<%- end -%>
# Use these options to restrict which interfaces/protocols sshd will bind to
@@ -138,6 +136,9 @@ KeepAlive yes
#Banner /etc/issue.net
#ReverseMappingCheck yes
+# Allow client to pass locale environment variables
+AcceptEnv LANG LC_*
+
<%- if sshd_sftp_subsystem.to_s.empty? then %>
Subsystem sftp /usr/lib/openssh/sftp-server
<%- else %>
@@ -159,8 +160,6 @@ UsePAM yes
UsePAM no
<%- end -%>
-HostbasedUsesNameFromPacketOnly yes
-
<%- if sshd_tcp_forwarding.to_s == 'yes' then -%>
AllowTcpForwarding yes
<%- else -%>
@@ -182,6 +181,11 @@ AllowGroups <%= sshd_allowed_groups %>
PrintMotd no
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
<%- end %>
diff --git a/templates/sshd_config/Debian_sid.erb b/templates/sshd_config/Debian_sid.erb
new file mode 100644
index 0000000..0213342
--- /dev/null
+++ b/templates/sshd_config/Debian_sid.erb
@@ -0,0 +1,207 @@
+# This file is managed by Puppet, all local modifications will be overwritten
+#
+# Package generated configuration file
+# See the sshd(8) manpage for details
+
+<%- unless sshd_head_additional_options.to_s.empty? then %>
+<%= sshd_head_additional_options %>
+<%- end %>
+
+# What ports, IPs and protocols we listen for
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
+#Port -- disabled by puppet
+<% else -%>
+Port <%= port %>
+<% end -%>
+<%- end -%>
+
+# Use these options to restrict which interfaces/protocols sshd will bind to
+<% for address in sshd_listen_address -%>
+ListenAddress <%= address %>
+<% end -%>
+Protocol 2
+# HostKeys for protocol version 2
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+#Privilege Separation is turned on for security
+UsePrivilegeSeparation yes
+
+# Lifetime and size of ephemeral version 1 server key
+KeyRegenerationInterval 3600
+ServerKeyBits 768
+
+# Logging
+SyslogFacility AUTH
+LogLevel INFO
+
+# Authentication:
+LoginGraceTime 600
+<%- unless sshd_permit_root_login.to_s.empty? then -%>
+PermitRootLogin <%= sshd_permit_root_login -%>
+<%- else -%>
+PermitRootLogin without-password
+<%- end -%>
+
+<%- if sshd_strict_modes.to_s == 'yes' then -%>
+StrictModes yes
+<%- else -%>
+StrictModes no
+<%- end -%>
+
+<%- if sshd_rsa_authentication.to_s == 'yes' then -%>
+RSAAuthentication yes
+<%- else -%>
+RSAAuthentication no
+<%- end -%>
+
+<%- if sshd_pubkey_authentication.to_s == 'yes' then -%>
+PubkeyAuthentication yes
+<%- else -%>
+PubkeyAuthentication no
+<%- end -%>
+
+<%- unless sshd_authorized_keys_file.to_s.empty? then -%>
+AuthorizedKeysFile <%= sshd_authorized_keys_file %>
+<%- else -%>
+AuthorizedKeysFile %h/.ssh/authorized_keys
+<%- end -%>
+
+# Don't read the user's ~/.rhosts and ~/.shosts files
+<%- if sshd_ignore_rhosts.to_s == 'yes' then -%>
+IgnoreRhosts yes
+<%- else -%>
+IgnoreRhosts no
+<% end -%>
+# For this to work you will also need host keys in /etc/ssh_known_hosts
+<%- if sshd_rhosts_rsa_authentication.to_s == 'yes' then -%>
+RhostsRSAAuthentication yes
+<%- else -%>
+RhostsRSAAuthentication no
+<% end -%>
+# similar for protocol version 2
+<%- if sshd_hostbased_authentication.to_s == 'yes' then -%>
+HostbasedAuthentication yes
+<%- else -%>
+HostbasedAuthentication no
+<% end -%>
+# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
+#IgnoreUserKnownHosts yes
+
+# To enable empty passwords, change to yes (NOT RECOMMENDED)
+<%- if sshd_permit_empty_passwords.to_s == 'yes' then -%>
+PermitEmptyPasswords yes
+<% else -%>
+PermitEmptyPasswords no
+<% end -%>
+
+# Change to yes to enable challenge-response passwords (beware issues with
+# some PAM modules and threads)
+<%- if sshd_challenge_response_authentication.to_s == 'yes' then -%>
+ChallengeResponseAuthentication yes
+<%- else -%>
+ChallengeResponseAuthentication no
+<%- end -%>
+
+# To disable tunneled clear text passwords, change to no here!
+<%- if sshd_password_authentication.to_s == 'yes' then -%>
+PasswordAuthentication yes
+<%- else -%>
+PasswordAuthentication no
+<%- end -%>
+
+# Kerberos options
+<%- if sshd_kerberos_authentication.to_s == 'yes' then -%>
+KerberosAuthentication yes
+<%- else -%>
+KerberosAuthentication no
+<%- end -%>
+<%- if sshd_kerberos_orlocalpasswd.to_s == 'yes' then -%>
+KerberosOrLocalPasswd yes
+<%- else -%>
+KerberosOrLocalPasswd no
+<%- end -%>
+<%- if sshd_kerberos_ticketcleanup.to_s == 'yes' then -%>
+KerberosTicketCleanup yes
+<%- else -%>
+KerberosTicketCleanup no
+<%- end -%>
+
+# GSSAPI options
+<%- if sshd_gssapi_authentication.to_s == 'yes' then -%>
+GSSAPIAuthentication yes
+<%- else -%>
+GSSAPIAuthentication no
+<%- end -%>
+<%- if sshd_gssapi_authentication.to_s == 'yes' then -%>
+GSSAPICleanupCredentials yes
+<%- else -%>
+GSSAPICleanupCredentials yes
+<%- end -%>
+
+<%- if sshd_x11_forwarding.to_s == 'yes' then -%>
+X11Forwarding yes
+<%- else -%>
+X11Forwarding no
+<%- end -%>
+X11DisplayOffset 10
+PrintMotd no
+PrintLastLog yes
+TCPKeepAlive yes
+
+#UseLogin no
+
+#MaxStartups 10:30:60
+#Banner /etc/issue.net
+
+# Allow client to pass locale environment variables
+AcceptEnv LANG LC_*
+
+<%- if sshd_sftp_subsystem.to_s.empty? then %>
+Subsystem sftp /usr/lib/openssh/sftp-server
+<%- else %>
+Subsystem sftp <%= sshd_sftp_subsystem %>
+<%- end %>
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication. Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
+<%- if sshd_use_pam.to_s == 'yes' then -%>
+UsePAM yes
+<%- else -%>
+UsePAM no
+<%- end -%>
+
+<%- if sshd_tcp_forwarding.to_s == 'yes' then -%>
+AllowTcpForwarding yes
+<%- else -%>
+AllowTcpForwarding no
+<%- end -%>
+
+<%- if sshd_agent_forwarding.to_s == 'yes' then -%>
+AllowAgentForwarding yes
+<%- else -%>
+AllowAgentForwarding no
+<%- end -%>
+
+<%- unless sshd_allowed_users.to_s.empty? then -%>
+AllowUsers <%= sshd_allowed_users -%>
+<%- end -%>
+<%- unless sshd_allowed_groups.to_s.empty? then %>
+AllowGroups <%= sshd_allowed_groups %>
+<%- end %>
+
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
+<%- unless sshd_tail_additional_options.to_s.empty? then %>
+<%= sshd_tail_additional_options %>
+<%- end %>
diff --git a/templates/sshd_config/Debian_squeeze.erb b/templates/sshd_config/Debian_squeeze.erb
index 56b1cab..dfebcc3 100644
--- a/templates/sshd_config/Debian_squeeze.erb
+++ b/templates/sshd_config/Debian_squeeze.erb
@@ -8,15 +8,14 @@
<%- end %>
# What ports, IPs and protocols we listen for
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
-<%- end %>
+<%- end -%>
+
# Use these options to restrict which interfaces/protocols sshd will bind to
<% for address in sshd_listen_address -%>
ListenAddress <%= address %>
@@ -198,7 +197,11 @@ AllowUsers <%= sshd_allowed_users -%>
AllowGroups <%= sshd_allowed_groups %>
<%- end %>
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
<%- end %>
-
diff --git a/templates/sshd_config/Debian_wheezy.erb b/templates/sshd_config/Debian_wheezy.erb
new file mode 120000
index 0000000..3faae05
--- /dev/null
+++ b/templates/sshd_config/Debian_wheezy.erb
@@ -0,0 +1 @@
+Debian_sid.erb \ No newline at end of file
diff --git a/templates/sshd_config/Gentoo.erb b/templates/sshd_config/Gentoo.erb
index 2112f0d..f9f5b23 100644
--- a/templates/sshd_config/Gentoo.erb
+++ b/templates/sshd_config/Gentoo.erb
@@ -14,14 +14,12 @@
<%= sshd_head_additional_options %>
<%- end %>
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
<%- end -%>
# Use these options to restrict which interfaces/protocols sshd will bind to
@@ -210,6 +208,10 @@ AllowUsers <%= sshd_allowed_users %>
AllowGroups <%= sshd_allowed_groups %>
<%- end %>
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
diff --git a/templates/sshd_config/OpenBSD.erb b/templates/sshd_config/OpenBSD.erb
index 69e8afa..7a20cd9 100644
--- a/templates/sshd_config/OpenBSD.erb
+++ b/templates/sshd_config/OpenBSD.erb
@@ -12,14 +12,12 @@
<%= sshd_head_additional_options %>
<%- end %>
-<%- unless sshd_port.to_s.empty? then -%>
-<%- if sshd_port.to_s == 'off' then -%>
+<%- sshd_ports.each do |port| -%>
+<%- if port.to_s == 'off' then -%>
#Port -- disabled by puppet
<% else -%>
-Port <%= sshd_port -%>
+Port <%= port %>
<% end -%>
-<%- else -%>
-Port 22
<%- end -%>
# Use these options to restrict which interfaces/protocols sshd will bind to
@@ -186,6 +184,11 @@ AllowGroups <%= sshd_allowed_groups %>
# AllowTcpForwarding no
# ForceCommand cvs server
+<%- if sshd_hardened_ssl.to_s == 'yes' then -%>
+Ciphers aes256-ctr
+MACs hmac-sha1
+<%- end -%>
+
<%- unless sshd_tail_additional_options.to_s.empty? then %>
<%= sshd_tail_additional_options %>
<%- end %>
diff --git a/templates/sshd_config/Ubuntu.erb b/templates/sshd_config/Ubuntu.erb
new file mode 120000
index 0000000..11b0acc
--- /dev/null
+++ b/templates/sshd_config/Ubuntu.erb
@@ -0,0 +1 @@
+Debian_squeeze.erb \ No newline at end of file