Unix Identity and Access Management

A brief history

Identity and Access Management (IAM) historically consists of the three A’s

  • Authentication
    • What acccount is being accessed?
  • Authorization
    • Is this account allowed access to this machine?
  • Access Control
    • What resources are you allowed to use?

On top of this we may also need to consider

  • Auditing
    • Log the attempt to use the machine
  • Provisioning
    • How does the account get onto the machine?

“Access Control” is not directly under control of IAM. In the unix world this is defined by group permissions on files (group membership is part of IAM), ACLs and so on. For this blog entry I’m going to ignore it… mostly.

Let’s call the result (excluding Access Control) AAAP.

Historical Unix

In Unix we started pretty simple. We had the password file /etc/passwd. The second field of this was a one-way encryption using your password as the key. The AAAP answers are now simple:

  • Authentication
    • Did you enter the right password?
  • Authorization
    • Is the account in the passwd file?
  • Auditing
    • Log to syslog (and maybe elsewhere)
  • Provisioning
    • A superuser added the account.

(This password file also defined your primary group. Another file /etc/group defined your secondary groups; this is where IAM impacts Access Control).

In this world the mere existence of the account was authorization.

Aside: this process still works today in an “out of the box” Linux build. The crypt string has moved into /etc/shadow because the old DES algorithm was eventually too weak and open to simple attacks; a modern machine will use SHA2 instead of DES. But a machine can still be setup so it works just like it did 30 years ago; add the user to /etc/passwd and /etc/shadow and they can login!

Yellow PagesNIS

This started to hit scaling problems. It was OK if you had 1 or 2 machines, but 10? 20? 100? Many organizations started to write simple synchronisation scripts to try and keep the password in sync but these didn’t scale too well.

In the ‘80s Sun Microsystems invented a solution called “Yellow Pages”. Eventually (due to British Telecom trademark issues) it got renamed NIS (Network Information Services). Now what NIS did was to create a network version of the password file (and other files, out of scope for this discussion). You can add a user to the central map and it will show up on every machine. Scaling solved!

A new problem showed up; you may not want every user to login to every machine. So NIS also included the concept of a “netgroup”. You could create a netgroup called “sa_team” and put the SAs into it. Another netgroup could be called “dba” and your Oracle DBAs go into that. Developers could go into “dev”.

Now your passwd file consists of users, as before, and @netgroup entries. So every machine would have @sa_team but only the Oracle servers would have @dba. AAAP now reads:

  • Authentication
    • Did you enter the right password?
  • Authorization
    • Is the account in the passwd file or in an included netgroup?
  • Auditing
    • Log to syslog (and maybe elsewhere)
  • Provisioning
    • A superuser added the account or a netgroup.

There’s still a scaling issue (every machine needs to be configured for the right netgroups) but this is normally a one-off event or easily scripted event. You don’t need to touch hundreds of servers every time someone leaves or joins.

As a technology NIS had a number of security issues (e.g. spoofable, allowed the crypt strings to be seen) but the ideas worked well. Similar ideas still persist today, using LDAP instead of NIS. (We’ll not talk about NIS+ and pretend it never existed).

PAM and NSS

What more do you need?

Flexibility.

Until now every program needed to know about all the backends. The programs like login/ftp/telnet/rsh on a SunOS machine all knew about NIS. But that’s all they knew. You couldn’t add a new backend without replacing every “front door” program.

Starting in Solaris 2.5.1 and made better in Solaris 2.6, Sun created a new structure “PAM” - Pluggable Authentication Modules. Modern Linux also has PAM. Even AIX now has PAM (after going down its own path for a while).

PAM and its partner NSS (Name Service Switch) are (at first glance) a complicated process. They splits out something that was done by the passwd file into two separate sections:

  • Naming Services
  • Authentication/Authorization

Naming services are handling things like “what UID is login fred?” “What account is uid 12345?“. NSS allows for different backends (the local passwd file; a NIS server; an LDAP server; a MySQL database…). It takes what Sun created in the early NIS days and improves it to an API so every program doesn’t need to know how to talk to every backend; they call (via libc) a common stack. This turns out to be very powerful and persists today.

PAM is where things get more interesting. Historically we’ve seen that “authorization” was simply based on a simple rule such as “are you in the passwd file or an included netgroup”. PAM potentially allows any rule to be defined; “Harry can login from these machines between 9am and 5pm”; “Fred must use an RSA token to login”. Normally you wouldn’t go to these extremes (you’d use “role based” rules - I’ll cover this in a later blog) but because the rules are now programmable you can do everything.

It also opens up a difference between traditional unix and modern unix. Previously if you were in the password file then you were authorized. “id fred” was enough to tell you if you had an account.

Now PAM may deny you access even if you exist. “id fred” may say that Fred has a login, but PAM may still deny him.

AAAP gets more complicated:

  • Authentication
    • Does NSS say your account exist? Do the pam “auth” rules say the right credentials have been provided?
  • Authorization
    • Do the pam “account” rules permit this login at this time from this machine with this credential?
  • Auditing
    • Log to syslog (and maybe elsewhere)
  • Provisioning
    • Are you in the datastores queried by NSS?

All is not good in paradise

We can now handle lots of things. What could possibly go wrong?

Auditing is traditionally just syslog. Remote syslog is unreliable (UDP packet loss) or insecure (TCP packet sniffing). Authentication logs should be considered high risk; who hasn’t mistakenly entered their password into a login prompt? “Failed login for mypasswd on ttya”; “successful login for fred on ttya”… can you guess Fred’s password?

So audit logging needs to be handled better.

Then there’s the provisioning stage; how are the rules for NSS and PAM setup and maintained?

A common setup is to allow “passwd: files ldap” (or similar). This means “look in the local passwd file first; and if the user isn’t found look in LDAP”. So far so good. But this means that an SA could add “myacct” to the passwd file and login with that.

What happens when that SA leaves? We may delete his LDAP account, but “myacct” is still there”.

A number of organizations with an IAM function (e.g. banks, pharma) have a “separations of duties” control structure. One team controls access (an IAM team) and another machine controls the machine (the SA team). If the SA team can add users then we have a separation violation.

We’ll deal with this problem in a later blog. This is where IAM gets “interesting”.

Summary

Modern Unix systems use PAM and NSS to control access to machines. In their default configuration they look just like a machine from 20 years ago; add user to /etc/passwd and crypt string to /etc/shadow and the user can login (if it wasn’t for /etc/shadow then this would be 30 years ago).

But they are a lot more flexible and can do a lot more than that. Want single signon from your windows desktop to the linux machine (no need to enter your password!)? The PAM kerberos module can help. Want to pull in usernames and groups from your Active Directory tree? NSS is the answer.

PAM and NSS allow you to write code that’ll do almost anything you want.