1 2 3 4 5 6 | ||
Editor: DonovanBaarda
Time: 2014/07/16 12:23:35 GMT-4 |
||
Note: |
added:
Implementation
==============
See http://github.com/dbaarda/LightLdapd for the latest sources.
This was forked and renamed from http://github.com/urbanserj/entente after submitting several improvements and cleanups. The fork was done with the approval blessing of the entente author so that entente could remain a good example of a bare minimum LDAP server.
With dnsmasq there is a very small, simple, powerful, and reliable combined dns server, dns cache, dhcp server, and tftp server. It's got everything you need to serve a small home/classroom/school sized network that can include thin clients. It's very easy to configure (dns just serves up the /etc/hosts file with auto-dns support for dhcp clients), and its dhcp server can easily be configured to serve anything like auto-proxy config or different boot options for different thin clients. It's small enough to run on a OpenWRT? router or QNAP NAS.
One of the things a small network like this really needs is an LDAP server for managing users. It needs to be small and efficient, with enough grunt to support at least 100 clients and 1000 users when running on something like a router or NAS. It must be powerful enough to support most commonly used functionality, but familiar and simple to configure. It absolutely must be reliable and secure enough for the home/classroom/school environment. I believe that they should be written in C (widely used and fast) using an event-loop design (threads suck).
Primary objectives are;
Secondary objectives are;
- OpenLdap? - Feels a bit big and clunky. Support for serving /etc/passwd deprecated in favour of database backends. Seems to be targeting enterprise sized setups, not small home networks.
- https://github.com/vlm/ldap-server-example - OK example. Looks like it's a one-shot server; run it and it answers one query then terminates. Might be useful to pull code from.
- https://github.com/urbanserj/entente - uses libpam, libev, and asn1c to compile LDAP ASN definition directly. A single 500 line file gives a server that can be used as an ldap auth backend using pam, but that's it. Should be extendible to support more of the LDAP functionality.
- http://www.fefe.de/tinyldap/ - Written in response to OpenLdap? being slow. Uses a simple fork-per-connection model and claims to still beat OpenLdap?. I think this shows that forking is not the high overhead it once was. Much more code than entente, including it's own ASN parser etc.
Of these entente looks the most interesting. It uses libev already. Its use of asn1c to compile the LDAP ASN appeals to my "as little coding as possible" objective. I think I'll use this as my starting point, and borrow code from the others when/if it turns out to be useful.
There are plenty of libraries, but I don't believe it's worth picking obscure ones unless they provide some really significant advantage over the more popular alternatives. Popular libraries get more use, debugging, support, and are more likely to be already installed. The Debian repository is a good indicator of popularity; if it's not in there, it's probably not popular enough to use. If multiple alternatives are in there, then the list of other packages that depend on it is a good indicator of which one is more popular. Also interesting is its own dependencies; does it depend only on other popular libraries? Something that has no dependencies but which implements large amounts of functionality normally provided by other libraries has probably re-invented lots of stuff badly (or statically linked the other libs in).
I also think code and binary size is a surprisingly good indicator of quality; the smaller the better. Look at the Debian installed package sizes for hints, but be aware that sometimes larger packages include lots of documentation, which is a good thing.
- async event framework
- libevent - the original event loop library.
- libev - the new event loop library which is faster, with slightly more functionality.
- datastructures
- glib - good datastructures, but bundled with libs for eventloops, logging, memory, errors, threads, etc. If you drink this cool-aid you don't really need many other libraries, but your code will not look like normal C.
- TLS secure network transport
- openssl
- gnutls
- CyaSSL?
- stunnel
- stud
- SASL secure authentication
- cyrus-sasl
- gsasl
- cyrus saslauthd
I've decided that the libs to use are libev, glib, gnutls (or stud in the beginning), and gsasl.
So that anyone can see users/groups, /etc/passwd and /etc/group are world readable. Historically these used to contain crypt passwords, relying on the crypt security to protect users passwords. This makes dictionary attacks too easy, so /etc/shadow and /etc/gshadow were created readable only by root to contain the crypted passwords. This way only root has access to the crypted passwords for doing auth.
LDAP can export data with or without TLS encryption. Originally TLS was done by serving ldaps:// through a secure tunnel on another port, but now LDAP supports a StartTLS? command to turn on encryption in the middle of an LDAP session.
When authenticating with an LDAP server there are several alternatives. The original simple BIND sends the password in plaintext to the LDAP server. This is a security hole without TLS on an untrusted network, so SASL was added, which supports several auth methods including challenge-response auth that doesn't send the plaintext passwd over the wire. The problem with challenge-response protocols is they require the server to know the plaintext passwd. See the following;
http://www.ldapguru.info/ldap/authentication-best-practices.html
We want to use /etc/shadow passwords which are crypted, so we can't use SASL challenge-response auths like DIGEST-MD5. Note that things like smtp auth uses SASL PLAIN over TLS, which is the same level of security as simple BIND over TLS.
This means SASL adds nothing over simple BIND for our purposes. The only reason to add SASL support would be for clients that insist on using SASL BIND, and then we can only support SASL PLAIN. Note that entente already supports simple BIND using pam.
Client machines can use ldap for users/groups 2 different ways;
Note that to bind to the ldap port, the ldap server needs to start as root, but can drop privileges after that if it doesn't need /etc/shadow read access.
See http://github.com/dbaarda/LightLdapd for the latest sources.
This was forked and renamed from http://github.com/urbanserj/entente after submitting several improvements and cleanups. The fork was done with the approval blessing of the entente author so that entente could remain a good example of a bare minimum LDAP server.