I have created one openLDAP server and one client. Now the requirement is to only allow members of some specific LDAP group to do SSH on this client.
Client machine
i can see the LDAP group using 'getent group'
this is my /etc/pam.d/sshd file
%PAM-1.0
account required pam_access.so
auth required pam_listfile.so onerr=fail item=group sense=allow
file=/etc/openldap/sshgroups
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in
the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare
the content of file /etc/openldap/sshgroups:
root
centos
ldap-test-group
but all the LDAP users are able to login to the client machine.
what is wrong here?
Since the accepted answer didn't provide any specific information, I'll provide an example that I was able to come up with. This assumes that you assign users to a unix group "mygroup" which is what controls whether they should log in or not.
In /etc/pam.d/sshd, in an early account line (in my example, the second--after pam_nologin.so), include the following line:
account required pam_access.so
Then in /etc/security/access.conf you can put some lines like:
+:root:ALL
+:localuser:ALL
+:mygroup:ALL
-:ALL:ALL
Which lets users root and "localuser" and anyone in group "mygroup" log in via ssh, but no-one else. Make sure there isn't a user named "mygroup" or your mileage may vary (there are ways to work around the problem). Pro tip: make sure you always leave a way to log in and become root that doesn't depend on LDAP, and test all of this prior adding the -:ALL:ALL rule and don't leave your root shell until you have proved that everything is working the way you want. You do not need to reboot or otherwise reload any configuration files to activate the new configuration. Any new ssh attempt will use the new access policy.
Also note, /etc/security/access.conf might restrict logins other than ssh--sometimes it is used to restrict the (console) login and/or other places where pam_access.so might be referenced--so double check all access mechanisms prior to declaring victory. The last argument in each line controls where the user(s) referenced can come from.
After a lot of hit and trial methods, I was able to get it using pam_access.so and access.conf.
Related
Due to some requirements, a set of machines I use needs to have 2 KDCs defined in /etc/krb5.conf. On top of that, the realm that doesn't contain user principles (just host and service principals) must be specified as the default realm under libdefaults.
The user principals are stored in the other realm and ssh is supposed to work through that realm. The sshd config also uses PAM. In PAM, I've overriden the default realm with realm=MY_SECOND_REALM for the account interface and my ssh logins now work.
The only problem is that my logins now require a password -- each time despite my valid tickets for the MY_SECOND_REALM.
I'm also using sssd. Quite a setup!
Did I miss something simple?
After a few hours of playing with my pam auth modules, I figured out a way to circumvent the problem by using the realm=MY_SECOND_REALM as an argument to the pam_krb line in the account section.
From the pam_krb5 man page:
realm=realm
overrides the default realm set in /etc/krb5.conf,
which > pam_krb5.so will attempt to authenticate users to.
I am working for an IBM Business Partner and I am trying to complete a first PoC ICP installation. The basic installation has worked. I did not configure LDAP during the deployment but I am trying to add an LDAP connection in the console now, afterwards.
Unfortunately, I always fail. And there seem to be a number for limitations and/or bugs in the LDAP connection of ICP to the point of making it unuseable.
First, I would like to connect to an IBM Domino Directory as my LDAP server. Anyone who has worked with a Domino directory before knows that many Domino deployments have an O=Org suffix where Org is a company name containing spaces. For example, in our case it is "O=ARS GmbH". I would normally need to use this as the base DN (search base). However, ICP does not allow spaces in this field ... that need to be fixed! Any other LDAP client product I tried to connect to our Domino directory over many years was able to deal with spaces in the base DN.
Next, in a Domino directory usually the groups do have a different suffix (e.g. search base) than users. But ICP only offers ONE base DN field and not separate base DN fields for users and groups. Any other LDAP client ... DOES offer this. This needs to be fixed in ICP as well.
Next, the bind DN field does not allow some commonly used special characters which are often found in account names, such as the - character. This needs to be fixed as well (as it happens, the special user ID we have in our Domino directory which we use for LDAP binding is named dir-client ...).
Well, after hitting all those blocking problems, I finally tried to connect to our Microsoft Active Directory. This time I could successfully complete the LDAP connection. After doing so, I turned to "Users" and discovered I need to "Import group". However, no matter what I try to enter as (correct) values into the CN and OU fields, I only end up with an "internal server error".
Further more, after I could save the LDAP connection to Active Directory, I could no longer log in to the console with the builtin admin account! But since I could not import any users/groups, I could not assign that role to an LDAP account ... luckily, I had a VM snapshot of the master server and could thus revert to the state before.
This is really frustrating ...
I ran into identical issue when hooking up to an openldap server running in a docker container. It took me awhile to figure out the ICP pod and container where the log file is to get more information than "Internal Server Error".
Here is how to find the relevant ICP pod/container log:
Look for the "auth-idp" pods in the kube-system namespace. I use:
kubectl get pods --namespace=kube-system | grep auth-idp
If you are running an HA cluster, you will have a pod on each master node.
In my case I have 3 master nodes. If you are running only a single master, then you will have only one auth-idp pod.
Again, in an HA scenario, you need to figure out which is your current master node. (The easiest, crude way to do that is ssh to your master VIP and see which node you land on.)
Now figure out which pod is running on the current master node. On each pod I use:
kubectl describe pod auth-idp-vq5bl --namespace=kube-system | grep IP
or
kubectl get pod auth-idp-vq5bl --namespace=kube-system -o wide
The one on the IP that is the current master node is where the log of interest will be.
The container in the pod that has the log of interest is: platform-identity-mgmt
To actually see the log file use:
kubectl logs auth-idp-vq5bl --namespace=kube-system --container=platform-identity-mgmt
At that point you will be able to scroll through the log and see a more detailed error message.
In the case of my error the log indicated my search filter for the group was not working properly. I decided to mess with the user ID map and user filter so I used a user ID map of *:cn and a user filter of: (&(cn=%v)(objectclass=inetOrgPerson)) Once I changed those in the ICP LDAP configuration, the user import succeeded. However, later I realized the logins were not working because the login is based on a search on userid or uid. So I changed the user ID map back to *:uid and the user filter back to (&(uid=%v)(objectClass=inetOrgPerson)). That corrected the login issue. I added some users to my LDAP group and reimported the group and the import worked as well. At this point, I'm not sure what was going on with the original import not working until I messed with the user ID map and user filter. Go figure.
In my OpenLDAP directory instance my groups are all under ou=groups and each group member is listed as, e.g., cn=Peter Van Sickel,dc=ibm,dc=com. I had to edit the group member to get it using the full DN of an actual user.
My users are all directly under the root DN: dc=ibm,dc=com.
As to specific issues with other LDAPs, it is my experience that each has its own set of idiosyncrasies to get things working as desired.
Good day.
I am developing a program that will be used in a corporate environment by the end users. The application will automatically fix certain errors as soon as the user selects the application name, chooses the symptom or error message and clicking on the fix button.
The idea behind is to decrease the amount of calls we receive at the IT Service Desk (The company's personal Call Centre for IT Issues) and at the same time assist the end user by resolving the issue within a minute (versus waiting on the phone for up to 15 minutes or more).
I've am not yet allowed to upload an image of the application, but imagine a small'ish windows form with 2 columns; Aplication name and Synptom. The user will choose the application's name, click on the error message and click on the FIX button. This basically automates whatever we has IT Techs would manually.
The problem I'm facing is that some of the code is supposed to be executed with adminsitartor rights, eg. Stop and Start a given service, adding regsitry entries for Local Machine, etc.
Given the fact that none of the users will be allowed to have elevated rights and the fact that they need to use this application as a sort of "self-help" alternative without the need to call the IT Service Desk, is there a way to give a set of code "administrator permissions"? The application should NOT request the user to enter ANY passwords.
Regards,
Willem
No way, AFAIK: the model in common operating systems is process-centric, so that the process is given permissions that are then inherited by its code. You can elevate such privileges at some point, but that will be for the whole future life of the process (or as long as the authentication token for it ceases to be valid).
In windows the right way to do that is to employ a back-end service: at boot, you start the service called IT_Auto_Fixer_Back_End with high permissions (try to avoid Administrator, NetworkService or LocalService could be enough for you). When the app IT_Auto_Fixer_Front_End is started with USER privileges, it operates until it needs something with high privileges. At that point it sends a request to the service, that will do it.
If you choose this way, some important advices:
The IT_Auto_Fixer_Back_End must not become a backdoor! If you use TCP as form of communication with IT_Auto_Fixer_Front_End, make it listen localhost only and use SSL (yes!) to encrypt local traffic
It must not be possible to invoke arbitrary commands using IT_Auto_Fixer_Back_End. You need to enumerate the possible requests that could be made (i.e. a command like stop_mysql_service rather than accepting directly the string net stop mysql - the application logic will translate your string into the real OS command)
Every input from the user could be used to perform command injection. To prevent this, use the Windows API that requires an array for the command - this way if the user adds options to a command (i.e. the name of the service in net stop) they won't be interpreted as another command (common scenario: when accepting the name of the service as a parameter, a malicious user that tries to execute something like net start mysql ; net user /add hacker t00E4sy). Authentication and encryption will not help you against this, you must escape any user input that goes inside the command.
Sanitize your ENVIRONMENT by using the API that executes commands setting the PATH (and other relevant variables), so that the user will not be able to taint the PATH, executing C:\temp\net.exe instead of C:\Windows\System32\Net.exe
IT_Auto_Fixer_Back_End service should be authenticated: it should check every time if the request comes form the user by checking if the Kerberos token is valid (Windows => you get a very nice Kerberos environment for free!). This will prevent someone else to break into the machine, use SSL to connect to the localhost port and elevate privileges through your service
The above (authentication) still stands when something else (i.e. shared memory, windows sockets, a file, etc...) is used as communication channel between IT_Auto_Fixer_Back_End and IT_Auto_Fixer_Front_End
Life gets harder when you want to properly implement something dealing with multiple level of permissions...
I am using Liferay 6.2 and I am trying to do LDAP Authentication. The LDAP Server is provided by another organization and I do not have access to any configuration, I just have credentials for a system account to look up the directory. When I try to log in Liferay with user credentials from the LDAP Server the authentication fails with the following error code:
13:54:05,738 ERROR [http-bio-8080-exec-3][LDAPAuth:341] Problem accessing LDAP server
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr:
DSID-0315270B, problem 2001 (NO_OBJECT), data 0, best match of:
'O=uni,C=de' remaining name 'ou=people,o=uni,c=de'
The same error that occurs when trying to log in with a user that does not exist in the LDAP directory. Nevertheless, the mapping still works. After trying to log in with valid user credentials there is an entry in the liferay database with the corresponding user data. Accessing Liferay is not possible though.
These are my settings in portal-ext.properties (Test LDAP connections returns success, connection settings are pseudonymised):
ldap.base.provider.url=ldaps://ldap.ldap-server
ldap.base.dn=ou=people,o=uni,c=de
ldap.security.principal=uid=prox,ou=prox,o=uni,c=de
ldap.security.credentials=secret
#auth.pipeline.enable.liferay.check=false
ldap.auth.enabled=true
ldap.auth.required=true
ldap.auth.method=bind
ldap.import.enabled=false
ldap.import.on.startup=false
ldap.import.interval=10
ldap.export.enabled=false
ldap.export.group.enabled=false
ldap.auth.search.filter=(uid=#screen_name#)
ldap.import.user.search.filter=(objectClass=inetOrgPerson)
ldap.attrs.transformer.impl=com.liferay.portal.security.ldap.DefaultAttributesTransformer
ldap.user.mappings=screenName=cn\npassword=userPassword\nfirstName=givenNam\nlastName=sn\njobTitle=title\ngroup=groupMembership
users.email.address.required=false
users.email.address.auto.suffix=#no-emailaddress.com
users.email.address.generator=com.liferay.portal.security.auth.DefaultEmailAddressGenerator
users.email.address.validator=com.liferay.portal.security.auth.DefaultEmailAddressValidator
ldap.password.policy.enabled=false
ldap.import.user.password.enabled=true
ldap.import.user.password.autogenerated=false
ldap.import.user.password.default=test
Check the FQDN on the LDAP side, including the prefixes (cn, ou, etc.), and ensure that it matches the directory configuration within Liferay.
You can try configuring it from the control panel it will be easier for you as it allows to check whether the connection is made or not. You can check the users are fetched or not and it doesnt even need a server restart.
It works now. There were two issues:
I changed ldap.base.dn=ou=people,o=uni,c=de to ldap.base.dn=o=uni,c=de and
ldap.import.user.search.filter=(objectClass=inetOrgPerson) to ldap.import.user.search.filter=(objectClass=*)
I'm building a web API that use a command line on the server.
This command do certain build tasks and it has many optional arguments
I'm not so happy about building a rest API to handle all the arguments and escape/validate all security risk there is...
Is there anyway you could instead whitelist only one command to run by a certain proccess/program or user?
Or can it be as easy as validateing the command if it contains ; if it dose > consider it as unsafe to run?
Or can you create a little sandbox?
You could create a user (login account) on your server that runs your whitelisted command instead of a regular shell when he logs in, if that's what you mean.
For example, I have worked at some sites where there is a user account called "reset" and another called "mountall". So, if you know the password of that account, when you log in, certain databases get reset and you get logged out, or all filesystems in /etc/fstab get mounted and then you get logged out.