denismo / aws-iam-ldap-bridge Goto Github PK
View Code? Open in Web Editor NEWAccess to the AWS IAM accounts via LDAP
License: Apache License 2.0
Access to the AWS IAM accounts via LDAP
License: Apache License 2.0
At the moment the ApacheDS instance needs to be configured manually before it can be used with IAM. In simple cases, an embedded ApacheDS can be started which will self-configure with reasonable defaults and all it needs is keys (or it even can be instructed to use Role credentials if this is running on AWS EC2).
Users who have been set up with multi-factor authentication (MFA) can't authenticate against the LDAP. I'm not sure if the password supplied needs to be formatted to include the MFA code, or another api call needs to be implemented for this feature.
Current build artifact is hosted on s3 in the ap-southeast-2 region. Would be useful to have this available through github for:
The role logins are currently enabled (experimentally). However they pose a huge security risk so they are better be disabled until the risk is cleared.
latest AWS CLI supports using EC2 instance metadata as credential source together with a role with following fashion:
[profile crossaccount]
role_arn=arn:aws:iam:...
credential_source=Ec2InstanceMetadata
This profile could be even default. The current implementation does not support using this enhanced configuration, but uses the default AWS instance credentials even if default profile is configured to use one.
Using the cli with the apacheds user from shell work ok, but apacheds error message reveals that it is using the default instance profile and not assumed role:
[18:09:26] ERROR [com.denismo.aws.iam.LDAPIAMPoller] - Exception polling
com.amazonaws.AmazonServiceException: User: arn:aws:sts::xxxxxxxxxxx:assumed-role/EC2/i-0aaa93ab6076d35ce is not authorized to perform: iam:ListGroups on resource: arn:aws:iam::yyyyyyyyyyyy:group/ (Service: AmazonIdentityManagement; Status Code: 403; Error Code: AccessDenied; Request ID: c708e7cd-d6ee-11e8-bd77-49651db80edb)
using from shell with CLI and only default profile
apacheds@ip-10-0-1-210:~$ aws iam list-users
{
"Users": [
{
"UserName": "[email protected]",
"PasswordLastUsed": "2018-10-17T06:48:44Z",
"CreateDate": "2018-01-09T09:11:15Z",
"UserId": "TBD",
"Path": "/",
"Arn": "arn:aws:iam::yyyyyyyyyyyy:user/[email protected]"
},
...
If a new group is added in IAM, and an existing user is added to this group, the group will appear in the LDAP but with no users in it. Additionally, if a user is removed from a group in IAM, LDAP does not update the group to show that the user is removed from it.
Is there a setting in iam.ldif or /etc/iam_ldap.conf that I'm missing?
as opposed to a Secret Key.
I have used the provided ami to run ApacheDS + the IAM-LDAP bridge code. I updated the ~/apacheds directory to the latest apacheds-0.2.1.zip and created a /etc/iam_ldap.conf with "validator=iam_password". In my system, I have 10 IAM users of which 5 have passwords and 2 have access keys.
When it runs, I see 10 IAM users in my system. The first bug is that the service should check to see if the IAM user has a password and skip if it is not there. There should only have been 5 users imported.
The second bug is that after a while, the sync runs again, and the users that have no access key are deleted from the system. A typical apacheds.log entry is as follows:
[00:04:12] ERROR [org.apache.directory.api.ldap.model.entry.Modification] - ERR_04472 The attribute 'accesskey' is incorrect [00:04:12] ERROR [com.denismo.aws.iam.LDAPIAMPoller] - Exception processing user potal java.lang.NullPointerException at org.apache.directory.server.core.normalization.NormalizationInterceptor.modify(NormalizationInterceptor.java:211) at org.apache.directory.server.core.DefaultOperationManager.modify(DefaultOperationManager.java:883) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:629) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:594) at com.denismo.aws.iam.LDAPIAMPoller.addUser(LDAPIAMPoller.java:527) at com.denismo.aws.iam.LDAPIAMPoller.populateUsersFromIAM(LDAPIAMPoller.java:473) at com.denismo.aws.iam.LDAPIAMPoller.pollIAM(LDAPIAMPoller.java:220) at com.denismo.aws.iam.LDAPIAMPoller.access$000(LDAPIAMPoller.java:77) at com.denismo.aws.iam.LDAPIAMPoller$1.run(LDAPIAMPoller.java:600) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) [00:04:13] ERROR [org.apache.directory.api.ldap.model.entry.Modification] - ERR_04472 The attribute 'accesskey' is incorrect [00:04:13] ERROR [com.denismo.aws.iam.LDAPIAMPoller] - Exception processing user tborger java.lang.NullPointerException at org.apache.directory.server.core.normalization.NormalizationInterceptor.modify(NormalizationInterceptor.java:211) at org.apache.directory.server.core.DefaultOperationManager.modify(DefaultOperationManager.java:883) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:629) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:594) at com.denismo.aws.iam.LDAPIAMPoller.addUser(LDAPIAMPoller.java:527) at com.denismo.aws.iam.LDAPIAMPoller.populateUsersFromIAM(LDAPIAMPoller.java:473) at com.denismo.aws.iam.LDAPIAMPoller.pollIAM(LDAPIAMPoller.java:220) at com.denismo.aws.iam.LDAPIAMPoller.access$000(LDAPIAMPoller.java:77) at com.denismo.aws.iam.LDAPIAMPoller$1.run(LDAPIAMPoller.java:600) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) [00:04:13] ERROR [org.apache.directory.api.ldap.model.entry.Modification] - ERR_04472 The attribute 'accesskey' is incorrect [00:04:13] ERROR [com.denismo.aws.iam.LDAPIAMPoller] - Exception processing user tgumto java.lang.NullPointerException at org.apache.directory.server.core.normalization.NormalizationInterceptor.modify(NormalizationInterceptor.java:211) at org.apache.directory.server.core.DefaultOperationManager.modify(DefaultOperationManager.java:883) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:629) at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:594) at com.denismo.aws.iam.LDAPIAMPoller.addUser(LDAPIAMPoller.java:527) at com.denismo.aws.iam.LDAPIAMPoller.populateUsersFromIAM(LDAPIAMPoller.java:473) at com.denismo.aws.iam.LDAPIAMPoller.pollIAM(LDAPIAMPoller.java:220)
Hi, I am trying to use Apache Directory Studio to clean up some of the security settings and use this solution with SSSD. Using Apache Directory Studio UI, I can connect to the directory and browse the directory. However, when I want to open the configuration (right click on the connection and chose 'Open Configuration' I get a failure saying that ATTRIBUTE_TYPE for OID pollperiod does not exist. I remove the pollPeriod attribute from the object that had it, then it fails with the same error on the rootDN.
I thought I found the problem, in the iam.ldif file, I think there is a typo, where instead of ou=schema, cn=iam, the rootDN and the pollPeriod both have ou=schema,cn=adsconfig. However, I moved these attributes to under the iam, but I am still getting the same error.
It is advised that you not try to configure ApacheDS by hand (as it is very error prone), but because of this problem I can not use the interface.
Do you have any advice here?
Hi,
I'm using version 0.2.2
addUser() method in LDAPIAMPoller.java makes bug when user doesn't have an accesskey.
Modification failure would delete the entity, and next schedule create it again.
if (accessKey == null) {
if (AWSIAMAuthenticator.getConfig().isSecretKeyLogin()) {
LOG.debug("User " + user.getUserName() + " has no active access keys");
return;
} else {
accessKey = ""; // empty accessKey makes null pointer exception.
}
}
Entry existingUser = getExistingUser(user);
if (existingUser != null) {
directory.getAdminSession().modify(existingUser.getDn(),
new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "accessKey", accessKey),
new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "gidNumber", group.get("gidNumber").getString())
);
// TODO If gidNumber changed for user, shouldn't groups memberUid list be updated?
updateUserMemberOf(existingUser, otherGroups);
return;
}
below exception occurred.
[10:34:33] ERROR [org.apache.directory.api.ldap.model.entry.DefaultAttribute] - ERR_04449 The value '' cant be normalized, it hasn't been added
[10:34:34] ERROR [org.apache.directory.api.ldap.model.entry.Modification] - ERR_04472 The attribute 'accesskey' is incorrect
[10:34:34] ERROR [com.denismo.aws.iam.LDAPIAMPoller] - Exception processing user d.ga#####
java.lang.NullPointerException
at org.apache.directory.server.core.normalization.NormalizationInterceptor.modify(NormalizationInterceptor.java:211)
at org.apache.directory.server.core.DefaultOperationManager.modify(DefaultOperationManager.java:883)
at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:629)
at org.apache.directory.server.core.shared.DefaultCoreSession.modify(DefaultCoreSession.java:594)
at com.denismo.aws.iam.LDAPIAMPoller.addUser(LDAPIAMPoller.java:548)
at com.denismo.aws.iam.LDAPIAMPoller.populateUsersFromIAM(LDAPIAMPoller.java:473)
at com.denismo.aws.iam.LDAPIAMPoller.pollIAM(LDAPIAMPoller.java:220)
at com.denismo.aws.iam.LDAPIAMPoller.access$000(LDAPIAMPoller.java:77)
at com.denismo.aws.iam.LDAPIAMPoller$1.run(LDAPIAMPoller.java:645)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
ModificationOperation maybe doesn't allow empty string.
Best Regards,
For simple cases, one does not need anything but an instance with Java + ApacheDS, configured to load the users/groups from IAM. It will be a standalone ApacheDS mostly suitable just for this use case (it can be configured further if necessary).
Right now it looks very slow, about a second per account
* aws_instance.ldap: Error launching source instance: InvalidAMIID.NotFound: The image id '[ami-d19df4eb]' does not exist
status code: 400, request id:
Is there a new AMI available or we have to bake this ourselves?
Enable TLS by default Disable anonymous bind
Hello,
I am trying to set up an EC2 instance as a central machine that manages and controls access to all my other EC2 instances.
Do I need to first install LDAP server on this and then use your plugin?
Regards,
Jyothi
Your project seems interesting, however I've tried both your AMI based in sydney and when following the Install instructions the ldapsearch command is not found
I've also tried to download the binarys but the instructions are unclear on how to expand the files.
Once I've extracted (both to tmp and then to the root directory, and even run the script from the install script - although I didn't see the necessity of removing all the ssh keys and then wiping your history of doing so) it still could never find the ldapsearch command.
I even tried echo $PATH and ldap search never appeared there or in /bin
I did get it to ldapsearch to work after installing openldap-clients vi yum
then changed to the instance ip and saw my IAM usernames populated. on the screen.
I then went to the /home but only saw the ec2 user directory.
I went into the sshd config and allowed for passwords and with my test user whom I saw come down on the list tried to log in with via ssh but was denied.
I'd like to help you get the bugs worked out of this project, but java isn't my best language.
Hello there,
First and foremost, thank you very much for creating this bridge.
I git cloned the src code and built it via "ant dist".
Moved the newly built binary into a different folder and then started it like this:
sudo bash $ADS_HOME/bin/apacheds.sh start
Was able to change the password from admin to something else.
Seems as if the anonymous bind alongwith admin bind works but not user bind.
e.g.
ldapsearch -H ldap://localhost:10389 -D "uid=admin,ou=system" -x -w password -b "dc=iam,dc=aws,dc=org" "(cn=jdoe)"
returns a list of entries
but
trying it like this:
ldapsearch -x -D "uid=jdoe,ou=users,dc=iam,dc=aws,dc=org" -W -H ldap://localhost:10389/ -b "ou=users,dc=iam,dc=aws,dc=org" -s sub 'uid=jdoe'
Enter LDAP Password:
ldap_bind: Invalid credentials (49)
additional info: INVALID_CREDENTIALS: Bind failed: ERR_229 Cannot authenticate user uid=jdoe,ou=users,dc=iam,dc=aws,dc=org
Is there a configuration setting or a change in the source code which allows user binds when building apacheds with your iam / aws integration code?
This project seems very interesting and been thinking of couple use cases for this already.
One challenge I've ran into is that the ApacheDS does not have MemberOf overlay that would benefit many group related authorizations on the client side.
Alternatively ability to just import identities on group basis would be acceptable workaround.
On securing my instance I've modified the config file to bind the service to loopback address as in my scenario I don't want to build a central directory, but have each server their own directory. This takes care of most of the security challenges as you would need access to the host in order to compromize anything and I'm using not the directory to grant access to the host but authorizing identities to use an application running on the host.
Teemu
Hi, denismo
in src/com/denismo/apacheds/ApacheDSUtils.java after loaded iam.ldif
if (!utils.exists("cn=config,ads-authenticatorid=awsiamauthenticator,ou=authenticators,ads-interceptorId=authenticationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config")) {
Entry entryIAM = service.newEntry( service.getDnFactory().create("cn=config,ads-authenticatorid=awsiamauthenticator,ou=authenticators,ads-interceptorId=authenticationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config") );
entryIAM.put("objectClass", "iamauthenticatorconfig", "top");
entryIAM.put(SchemaConstants.ENTRY_CSN_AT, service.getCSN().toString());
entryIAM.put(SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString());
entryIAM.put("cn", "config");
entryIAM.put("idGenerator", "1000");
service.getAdminSession().add(entryIAM);
}
I was wondering why not wirte this cn into iam.ldif file?what is the meaning for this check?
Ideally, the logged in user should be able to continue acting under their credentials on the logged in machine.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.