tacacs+ for Linux authentication/authorization using pam_tacplus - linux

I am using TACACS+ to authenticate Linux users using pam_tacplus.so PAM module and it works without issues.
I have modified the pam_tacplus module to meet some of my custom requirements.
I know by default, TACACS+ does not have any means to support linux groups or access level control over linux bash commands, however, I was wondering is there any way that some information could be passed from TACACS+ server side to let the pam_tacplus.so module which can be used to allow/deny , or modify the user group on the fly [from pam module itself].
Example: If I could pass the priv-lvl number from server to the client and which could be used for some decision making at the PAM module.
PS: I would prefer a method which involved no modification at the server side [code], all modification should be done at Linux side ie pam_tacplus module.
Thanks for any help.

Eventually I got it working.
Issue 1:
The issue I faced was there is very few documentation available to configure TACACS+ server for a non CISCO device.
Issue 2:
The tac_plus version that I am using
tac_plus -v
tac_plus version F4.0.4.28
does not seem to support
service = shell protocol = ssh
option in tac_plus.conf file.
So eventually I used
service = system {
default attribute = permit
priv-lvl = 15
}
On the client side (pam_tacplus.so),
I sent the AVP service=system at authorization phase(pam_acct_mgmt), which forced the service to return priv-lvl defined at the configuration file, which I used to device privilege level of the user.
NOTE: In some documentations it is mentioned that service=system is not used anymore. So this option may not work with CISCO devices.
HTH

Depending on how you intend to implement this, PAM may be insufficient to meet your needs. The privilege level from TACACS+ isn't part of the 'authentication' step, but rather the 'authorization' step. If you're using pam_tacplus, then that authorization takes place as part of the 'account' (aka pam_acct_mgmt) step in PAM. Unfortunately, however, *nix systems don't give you a lot of ability to do fine grained control here -- you might be able to reject access based on invalid 'service', 'protocol', or even particulars such as 'host', or 'tty', but probably not much beyond that. (priv_lvl is part of the request, not response, and pam_tacplus always sends '0'.)
If you want to vary privileges on a *nix system, you probably want to work within that environments capabilities. My suggestion would be to grouping as a means of producing a sort of 'role-based' access controls. If you want these to exist on the TACACS+ server, then you'll want to introduce custom AVP that are meaningful, and then associate those with the user.
You'll likely need an NSS (name service switch) module to accomplish this -- by the time you get to PAM, OpenSSH, for example, will have already determined that your user is "bogus" and send along a similarly bogus password to the server. With an NSS module you can populate 'passwd' records for your users based on AVPs from the TACACS+ server. More details on NSS can be found in glibc's documentation for "Name Service Switch".

Related

With WebAuthN is it possible to deny certain types of authentication methods FIDO2)

