0
0
mirror of https://github.com/saltstack-formulas/openssh-formula.git synced 2026-02-21 12:28:09 +01:00

Merge pull request #2 from saltstack-formulas/master

Updating my branch to be in line with the saltstack openssh-formula
This commit is contained in:
Mark Eggert 2015-05-06 23:43:48 -05:00
commit b0cd6604f5
9 changed files with 414 additions and 176 deletions

View File

@ -5,7 +5,7 @@ Install and configure an openssh server.
.. note::
See the full `Salt Formulas installation and usage instructions
<http://docs.saltstack.com/topics/conventions/formulas.html>`_.
<http://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html>`_.
Available states
================
@ -41,3 +41,42 @@ Installs the ssh daemon configuration file included in this formula
by values from pillar. ``pillar.example`` results in the generation
of the default ``sshd_config`` file on Debian Wheezy.
``openssh.known_hosts``
-----------------------
Manages the site-wide ssh_known_hosts file and fills it with the
public SSH host keys of all minions. You can restrict the set of minions
whose keys are listed by using the pillar data ``openssh:known_hosts:target``
and ``openssh:known_hosts:expr_form`` (those fields map directly to the
corresponding attributes of the ``mine.get`` function).
The Salt mine is used to share the public SSH host keys, you must thus
configure it accordingly on all hosts that must export their keys. Two
mine functions are required, one that exports the keys (one key per line,
as they are stored in ``/etc/ssh/ssh_host_*_key.pub``) and one that defines
the public hostname that the keys are associated to. Here's the way to
setup those functions through pillar::
# Required for openssh.known_hosts
mine_functions:
public_ssh_host_keys:
mine_function: cmd.run
cmd: cat /etc/ssh/ssh_host_*_key.pub
public_ssh_hostname:
mine_function: grains.get
key: id
The above example assumes that the minion identifier is a valid DNS name
that can be used to connect to the host. If that's not the case, you might
want to use the ``fqdn`` grain instead of the ``id`` one. The above example
also uses the default mine function names used by this formula. If you have to
use other names, then you should indicate the names to use in pillar keys
``openssh:known_hosts:mine_keys_function`` and
``openssh:known_hosts:mine_hostname_function``.
You can also integrate alternate DNS names of the various hosts in the
ssh_known_hosts files. You just have to list all the alternate DNS names as a
list in the ``openssh:known_hosts:aliases`` pillar key. Whenever the IPv4 or
IPv6 behind one of those DNS entries matches an IPv4 or IPv6 behind the
official hostname of a minion, the alternate DNS name will be associated to the
minion's public SSH host key.

View File

@ -1,43 +1,49 @@
{%- macro print_name(identifier, key) -%}
{%- if 'name' in key %}
{{ key['name'] }}:
{%- else %}
{{ identifier }}:
{%- endif %}
{%- endmacro -%}
{%- macro print_ssh_auth(identifier, key) -%}
{%- if 'user' in key %}
- user: {{ key['user'] }}
{%- else %}
- user: {{ identifier }}
{%- endif %}
{%- if 'present' in key and key['present'] and 'source' in key %}
- source: {{ key['source'] }}
{%- else %}
{%- if 'enc' in key %}
- enc: {{ key['enc'] }}
{%- endif -%}
{%- if 'comment' in key %}
- comment: {{ key['comment'] }}
{%- endif -%}
{%- if 'options' in key %}
- options: {{ key['options'] }}
{%- endif -%}
{%- endif %}
{%- endmacro -%}
include:
- openssh
{% from "openssh/map.jinja" import openssh with context %}
{% set openssh_pillar = pillar.get('openssh', {}) %}
{% set auth = openssh_pillar.get('auth', {}) %}
{% for user,keys in auth.items() -%}
{% for key in keys -%}
{%- from "openssh/map.jinja" import openssh with context -%}
{%- set openssh_pillar = pillar.get('openssh', {}) -%}
{%- set auth = openssh_pillar.get('auth', {}) -%}
{%- for identifier,keys in auth.items() -%}
{%- for key in keys -%}
{% if 'present' in key and key['present'] %}
{{ key['name'] }}:
{{ print_name(identifier, key) }}:
ssh_auth.present:
- user: {{ user }}
{% if 'source' in key %}
- source: {{ key['source'] }}
{% else %}
{% if 'enc' in key %}
- enc: {{ key['enc'] }}
{% endif %}
{% if 'comment' in key %}
- comment: {{ key['comment'] }}
{% endif %}
{% if 'options' in key %}
- options: {{ key['options'] }}
{% endif %}
{% endif %}
{{ print_ssh_auth(identifier, key) }}
- require:
- service: {{ openssh.service }}
{% else %}
{{ key['name'] }}:
{%- else %}
{{ print_name(identifier, key) }}:
ssh_auth.absent:
- user: {{ user }}
{% if 'enc' in key %}
- enc: {{ key['enc'] }}
{% endif %}
{% if 'comment' in key %}
- comment: {{ key['comment'] }}
{% endif %}
{% if 'options' in key %}
- options: {{ key['options'] }}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{{ print_ssh_auth(identifier, key) }}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}

