OpenSSH and PAM
Hello!
I try to authenticate the ssh user via PAM using FreeRadius. So the setup is: SSH client --> [SSH server <- PAM -> FreeRadius Client] --> FreeRadius Server (storing user accounts) I found that Openssh will set the password to "\b\n\r\177INCORRECT" if the user is not specified in /etc/passwd (see auth-pam.c). So when the FreeRadius client attempts to retrieve the password using pam_get_item, it will get the hardcoded bad password. All of the user accounts are stored in the FreeRadius server. I don't want to have another set of username stored in the Radius client machine. Is there an easy way to workaround on this? Thanks a lot!!!! |
Which version of OpenSSH? In 5.8p2, there are two places where the hardcoded bad password is assigned. In both auth-pam.c:839:sshpam_respond() and auth-pam.c:1200:sshpam_auth_passwd() it happens only if the context is invalid (!authctxt->valid) or if the account is root but root login is not permitted. As far as I can see, OpenSSH 5.8p2 uses getpwnam() to determine the user account; and that of course uses PAM. I cannot see the behaviour you describe; the authentication context is based on information correctly obtained via PAM, and not from local files. Are you sure you have the correct OpenSSH port?
The majority of systems I use would not work if OpenSSH required the user to be in /etc/passwd. (Typically, only service user accounts are in /etc/passwd, local administration groups in /etc/group, and all users defined and authenticated via PAM (usually LDAP and AD).) I suspect you have a problem in the PAM config on the SSH server machine. Does e.g. id -u someuser output the user ID for a FreeRadius user? It should. I'm personally not that familiar with Radius authentication, so hopefully someone with experience with FreeRadius can help you with that. (On the other hand, the documentation and config example at the FreeRadius web site does look relatively straightforward.) |
Quote:
Quote:
If the username is specified in /etc/passwd, e.g. sshuser::638:638::/home/sshuser:/bin/bash. The username and password entered by the user in the SSH client will be passed to the FreeRadius server (use pam_get_item to get the password) to authenticate and we can successfully login if the user credential exists. Otherwise, the username entered by the user and the hardcoded password "\b\n\r\177INCORRECT" will be passed to the FreeRadius server and thus the login fails. Quote:
|
Quote:
Code:
auth sufficient /lib/security/pam_radius_auth.so Based on LDAP configurations known to work, I personally would use Code:
auth sufficient pam_unix.so In my config, local user accounts are sufficient. pam_unix.so should prompt for a password if necessary (if no password has been supplied to the PAM stack yet). FreeRadius user accounts are sufficient too (although local users are checked first). use_first_pass tells pam_radius_auth.so to use the already prompted for password, and not prompt for yet another one. If neither of the above succeeded, the auth fails. Could you try this modified configuration, and see if this works? |
Thank you for your response! Unfortunately, I am still struggling how to make it work with your suggestion.
Quote:
Quote:
What Radius does is fairly straight-forward, i.e.: 1. Get the username using pam_get_user 2. Get the password using pam_get_item 3. If the password is provided in the first place, it will use those username and password 4. If the password is NOT provided, it will wait for the user to enter the password using pam_conv, i.e. Code:
retval = pam_get_item(pamh, PAM_CONV, (CONST void **) &conv); So the configuration you suggested will get to step 1, 2 and 3 where password is null. I am not familiar with SSH source code at all. I don't understand at which point in time SSH server will update the password if the user is not in /etc/passwd. Do you have any other suggestions? Thanks!!! |
Quote:
You could try inverting the stacking order, i.e. Code:
auth sufficient pam_radius_auth.so Quote:
Quote:
Your problem is that your PAM configuration, for some reason, is not satisfied by the pam_radius module alone. Have you noted that the configuration files may contain @include diretives? While the configuration for the OpenSSH daemon is in /etc/pam.d/sshd, the file usually contains @include common-auth to include /etc/pam.d/common-auth file, which contains the authentication for all services. I apologise if I am repeating things you already know well; I only wish to make sure we both have the entire picture. What I do not know, is whether the FreeRadius server provides the user information (user ID, group IDs, GECOS or attributes) like UNIX user accounts and LDAP do. If it does, then you could start by replacing /etc/pam.d/sshd with just Code:
auth required pam_radius_auth.so After the above works, you can continue by replacing the auth line with Code:
auth sufficient pam_radius_auth.so Finally, when you are sure it works, move the auth config from /etc/pam.d/sshd to the common files, so that all services use the same configuration by default. It might not seem like very important right now, but it is; one uses PAM services surprisingly often. Consider sudo for example: if it does not share the auth config, your Radius users cannot use sudo. (Furthermore, the superuser cannot do operations via sudo as a Radius user.) I would be extremely interested in whether the basic four-line /etc/pam.d/sshd configuration works. Also, you did not yet tell me whether id -u sshuser works when sshuser is a Radius user not mentioned in /etc/passwd nor /etc/shadow? If it does, then the user information is obtained from the Radius service. If it does not work, then user information is not obtained from the Radius service. |
Thanks for your reply!
Quote:
Quote:
Code:
#%PAM-1.0 Code:
#%PAM-1.0 Code:
UsePAM yes Quote:
Does it mean that the pam_radius_auth module uses linux pam incorrectly? Thanks!!! |
Just to verify, if you replace /etc/pam.d/sshd with
Code:
#%PAM-1.0 Quote:
According to a recent post by the developer, I think pam_auth_radius alone cannot provide the necessary information. I could be wrong, though. It may be that you just have not specified the user ID, group ID, and optional supplementary group IDs to the FreeRadius server. Everything I've seen thus far indicates you should consider using LDAP instead. If you need Radius for something specific, you can always use FreeRadius with the same LDAP configured as a backend: basically, you can still use FreeRadius for passwords and accounting, but keep the user information (posixAccount) in LDAP. This seems to be quite a common configuration, but if you do not specifically need the Radius accounting stuff, you could simplify things and go with LDAP alone. Personally, I find the Radius network protocol dangerous (the passwords are only secured by the static secret); I believe SSL/TLS-secured LDAP connections are orders of magnitude more secure. Another option is to write a set of simple scripts to "push" the Radius user account information (/etc/{passwd,group,shadow,gshadow} from a centralized location. You do not want to simply replace the files, you need a merge script on the receiving end to modify only the Radius entries. It's not too complicated with Bash and awk, for example. Basically, you "reserve" (logically, not technically) a range of user and group ID's for Radius users, say 30000-40000. Periodically, or when the user set changes, each machine retrieves the user and group lists from a centralized server, then modifies their local files accordingly. (Retrieving is easiest to do using scp and a dedicated user account, using public keys to authenticate between machines.) I'm sure I and others can help you with this, if you decide to go this route; just start a new topic in the Programming forum. |
Thanks for your great help! I had a better idea of OpenSSH now.
Quote:
PC1: OpenSSH server and PAM-capable FreeRadius client PC2: FreeRadius Server (with user accounts) If the user accounts are not specified in PC1, I am just curious normally how a FreeRadius client or PAM-capable client should provide the user ID, group ID, and optional supplementary group IDs so that SSH can pick them up. Is that once the FreeRadius client receives the user ID from SSH server, it should create a user temporarily in /etc/{passwd,group,shadow,gshadow} in runtime? If so, would it be "too late" because SSH cannot find the user information until the pam_radius_auth kicks in? What is the proper way to deal with this? Thanks A LOT!!! |
Quote:
Check out this post by the pam_auth_radius maintainer (Alan DeKok) on the freeradius-users mailing list: The missing bit is a Radius NSS module (Name Service Switch module) that would provide the necessary account information. NSS is implemented as a dynamic library (even for static binaries!) in systems using the GNU C library. For proper privilege separation (and keeping the shared secret secret) the module would have to be in two parts: a dynamic library part, which connects to a locally-running daemon. The daemon would know the shared secrets, and do the communication with the Radius server. However, Radius and NSS designs are at odds. Radius basically keys everything off based on the user name, but NSS identifies users and groups based on ID (numbers); names are just string labels. It might be workable to just cache and occasionally re-query the Radius server about users that have ever logged in to a machine, but it would be pretty much a hack: it would not work well if there are shared filesystems (since the cached user information may not contain all users). Technically, the Radius server would need to have a special Login-Service that would always succeed (ignoring the supplied password), but would specify the user information in Vendor-Specific attribute in the response, say format UID:GID:Supplementary-GID(s):GECOS: where the UID and GID(s) can be either numeric or local user/group names for mapping. In other words, Radius alone is not going to cut it. Even if you invested (time) to develop an NSS module, it would be limited compared to LDAP. It is therefore no surprise that many use LDAP in addition to (or as a backed to) FreeRadius, at least storing the user account information in the LDAP database (posixAccount objects). Or, as I stated earlier, use scripts to maintain the user account information in files, from a centralized location. My suggestion to you is therefore to install OpenLDAP alongside FreeRadius, and perhaps modify FreeRadius to use LDAP as the backend. Or, if you do not need Radius features, just discard FreeRadius altogether for a simpler LDAP scheme. |
All times are GMT -5. The time now is 08:20 AM. |