When using WebAuthN (https://w3c.github.io/webauthn/) to authenticate, is it possible to hide certain authentication options?
For example, when testing on webauthn.io, my android device shows available authentication types like hardware keys, Bluetooth, and fingerprint. Is it possible for me to configure it somehow to not accept hardware keys and bluetooth.
Also, when selecting and using my fingerprint to login, if I force it to fail by using the wrong finger, it defaults to then asking for my unlock pattern and if I enter my unlock pattern, I still get a success. In my opinion an unlock pattern is not secure as a dirty screen leaves the pattern on the screen with a smudge mark. Also parents give the pin to children. Can I stop this behaviour and if the fingerprint fails error instead?
Not an expert but this is what I discovered when I recently implemented WebAuthn/FIDO2 support in our identity provider:
authenticatorSelection.authenticatorAttachment - When you create the request for navigator.credentials.create() you can specify whether it should use platform (i.e. built-in biometric/PIN) or cross-platform (e,g, an external USB/BT/NFC device). Note this just gives the user agent a hint about what you're after.
authenticatorSelection.userVerification - set this to required and it will require the user of an additional factor beyond mere verification of presence - i.e. a PIN or biometric challenge
Attestation - A FIDO2 compliant device can provide attestation information that can be verified via the Metadata Service. This will expose the capabilies of the device and you can base policy on that. E.g. you could insist that it must use tamperproof hardware to protect the private key.
Authentication result - can provide information about how the user was verified so you could build a policy around that. The spec for this extension is here: https://www.w3.org/TR/webauthn/#sctn-uvm-extension
The recommenation is not to specifically black/white-list devices yourself but the MDS does support revocation of certification and that should be respected by relying parties.

What information is needed to write an abstract LDAP Integration Service

I've been tasked with researching/writing an LDAP integration module to support any/all clients that use local LDAP authentication for our new app. As I've never worked with LDAP before, I'm trying to figure out what settings are required/not required, and what settings I'd need to capture from each LDAP system to be able to support them all. So if I'm storing data in a database about each LDAP server, what is needed about that server to be able to successfully auth with a username/password?
I see lots of ou/cn/dc references, but sometimes people don't use them in their connection strings? And unless pre-registered, it seems like I'd have no way of knowing the names of the groups/categories to query against. I was thinking about the SAML spec and was curious if LDAP systems have an endpoint to retrieve some kind of XML describing their LDAP hierarchy? Or if I'd just need to know/ask for it from a sysadmin in advance?
FWIW I'm using Node/ldapjs
There is no standard way of describing the LDAP hierarchy in the manner you were considering. LDAP is in fact self-describing, you can search for a particular entry regardless of it's position in the LDAP tree by looking up one of its attribute's value.
So, to get started with completely unknown LDAP you only require it's network parameters: hostname, port (and even that can be avoided if you consult SRV DNS records (_ldap._tcp.domain.com)) and authentication details in the form of bind DN and password.
After that you can search for users, typically by looking up with filter like (objectClass=inetOrgPerson), or groups of users with filter like (objectClass=groupOfNames). Then you would use common attributes such as username, CN or displayName to reference or display the users in the user interface.
As you can see from this LDAP servers are very self defining and this ideally works for most LDAP servers, but as you perceived in your question it can differ from one LDAP server to another.
So here is my list of LDAP configuration settings that should be configurable:
hostname/port number (if not using DNS discovery)
username/password (if not using anonymous access)
does the server use SSL (port 636 by default) (or detect support for StartTLS)
user filter and user base DN (e.g. (objectClass=inetOrgPerson) and o=users)
group filter and group base DN (e.g. (objectClass=groupOfNames) and o=groups)
Depending on your use case you could define what attributes are used for displaying the user, mapping them to other parts of your application/system or you could determine those from the returned set of attributes. I've seen implementations that have that very configurable and implementations that default to some standard schema.

Check shibboleth SP session on application level

The question may sound odd, but I have a worst case scenario.
My application server is on http://10.10.10.10/app (say it app-server) and http-apache server is on http://some.dns.com/app (say it http-server). Both are different system-server.
I know app-server shouldn't directly accessible publically, but let's assume it is publically accessible. Now Shibboleth is installed on http-server , securing path http://some.dns.com/app/secure . While one servlet is mapped to get attributes from path /secure.
If someone manages to create fake http-apache-server (say fake-http-server) and that too points to app-server. So here fake-http-server can directly have access to /secure path and that server can manually send shibboleth-like attributes and can login in system without protection.
My question here is, Is there a mechanism in Shibboleth where I can check the shibboleth session in my application - not only in http layer.
The mod_shib Apache module sets environment variables by default. These variables cannot be spoofed by a proxying Apache server.
From the docs:
The safest mechanism, and the default for servers that allow for it,
is the use of environment variables. The term is somewhat generic
because environment variables don't necessarily always imply the
actual process environment in the traditional sense, since there's
often no separate process. It really refers to a set of controlled
data elements that the web server supplies to applications and that
cannot be manipulated in any way from outside the web server.
Specifically, the client has no say in them.
If you don't trust the Apache webserver, you can parse the SAML assertion in your code and validate the signatures in the assertion using the certificate provided by the Identity Provider (IdP) making the SAML assertion. But checking signatures is difficult and you need to deal with cases like key rotation and how to handle new certificates being used by the IdP. Shibboleth handles these very difficult and important tasks for you.

How to restrict Chrome Apps to only work on specific computers?

I'm developing a POS Client using Chrome (packaged) Apps. It will run locally on the installed computers and interact with the server via web service. This app should only run on specific computers at the stores.
I know I can go to each store and install the .crx file in which case I don't have to publish the app to Chrome Web Store. However, I want it to be published to Chrome Web Store so that I can take advantage of its auto-updating feature.
What should I do to make sure that the app can only run at the stores' computers? (I can go the the stores and setup anything needed at the first installation).
Options I have thought of:
Create some secret key and enter it to the app at the first time of running.
Build a small tool (winforms application) to generate time-based tokens and install it on the computers. The staff will need to enter the token each time opening the app.
Any better idea how to accomplish this?
You said the app needs to talk to a web service to work. That's the key to a simple approach. (Assume you don't care whether the staff acquires a nonfunctional copy of the client app.)
At startup, app checks for existence of a validation of some kind stored in chrome.storage.local. If it exists, startup continues.
If the validation is missing, the app checks for existence of a GUID stored in chrome.storage.local.
If the GUID is missing, generate and store one using something like window.crypto.getRandomValues().
Ask the server for a validation by sending the GUID and getting a response.
If a validation comes back, save it in chrome.storage.local and go back to the start of this sequence.
Otherwise tell the user to get lost.
A full-strength version of this approach would have some additional features:
Use an HMAC(GUID, secret) for the validation. I'm assuming the staff aren't tech superstars, so something simple like a boolean would probably suffice.
Optionally add a per-launch step that sends up the GUID and validation and confirms it's still valid each time.
When the validation is requested, you might prompt for the secret key you mentioned in your question. In normal cases this would be needed only at provisioning time.
In case you haven't figured it out yet, the server is now acting like a simple licensing server, so it's up to you to decide how to decide whether the validation request succeeds. Maybe it allows only N validations to exist at once, or after you're done provisioning you hardcode future validations to fail. Maybe it limits validation requests to certain IP addresses. You get to choose.
That's the gist. It's a simple DRM system that is easier to manage than the enter-secret-at-installation method, but that won't withstand an attack of more than 30 minutes (since a smart attacker will just inject another machine's GUID and HMAC validation into the duplicate machine's chrome.storage.local).