View File

@ -9,47 +9,35 @@ sshd_config:
- source: {{ openssh.sshd_config_src }}
- template: jinja
- user: root
- group: root
- mode: 644
- watch_in:
- service: openssh
{% if salt['pillar.get']('openssh:provide_dsa_keys', False) %}
ssh_host_dsa_key:
{% for keyType in ['ecdsa', 'dsa', 'rsa', 'ed25519'] %}
{% if salt['pillar.get']('openssh:generate_' ~ keyType ~ '_keys', False) %}
ssh_generate_host_{{ keyType }}_key:
cmd.run:
- name: ssh-keygen -t {{ keyType }} -N '' -f /etc/ssh/ssh_host_{{ keyType }}_key
- creates: /etc/ssh/ssh_host_{{ keyType }}_key
- user: root
{% elif salt['pillar.get']('openssh:provide_' ~ keyType ~ '_keys', False) %}
ssh_host_{{ keyType }}_key:
file.managed:
- name: /etc/ssh/ssh_host_dsa_key
- contents_pillar: 'openssh:dsa:private_key'
- name: /etc/ssh/ssh_host_{{ keyType }}_key
- contents_pillar: 'openssh:{{ keyType }}:private_key'
- user: root
- mode: 600
- require_in:
- service: {{ openssh.service }}
ssh_host_dsa_key.pub:
ssh_host_{{ keyType }}_key.pub:
file.managed:
- name: /etc/ssh/ssh_host_dsa_key.pub
- contents_pillar: 'openssh:dsa:public_key'
- user: root
- mode: 600
- require_in:
- service: {{ openssh.service }}
{% endif %}
{% if salt['pillar.get']('openssh:provide_rsa_keys', False) %}
ssh_host_rsa_key:
file.managed:
- name: /etc/ssh/ssh_host_rsa_key
- contents_pillar: 'openssh:rsa:private_key'
- user: root
- mode: 600
- require_in:
- service: {{ openssh.service }}
ssh_host_rsa_key.pub:
file.managed:
- name: /etc/ssh/ssh_host_rsa_key.pub
- contents_pillar: 'openssh:rsa:public_key'
- name: /etc/ssh/ssh_host_{{ keyType }}_key.pub
- contents_pillar: 'openssh:{{ keyType }}:public_key'
- user: root
- mode: 600
- require_in:
- service: {{ openssh.service }}
{% endif %}
{% endfor %}

View File

