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 - Andrea Barisani