Remote access to Cpanel

I would like to enable my users (who are already authenticated in my application) to automatically log into their Cpanel accounts through API.
If I know the password of the specific account, then it will be no problem. However, I do not think that I can retrieve the password of any account? If I can, please tell me which API function to use? If not, what can I do to achieve what I want?
Thanks
Elcin
It looks like cPanel has a method for providing secure remote logins as documented here: http://docs.cpanel.net/twiki/bin/view/AllDocumentation/SecureRemoteLogins
You can find the source for it in /usr/local/cpanel/Cpanel/LogMeIn.pm
I have a PHP implementation of LogMeIn.pm ready to go (easy to understand and port to any other language) but I'm clearing it with the legal folks over at cPanel before I share it.
After speaking with cPanel's VP of Operations, LogMeIn.pm is now dual-licensed allowing modification and use elsewhere as long as a copyright and license notice stays intact.
My PHP port can be found here: https://gist.github.com/4440574 I decided to implement it as a static class to closely resemble the original but you can very easily turn it into a procedural function.
Using it is as easy as
LogMeIn::getLoggedInUrl('username', 'password', 'example.com', 'cpanel');
which will return false on failure, and on success a string with a URL that will log the user in.
If you're running PHP 5.3.0 or greater you can add this to a cPanel namespace (add namespace cPanel; on the line after <?php) to keep it from conflicting with anything in your application that you've already written (or will write).

Resources