- Notifications
You must be signed in to change notification settings - Fork27
Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.
License
aws/credentials-fetcher
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.
This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in -https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements
To use the custom credentials-fetcher rpm in ECS domainless mode, modify the user data script as followshttps://docs.aws.amazon.com/AmazonECS/latest/developerguide/linux-gmsa.html#linux-gmsa-setup
#!/bin/bash# prerequisitesdnf install -y dotnetdnf install -y realmddnf install -y oddjobdnf install -y oddjob-mkhomedirdnf install -y sssddnf install -y adclidnf install -y krb5-workstationdnf install -y samba-common-toolsdnf install -y credentials-fetcher# start credentials-fetchersystemctl enable credentials-fetchersystemctl start credentials-fetcherecho "ECS_GMSA_SUPPORTED=true" >> /etc/ecs/ecs.config echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.configAdd an additional optional field in the secret in AWS Secrets Manager along with the standard user's username, password, and the domain. Enter the service account's Distinguished Name (DN) into JSON key-value pairs called
distinguishedName{"username":"username","password":"passw0rd", "domainName":"example.com", "distinguishedName":"CN=WebApp01,OU=DemoOU,OU=Users,OU=example,DC=example,DC=com"}On Fedora 41 and similar distributions, the binary RPM can be installed as
sudo dnf install credentials-fetcher.You can also use yum if dnf is not present.The daemon can be started usingsudo systemctl start credentials-fetcher.On Enterprise Linux 9 ( RHEL | CentOS | AlmaLinux ), the binary can be installed from EPEL. To add EPEL, see the EPEL Quickstart.Once EPEL is enabled, install credentials-fetcher with
sudo dnf install credentials-fetcher.For other linux distributions, the daemon binary needs to be built from source code.
- Active Directory server ( Windows Server )
- Linux instances or hosts that are domain-joined to Active Directory
- EC2 Linux containers on Amazon ECS provides the option of domainless gMSA and joining each instance to a single domain
- Linux containers on Fargate must use domainless gMSA
- gMSA account(s) in Active Directory - Follow instructions provided to create service accounts -https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts
- Required packages as mentioned in RPM spec file.
- Create username ec2-user or modify the systemd unit file.
- Create a domain joined windows instance
- Install powershell module - "Install-Module CredentialSpec"
- New-CredentialSpec -AccountName WebApp01 // Replace 'WebApp01' with your own gMSA
- You will find the credentialspec in the directory'C:\Program Data\Docker\Credentialspecs\WebApp01_CredSpec.json'
To start a local dev environment from scratch:
* Clone the Git repository.* cd credentials-fetcher && mkdir build* cd build && cmake ../ && make -j && make install * ./credentials-fetcherd to start the program in non-daemon mode.Logs about request/response to the daemon and any failures.
journalctl -u credentials-fetcher| Environment Key | Examples values | Description |
|---|---|---|
CF_KRB_DIR | '/var/credentials-fetcher/krbdir' | (Default) Dir path for storing the kerberos tickets |
CF_UNIX_DOMAIN_SOCKET_DIR | '/var/credentials-fetcher/socket' | (Default) Dir path for the domain socker for gRPC communication 'credentials_fetcher.sock' |
CF_LOGGING_DIR | '/var/credentials-fetcher/logging' | (Default) Dir Path for log |
CF_TEST_DOMAIN_NAME | 'contoso.com' | Test domain name |
CF_TEST_GMSA_ACCOUNT | 'webapp01' | Test gMSA account name |
| Environment Variable | Examples values | Description |
|---|---|---|
CF_CRED_SPEC_FILE | '/var/credentials-fetcher/my-credspec.json' | Path to a credential spec file used as input. (Lease id default: credspec) |
| '/var/credentials-fetcher/my-credspec.json:myLeaseId' | An optional lease id specified after a colon | |
CF_GMSA_OU | 'CN=Managed Service Accounts' | Component of GMSA distinguished name (see docs/cf_gmsa_ou.md) |
Use the AWS CDK to create
- Active Directory Server
- Windows EC2 instance to manage AD
- EC2 Linux Containers on Amazon ECS
- gMSA Account(s) in Active Directory
The CDK will create all necessary infrastructure and install the necessary dependencies to run credentials-fetcher on non-domain-joined ECS hosts. Detailed steps to deploy and test using the CDK stack are presenthere.
/api/tests/gmsa_api_integration_test.cpp contains integration tests for the of the gMSA APIs.
Follow the instructions in theDomainless Mode README to set up the required infrastructure for testing gMSA on Linux containers.
Set AWS environment variables
export AWS_ACCESS_KEY_ID=XXXXexport AWS_SECRET_ACCESS_KEY=XXXXexport AWS_SESSION_TOKEN=XXXXexport AWS_REGION=XXXXSet Amazon S3 ARN containing the credential spec file.
export CF_TEST_CREDSPEC_ARN=XXXSet standard username, password and domain used for testing
export CF_TEST_STANDARD_USERNAME=XXXXexport CF_TEST_STANDARD_USER_PASSWORD=XXXXexport CF_TEST_DOMAIN=XXXXFollow the instructions fromStandalone mode sections to build the code with the integration test flag enabled, generate binaries and start the server. Once the server has started, run integration tests
cd credentials-fetcher/build/cmake -DBUILD_INTEGRATION_TESTS=ON .. && make -j# Start the server from another terminal and run `sudo ./credentials-fetcherd`sudo -E api/tests/gmsa_api_integration_test> sudo api/tests/gmsa_api_integration_test [==========] Running 6 tests from 1 test suite.[----------] Global test environment set-up.[----------] 6 tests from GmsaIntegrationTest[ RUN ] GmsaIntegrationTest.HealthCheck_Test[ OK ] GmsaIntegrationTest.HealthCheck_Test (4 ms)[ RUN ] GmsaIntegrationTest.A_AddNonDomainJoinedKerberosLeaseMethod_Test[ OK ] GmsaIntegrationTest.A_AddNonDomainJoinedKerberosLeaseMethod_Test (1028 ms)[ RUN ] GmsaIntegrationTest.B_RenewNonDomainJoinedKerberosLeaseMethod_Test[ OK ] GmsaIntegrationTest.B_RenewNonDomainJoinedKerberosLeaseMethod_Test (553 ms)[ RUN ] GmsaIntegrationTest.C_DeleteKerberosLeaseMethod_Test[ OK ] GmsaIntegrationTest.C_DeleteKerberosLeaseMethod_Test (7 ms)[ RUN ] GmsaIntegrationTest.A_AddKerberosArnLeaseMethod_Test[ OK ] GmsaIntegrationTest.A_AddKerberosArnLeaseMethod_Test (768 ms)[ RUN ] GmsaIntegrationTest.B_RenewKerberosArnLeaseMethod_Test[ OK ] GmsaIntegrationTest.B_RenewKerberosArnLeaseMethod_Test (691 ms)[----------] 6 tests from GmsaIntegrationTest (3054 ms total)[----------] Global test environment tear-down[==========] 6 tests from 1 test suite ran. (3054 ms total)[ PASSED ] 6 tests.To communicate with the daemon over gRPC, install grpc-cli. For examplesudo yum install grpc-cli
Note: APIs use unix domain socket
Invoke the AddkerberosLease API with the credentialsspec input as shown:grpc_cli call {unix_domain_socket} AddKerberosLease "credspec_contents: '{credentialspec}'"Sample:grpc_cli call unix:/var/credentials-fetcher/socket/credentials_fetcher.sockAddKerberosLease "credspec_contents: '{\"CmsPlugins\":[\"ActiveDirectory\"],\"DomainJoinConfig\":{\"Sid\":\"S-1-5-21-4217655605-3681839426-3493040985\",\"MachineAccountName\":\"WebApp01\",\"Guid\":\"af602f85-d754-4eea-9fa8-fd76810485f1\",\"DnsTreeName\":\"contoso.com\",\"DnsName\":\"contoso.com\",\"NetBiosName\":\"contoso\"},\"ActiveDirectoryConfig\":{\"GroupManagedServiceAccounts\":[{\"Name\":\"WebApp01\",\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp01\",\"Scope\":\"contoso\"}]}}'"* Response: lease_id - unique identifier associated to the request created_kerberos_file_paths - Paths associated to the Kerberos tickets created corresponding to the gMSA accountsInvoke the Delete kerberosLease API with lease id input as shown:grpc_cli call {unix_domain_socket} DeleteKerberosLease "lease_id: '{lease_id}'"Sample:grpc_cli call unix:/var/credentials-fetcher/socket/credentials_fetcher.sock DeleteKerberosLease "lease_id: '${response_lease_id_from_add_kerberos_lease}'"* Response: lease_id - unique identifier associated to the request deleted_kerberos_file_paths - Paths associated to the Kerberos tickets deleted corresponding to the gMSA accountsCredentials-fetcher in domainless mode assuming gMSA account 'WebApp01' has been setup as perhttps://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#use-case-for-creating-gmsa-account-for-domain-joined-container-hosts
Either launch Amazon-Linux 2023 instance or build from source and run.
Make sure the instance/server is domain-joined using the
realm listcommand in Linux.Make sure Credentials-fetcher is running using:
journalctl -u credentials-fetcherInstall grpc for python as perhttps://grpc.io/docs/languages/python/quickstart/
Create the grpc pb2 files usingcredentialsfetcher.proto:
# python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. credentialsfetcher.protoCopy this code (Create the credspec and add it to the script as below ) (Alternatively, configure using the managed services atAWS ECS mode andAWS Fargate mode)
# cat credentials_fetcher_client.py import grpc import credentialsfetcher_pb2 import credentialsfetcher_pb2_grpc def run(): with grpc.insecure_channel('unix:///var/credentials-fetcher/socket/credentials_fetcher.sock') as channel: stub = credentialsfetcher_pb2_grpc.CredentialsFetcherServiceStub(channel) credspec_contents="{\"CmsPlugins\":[\"ActiveDirectory\"],\"DomainJoinConfig\":{\"Sid\":\"S-1-5-21-2725122404-4129967127-2630707939\",\"MachineAccountName\":\"WebApp01\",\"Guid\":\"e96e0e09-9305-462f-9e44-8a8179722897\",\"DnsTreeName\":\"contoso.com\",\"DnsName\":\"contoso.com\",\"NetBiosName\":\"contoso\"},\"ActiveDirectoryConfig\":{\"GroupManagedServiceAccounts\":[{\"Name\":\"WebApp01\",\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp01\",\"Scope\":\"contoso\"}]}}" contents = [] contents += [credspec_contents] response = stub.AddKerberosLease(credentialsfetcher_pb2.CreateKerberosLeaseRequest(credspec_contents = contents)) print(f"Server response: {response}") if __name__ == '__main__': run()Configure Credentials-fetcher to create tickets for the 'WebApp01' gMSA account.
# python3 credentials_fetcher_client.py Server response: lease_id: "94efba947d75728bbf70" created_kerberos_file_paths: "/var/credentials-fetcher/krbdir/94efba947d75728bbf70/WebApp01"Here is the resulting kerberos ticket that can be shared
# klist /var/credentials-fetcher/krbdir/94efba947d75728bbf70/WebApp01/krb5cc Ticket cache: FILE:/var/credentials-fetcher/krbdir/94efba947d75728bbf70/WebApp01/krb5cc Default principal: WebApp01$@CONTOSO.COMValid starting Expires Service principal07/17/24 22:42:42 07/18/24 08:42:42 krbtgt/CONTOSO.COM@CONTOSO.COM renew until 07/24/24 22:42:42
Credentials-fetcher in domainless mode assuming gMSA account 'WebApp01' has been setup as perhttps://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#use-case-for-creating-gmsa-account-for-non-domain-joined-container-hosts( Please substitute username, secret and password as needed)
Run credentials-fetcher as follows:
# credentials-fetcherd --aws_sm_secret_name aws/directoryservices/d-xxxxxx/gmsa // Substitute your secret name in AWS secrets managerInstall grpc for python as perhttps://grpc.io/docs/languages/python/quickstart/
Create the grpc pb2 files usingcredentialsfetcher.proto:
# python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. credentialsfetcher.protoCopy this code (Create the credspec and add it to the script as below ) (Alternatively, configure using the managed services atAWS ECS mode andAWS Fargate mode)
# cat credentials_fetcher_client.py import grpc import credentialsfetcher_pb2 import credentialsfetcher_pb2_grpc def run(): with grpc.insecure_channel('unix:///var/credentials-fetcher/socket/credentials_fetcher.sock') as channel: stub = credentialsfetcher_pb2_grpc.CredentialsFetcherServiceStub(channel) credspec_contents="{\"CmsPlugins\":[\"ActiveDirectory\"],\"DomainJoinConfig\":{\"Sid\":\"S-1-5-21-2725122404-4129967127-2630707939\",\"MachineAccountName\":\"WebApp01\",\"Guid\":\"e96e0e09-9305-462f-9e44-8a8179722897\",\"DnsTreeName\":\"contoso.com\",\"DnsName\":\"contoso.com\",\"NetBiosName\":\"contoso\"},\"ActiveDirectoryConfig\":{\"GroupManagedServiceAccounts\":[{\"Name\":\"WebApp01\",\"Scope\":\"contoso.com\"},{\"Name\":\"WebApp01\",\"Scope\":\"contoso\"}]}}" contents = [] contents += [credspec_contents] response = stub.AddNonDomainJoinedKerberosLease(credentialsfetcher_pb2.CreateNonDomainJoinedKerberosLeaseRequest(credspec_contents = contents, username="admin", password="mypassword", domain="contoso.com")) print(f"Server response: {response}") if __name__ == '__main__': run()Configure Credentials-fetcher (in opensource mode) to create tickets for the 'WebApp01' gMSA account ( Alternatively, configure using the managed services atAWS ECS mode andAWS Fargate mode)
# python3 credentials_fetcher_client.py Server response: lease_id: "34e2b89e3fd8a9bcb297" created_kerberos_file_paths: "/var/credentials-fetcher/krbdir/34e2b89e3fd8a9bcb297/WebApp01"Here is the resulting kerberos ticket that can be shared
# klist /var/credentials-fetcher/krbdir/34e2b89e3fd8a9bcb297/WebApp01/krb5cc Ticket cache: FILE:/var/credentials-fetcher/krbdir/34e2b89e3fd8a9bcb297/WebApp01/krb5cc Default principal: WebApp01$@CONTOSO.COM Valid starting Expires Service principal 07/17/24 22:10:29 07/18/24 08:10:29 krbtgt/CONTOSO.COM@CONTOSO.COM renew until 07/18/24 22:10:29
On Amazon Linux 2023, only Linux x86_64 architecture is supported. Running the Credentials-fetcher outside of Linux distributions is notsupported.
Contributions and feedback are welcome! Proposals and pull requests will be considered and responded to. For moreinformation, see theCONTRIBUTING.md file.If you have a bug/and issue around the behavior of the credentials-fetcher,please open it here.
Amazon Web Services does not currently provide support for modified copies of this software.
If you think you’ve found a potential security issue, please do not post it in the Issues. Instead, please follow the instructionshere oremail AWS security directly.
The Credentials Fetcher is licensed under the Apache 2.0 License.SeeLICENSE andNOTICE for more information.
About
Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.
Resources
License
Code of conduct
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.