@ -0,0 +1,34 @@
{%- set target = salt['pillar.get']('openssh:known_hosts:target', '*') -%}
{%- set expr_form = salt['pillar.get']('openssh:known_hosts:expr_form', 'glob') -%}
{%- set keys_function = salt['pillar.get']('openssh:known_hosts:mine_keys_function', 'public_ssh_host_keys') -%}
{%- set hostname_function = salt['pillar.get']('openssh:known_hosts:mine_hostname_function', 'public_ssh_hostname') -%}
{#- Lookup IP of all aliases so that when we have a matching IP, we inject the alias name
in the SSH known_hosts entry -#}
{%- set aliases = salt['pillar.get']('openssh:known_hosts:aliases', []) -%}
{%- set aliases_ips = {} -%}
{%- for alias in aliases -%}
{%- for ip in salt['dig.A'](alias) + salt['dig.AAAA'](alias) -%}
{%- do aliases_ips.setdefault(ip, []).append(alias) -%}
{%- endfor -%}
{%- endfor -%}
{#- Loop over targetted minions -#}
{%- set host_keys = salt['mine.get'](target, keys_function, expr_form=expr_form) -%}
{%- set host_names = salt['mine.get'](target, hostname_function, expr_form=expr_form) -%}
{%- for host, keys in host_keys|dictsort -%}
{%- set ip4 = salt['dig.A'](host) -%}
{%- set ip6 = salt['dig.AAAA'](host) -%}
{%- set names = [host_names.get(host, host)] -%}
{%- for ip in ip4 + ip6 -%}
{%- do names.append(ip) -%}
{%- for alias in aliases_ips.get(ip, []) -%}
{%- if alias not in names -%}
{%- do names.append(alias) -%}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- for line in keys.split('\n') -%}
{%- if line -%}
{{ ','.join(names) }} {{ line }}
{% endif -%}
{%- endfor -%}
{%- endfor -%}

View File

@ -1,97 +1,127 @@
{% set sshd_config = pillar.get('sshd_config', {}) %}
{%- set sshd_config = pillar.get('sshd_config', {}) -%}
{#- present in sshd_config and known in actual file options -#}
{%- set processed_options = [] -%}
{#- generic renderer used for sshd matches, known options, -#}
{#- and unknown options -#}
{%- macro render_option(keyword, default, config_dict=sshd_config) -%}
{%- set value = config_dict.get(keyword, default) -%}
{%- if value is sameas true -%}
{{ keyword }} yes
{%- elif value is sameas false -%}
{{ keyword }} no
{%- elif value is string or value is number -%}
{{ keyword }} {{ value }}
{%- else -%}
{%- for single_value in value -%}
{{ keyword }} {{ single_value }}
{% endfor -%}
{%- endif -%}
{%- endmacro -%}
{#- macros for render option according to present -#}
{%- macro option_impl(keyword, default, present) -%}
{%- if present -%}
{%- do processed_options.append(keyword) -%}
{%- set prefix='' -%}
{%- else -%}
{%- set prefix='#' -%}
{%- endif -%}
{#- add prefix to keyword -#}
{%- set keyword = prefix ~ keyword -%}
{{ render_option(keyword, default) }}
{%- endmacro -%}
{#- macros for render option commented by default -#}
{%- macro option(keyword, default, present) -%}
{{ option_impl(keyword, default, keyword in sshd_config) }}
{%- endmacro -%}
{#- macros for render option uncommented by default -#}
{%- macro option_default_uncommented(keyword, default, present) -%}
{{ option_impl(keyword, default, True) }}
{%- endmacro -%}
# This file is managed by salt. Manual changes risk being overwritten.
# The contents of the original sshd_config are kept on the bottom for
# quick reference.
# See the sshd_config(5) manpage for details
{% for keyword, argument in sshd_config.iteritems() %}
{%- if argument is sameas true %}
{{ keyword }} yes
{%- elif argument is sameas false %}
{{ keyword }} no
{%- elif argument is string or argument is number %}
{{ keyword }} {{ argument }}
{%- else %}
{%- for item in argument %}
{{ keyword }} {{ item }}
{%- endfor %}
{%- endif %}
{%- endfor %}
# What ports, IPs and protocols we listen for
#Port 22
{{ option('Port', 22) }}
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
#Protocol 2
{{ option('ListenAddress', ['::', '0.0.0.0']) }}
{{ option_default_uncommented('Protocol', 2) }}
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
{{ option_default_uncommented('HostKey', ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_dsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key']) -}}
#Privilege Separation is turned on for security
#UsePrivilegeSeparation yes
{{ option_default_uncommented('UsePrivilegeSeparation', 'yes') }}
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 3600
#ServerKeyBits 768
{{ option_default_uncommented('KeyRegenerationInterval', 3600) }}
{{ option_default_uncommented('ServerKeyBits', 768) }}
# Logging
#SyslogFacility AUTH
#LogLevel INFO
{{ option_default_uncommented('SyslogFacility', 'AUTH') }}
{{ option_default_uncommented('LogLevel', 'INFO') }}
# Authentication:
#LoginGraceTime 120
#PermitRootLogin yes
#StrictModes yes
{{ option_default_uncommented('LoginGraceTime', 120) }}
{{ option_default_uncommented('PermitRootLogin', 'no') }}
{{ option_default_uncommented('StrictModes', 'yes') }}
#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
{{ option('DSAAuthentication', 'yes') }}
{{ option_default_uncommented('RSAAuthentication', 'yes') }}
{{ option_default_uncommented('PubkeyAuthentication', 'yes') }}
{{ option('AuthorizedKeysFile', '%h/.ssh/authorized_keys') }}
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
{{ option_default_uncommented('IgnoreRhosts', 'yes') }}
# For this to work you will also need host keys in /etc/ssh_known_hosts
#RhostsRSAAuthentication no
{{ option_default_uncommented('RhostsRSAAuthentication', 'no') }}
# similar for protocol version 2
#HostbasedAuthentication no
{{ option_default_uncommented('HostbasedAuthentication', 'no') }}
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
{{ option('IgnoreUserKnownHosts', 'yes') }}
# To enable empty passwords, change to yes (NOT RECOMMENDED)
#PermitEmptyPasswords no
{{ option_default_uncommented('PermitEmptyPasswords', 'no') }}
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
#ChallengeResponseAuthentication no
{{ option_default_uncommented('ChallengeResponseAuthentication', 'no') }}
{{ option('AuthenticationMethods', 'publickey,keyboard-interactive') }}
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
{{ option('PasswordAuthentication', 'yes') }}
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
{{ option('KerberosAuthentication', 'no') }}
{{ option('KerberosGetAFSToken', 'no') }}
{{ option('KerberosOrLocalPasswd', 'yes') }}
{{ option('KerberosTicketCleanup', 'yes') }}
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
{{ option('GSSAPIAuthentication', 'no') }}
{{ option('GSSAPICleanupCredentials', 'yes') }}
#X11Forwarding yes
#X11DisplayOffset 10
#PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
{{ option_default_uncommented('X11Forwarding', 'yes') }}
{{ option('AllowTcpForwarding', 'yes') }}
{{ option_default_uncommented('X11DisplayOffset', '10') }}
{{ option_default_uncommented('PrintMotd', 'no') }}
{{ option_default_uncommented('PrintLastLog', 'yes') }}
{{ option_default_uncommented('TCPKeepAlive', 'yes') }}
{{ option('UseLogin', 'no') }}
#MaxStartups 10:30:60
#Banner /etc/issue.net
{{ option('MaxStartups', '10:30:60') }}
{{ option('Banner', '/etc/issue.net') }}
# Allow client to pass locale environment variables
#AcceptEnv LANG LC_*
{{ option_default_uncommented('AcceptEnv', 'LANG LC_*') }}
#Subsystem sftp /usr/lib/openssh/sftp-server
{{ option_default_uncommented('Subsystem', 'sftp /usr/lib/openssh/sftp-server') }}
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
@ -102,42 +132,45 @@
# 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'.
UsePAM yes
{{ option_default_uncommented('UsePAM', 'yes') }}
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
PrintMotd no # pam does that
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
{% if grains['os_family'] == 'RedHat' %}
UsePrivilegeSeparation yes # RedHat/Centos 6.4 and earlier currently ship 5.3 (sandbox introduced in OpenSSH 5.9)
{% else %}
UsePrivilegeSeparation sandbox # Default for new installations.
{% endif %}
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# DNS resolve and map remote IP addresses
{{ option('UseDNS', 'yes') }}
# no default banner path
Banner /etc/ssh/banner
# Restricting Users and Hosts
# example:
# AllowUsers vader@10.0.0.1 maul@sproing.evil.com luke
# AllowGroups wheel staff
#
# Keep in mind that using AllowUsers or AllowGroups means that anyone
# not Matching one of the supplied patterns will be denied access by default.
# Also, in order for sshd to allow access based on full or partial hostnames it
# needs to to a DNS lookup
#
# DenyUsers
{{ option('DenyUsers', '') }}
# AllowUsers
{{ option('AllowUsers', '') }}
# DenyGroups
{{ option('DenyGroups', '') }}
# AllowGroups
{{ option('AllowGroups', '') }}
# override default of no subsystems
Subsystem sftp /usr/lib/ssh/sftp-server
{# Handling unknown in salt template options #}
{%- for keyword in sshd_config.keys() %}
{#- Matches have to be at the bottem and should be handled differently -#}
{%- if not keyword in processed_options and keyword != 'matches' -%}
{#- send a blank default as it doesn't matter #}
{{ render_option(keyword, '') }}
{%- endif -%}
{%- endfor %}
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server
{# Handle matches last as they need to go at the bottom #}
{%- if 'matches' in sshd_config %}
{%- for match in sshd_config['matches'].values() %}
Match {{ match['type'].keys()[0] }} {{ match['type'].values()[0] }}
{%- for keyword in match['options'].keys() %}
{{ render_option(keyword, '', config_dict=match['options']) }}
{%- endfor %}
{%- endfor %}
{%- endif %}

View File

@ -1,10 +1,14 @@
{% from "openssh/map.jinja" import openssh with context %}
openssh:
{% if openssh.server is defined %}
pkg.installed:
- name: {{ openssh.server }}
{% endif %}
service.running:
- enable: True
- name: {{ openssh.service }}
{% if openssh.server is defined %}
- require:
- pkg: {{ openssh.server }}
{% endif %}

16
openssh/known_hosts.sls Normal file
View File

@ -0,0 +1,16 @@
{% from "openssh/map.jinja" import openssh with context %}
ensure dig is available:
pkg.installed:
- name: {{ openssh.dig_pkg }}
manage ssh_known_hosts file:
file.managed:
- name: {{ openssh.ssh_known_hosts }}
- source: salt://openssh/files/ssh_known_hosts
- template: jinja
- user: root
- group: root
- mode: 644
- require:
- pkg: ensure dig is available

View File

@ -1,4 +1,15 @@
{% set openssh = salt['grains.filter_by']({
'Arch': {
'server': 'openssh',
'client': 'openssh',
'service': 'sshd.socket',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'dnsutils',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
'Debian': {
'server': 'openssh-server',
'client': 'openssh-client',
@ -7,6 +18,28 @@
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'dnsutils',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
'FreeBSD': {
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'bind-tools',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
'Gentoo': {
'server': 'net-misc/openssh',
'client': 'net-misc/openssh',
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'net-dns/bind-tools',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
'RedHat': {
'server': 'openssh-server',
@ -16,5 +49,18 @@
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'bind-utils',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
'Suse': {
'server': 'openssh',
'client': 'openssh',
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'dig_pkg': 'bind-utils',
'ssh_known_hosts': '/etc/ssh/ssh_known_hosts',
},
}, merge=salt['pillar.get']('openssh:lookup')) %}

View File

@ -5,41 +5,68 @@ sshd_config:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_ecdsa_key
UsePrivilegeSeparation: yes
- /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation: 'yes'
KeyRegenerationInterval: 3600
ServerKeyBits: 768
SyslogFacility: AUTH
LogLevel: INFO
LoginGraceTime: 120
PermitRootLogin: yes
StrictModes: yes
RSAAuthentication: yes
PubkeyAuthentication: yes
IgnoreRhosts: yes
RhostsRSAAuthentication: no
HostbasedAuthentication: no
PermitEmptyPasswords: no
ChallengeResponseAuthentication: no
X11Forwarding: yes
PermitRootLogin: 'yes'
PasswordAuthentication: 'no'
StrictModes: 'yes'
RSAAuthentication: 'yes'
PubkeyAuthentication: 'yes'
IgnoreRhosts: 'yes'
RhostsRSAAuthentication: 'no'
HostbasedAuthentication: 'no'
PermitEmptyPasswords: 'no'
ChallengeResponseAuthentication: 'no'
AuthenticationMethods 'publickey,keyboard-interactive'
X11Forwarding: 'yes'
X11DisplayOffset: 10
PrintMotd: no
PrintLastLog: yes
TCPKeepAlive: yes
PrintMotd: 'no'
PrintLastLog: 'yes'
TCPKeepAlive: 'yes'
AcceptEnv: "LANG LC_*"
Subsystem: "sftp /usr/lib/openssh/sftp-server"
UsePAM: yes
UsePAM: 'yes'
UseDNS: 'yes'
AllowUsers: 'vader@10.0.0.1 maul@evil.com sidious luke'
DenyUsers: 'yoda chewbaca@112.10.21.1'
AllowGroups: 'wheel staff imperial'
DenyGroups: 'rebel'
Deny
matches:
sftp_chroot:
type:
Group: sftpusers
options:
ChrootDirectory: /sftp-chroot/%u
X11Forwarding: no
AllowTcpForwarding: no
ForceCommand: internal-sftp
openssh:
auth:
joe:
- name: JOE_VALID_SSH_PUBLIC_KEY
joe-valid-ssh-key-desktop:
- user: joe
present: True
enc: ssh-rsa
comment: main key
- name: JOE_NON_VALID_SSH_PUBLIC_KEY
comment: main key - desktop
joe-valid-ssh-key-notebook:
- user: joe
present: True
enc: ssh-rsa
comment: main key - notebook
joe-non-valid-ssh-key:
- user: joe
present: False
enc: ssh-rsa
comment: obsolete key - removed
generate_dsa_keys: False
provide_dsa_keys: False
dsa:
private_key: |
-----BEGIN DSA PRIVATE KEY-----
@ -47,7 +74,18 @@ openssh:
-----END DSA PRIVATE KEY-----
public_key: |
ssh-dss NOT_DEFINED
provide_dsa_keys: False
generate_ecdsa_keys: False
provide_ecdsa_keys: False
ecdsa:
private_key: |
-----BEGIN EC PRIVATE KEY-----
NOT_DEFINED
-----END EC PRIVATE KEY-----
public_key: |
ecdsa-sha2-nistp256 NOT_DEFINED
generate_rsa_keys: False
provide_rsa_keys: False
rsa:
private_key: |
@ -56,3 +94,37 @@ openssh:
-----END RSA PRIVATE KEY-----
public_key: |
ssh-rsa NOT_DEFINED
generate_ed25519_keys: False
provide_ed25519_keys: False
ed25519:
private_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
NOT_DEFINED
-----END OPENSSH PRIVATE KEY-----
public_key: |
ssh-ed25519 NOT_DEFINED
known_hosts:
# The next 2 settings restrict the set of minions that will be added in
# the generated ssh_known_hosts files (the default is to match all minions)
target: '*'
expr_form: 'glob'
# Name of mining functions used to gather public keys and hostnames
# (the default values are shown here)
mine_keys_function: public_ssh_host_keys
mine_hostname_function: public_ssh_hostname
# List of DNS entries also pointing to our managed machines and that we want
# to inject in our generated ssh_known_hosts file
aliases:
- cname-to-minion.example.org
- alias.example.org
# Required for openssh.known_hosts
mine_functions:
public_ssh_host_keys:
mine_function: cmd.run
cmd: cat /etc/ssh/ssh_host_*_key.pub
public_ssh_hostname:
mine_function: grains.get
key: id