OpenSSH LDAP PUBLIC KEY PATCH
Copyright (c) 2003 Eric AUGE (eau@phear.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
purposes of this patch:
This patch would help to have authentication centralization policy
using ssh public key authentication.
This patch could be an alternative to other "secure" authentication system
working in a similar way (Kerberos, SecurID, etc...), except the fact
that it's based on OpenSSH and its public key abilities.
>> FYI: <<
'uid': means unix accounts existing on the current server
'lpkServerGroup:' mean server group configured on the current server ('lpkServerGroup' in sshd_config)
example schema:
server1 (uid: eau,rival,toto) (lpkServerGroup: unix)
___________ /
/ \ --- - server3 (uid: eau, titi) (lpkServerGroup: unix)
| LDAP Server | \
| eau ,rival | server2 (uid: rival, eau) (lpkServerGroup: unix)
| titi ,toto |
| userx,.... | server5 (uid: eau) (lpkServerGroup: mail)
\___________/ \ /
----- - server4 (uid: eau, rival) (no group configured)
\
etc...
- WHAT WE NEED :
* configured LDAP server somewhere on the network (i.e. OpenLDAP)
* patched sshd (with this patch ;)
* LDAP user(/group) entry (look at users.ldif (& groups.ldif)):
User entry:
- attached to the 'ldapPublicKey' objectclass
- attached to the 'posixAccount' objectclass
- with a filled 'sshPublicKey' attribute
Example:
dn: uid=eau,ou=users,dc=cuckoos,dc=net
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: posixAccount
objectclass: ldapPublicKey
description: Eric AUGE Account
userPassword: blah
cn: Eric AUGE
sn: Eric AUGE
uid: eau
uidNumber: 1034
gidNumber: 1
homeDirectory: /export/home/eau
sshPublicKey: ssh-dss AAAAB3...
sshPublicKey: ssh-dss AAAAM5...
Group entry:
- attached to the 'posixGroup' objectclass
- with a 'cn' groupname attribute
- with multiple 'memberUid' attributes filled with usernames allowed in this group
Example:
# few members
dn: cn=unix,ou=groups,dc=cuckoos,dc=net
objectclass: top
objectclass: posixGroup
description: Unix based servers group
cn: unix
gidNumber: 1002
memberUid: eau
memberUid: user1
memberUid: user2
- HOW IT WORKS :
* without patch
If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..)
and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled).
* with the patch
If a user want to authenticate to log in a server, the sshd will first look for auth method including LDAP pubkey, if the ldappubkey options is enabled.
It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem.
(usually in $HOME/.ssh/authorized_keys)
If groups are enabled, it will also check if the user that wants to login is in the group of the server he is trying to log into.
If it fails, it falls back on RSA auth files ($HOME/.ssh/authorized_keys), etc.. and finally to standard password authentication (if enabled).
7 tokens are added to sshd_config :
# here is the new patched ldap related tokens
# entries in your LDAP must be posixAccount & strongAuthenticationUser & posixGroup
UseLPK yes # look the pub key into LDAP
LpkServers ldap://10.31.32.5/ ldap://10.31.32.4 ldap://10.31.32.3 # which LDAP server for users ? (URL format)
LpkUserDN ou=users,dc=foobar,dc=net # which base DN for users ?
LpkGroupDN ou=groups,dc=foobar,dc=net # which base DN for groups ?
LpkBindDN cn=manager,dc=foobar,dc=net # which bind DN ?
LpkBindPw asecret # bind DN credidentials
LpkServerGroup agroupname # the group the server is part of
Right now i'm using anonymous binding to get public keys, because getting public keys of someone doesn't impersonate him¸ but there is some
flaws you have to take care of.
- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY
* my way (there is plenty :)
- create ldif file (i.e. users.ldif)
- cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub
- my way in 4 steps :
Example:
# you add this to the user entry in the LDIF file :
[...]
objectclass: posixAccount
objectclass: ldapPublicKey
[...]
sshPubliKey: ssh-dss AAAABDh12DDUR2...
[...]
# insert your entry and you're done :)
ldapadd -D balblabla -w bleh < file.ldif
all standard options can be present in the 'sshPublicKey' attribute.
- WHY :
Simply because, i was looking for a way to centralize all sysadmins authentication, easily, without completely using LDAP
as authentication method (like pam_ldap etc..).
After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get
public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser'
objectclass within LDAP and part of the group the SSH server is in).
Passwords update are no longer a nightmare for a server farm (key pair passphrase is stored on each user's box and private key is locally encrypted using his passphrase
so each user can change it as much as he wants).
Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only).
- RULES :
Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema.
and the additionnal lpk.schema.
This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication
(pamldap, nss_ldap, etc..).
This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..).
Referring to schema at the beginning of this file if user 'eau' is only in group 'unix'
'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'.
If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able
to log in 'server5' (i hope you got the idea, my english is bad :).
Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP
server.
When you want to allow a new user to have access to the server parc, you just add him an account on
your servers, you add his public key into his entry on the LDAP server, it's done.
Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys).
When the user needs to change his passphrase he can do it directly from his workstation by changing
his own key set lock passphrase, and all servers are automatically aware.
With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself
so he can add/modify/delete himself his public key when needed.
FLAWS :
LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP
allow write to users dn, somebody could replace someuser's public key by its own and impersonate some
of your users in all your server farm be VERY CAREFUL.
MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login
as the impersonnated user.
If LDAP server is down then, fallback on passwd auth.
the ldap code part has not been well audited yet.
- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif)
--- CUT HERE ---
dn: uid=jdoe,ou=users,dc=foobar,dc=net
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: posixAccount
objectclass: ldapPublicKey
description: My account
cn: John Doe
sn: John Doe
uid: jdoe
uidNumber: 100
gidNumber: 100
homeDirectory: /home/jdoe
sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB....
[...]
--- CUT HERE ---
- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif)
--- CUT HERE ---
dn: cn=unix,ou=groups,dc=cuckoos,dc=net
objectclass: top
objectclass: posixGroup
description: Unix based servers group
cn: unix
gidNumber: 1002
memberUid: jdoe
memberUid: user1
memberUid: user2
[...]
--- CUT HERE ---
>> FYI: <<
Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry
- COMPILING:
1. Apply the patch
2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes
3. make
4. it's done.
- BLA :
I hope this could help, and i hope to be clear enough,, or give ideas. questions/comments/improvements are welcome.
- TODO :
Redesign differently.
- DOCS/LINK :
http://pacsec.jp/core05/psj05-barisani-en.pdf
http://fritz.potsdam.edu/projects/openssh-lpk/
http://fritz.potsdam.edu/projects/sshgate/
http://dev.inversepath.com/trac/openssh-lpk
http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm )
- CONTRIBUTORS/IDEAS/GREETS :
- Falk Siemonsmeier.
- Jacob Rief.
- Michael Durchgraf.
- frederic peters.
- Finlay dobbie.
- Stefan Fisher.
- Robin H. Johnson.
- Adrian Bridgett.
- CONTACT :
- Eric AUGE <eau@phear.org>
- Andrea Barisani <andrea@inversepath.com>