Securing Lab Environments Part 1

One of the great things that operating in the cloud allows us to do, is create lab environments. With Infrastructure as Code (IoC) tools, it makes it really easy for users to create preconfigured lab environments to try new things, and experiment with new technologies.

Often these lab environments are created with some preconfigured infrastructure so that the learners can focus on the critical tasks. For example, if I am working with connecting an AWS Lambda function to a SQL Server Database, I don’t want to spend a lot of time waiting for the SQL Server to be created… I want to jump right into the coding!

One big mistake that is far too easy to make is the idea of having passwords to your lab hard coded into the IoC templates. If this happens, every environment has the same password, and it becomes very easy for some nefarious person on the internet to gain access to the resources. If this happens you may find that your lab infrastructure is being used for ill intent. Even though these accounts or resources are only being spun up temporarily, there is still a window of opportunity for the resources to be hijacked, and we should do everything we can to limit this risk.

This blog post is going to outline one way you can add security to your lab environment’s IaC templates. We will create a random unique password for the environment, and then spin up an AWS Managed Microsoft Active Directory (MMAD) instance using that random password to use as an identity provider for the rest of the infrastructure.

As usual for me, the code is going to be expressed in C# for CDK. However, the same actions can be performed in any other CDK language, or native Cloud Formation.

Create a Random Password to Use

Creating a random password in CDK is done by using the AWS Secrets Manager service.

            var adminSecret = new Secret(this, "mmad-admin-user-secret", new SecretProps
            {
                Description = "Common Administrator password",
                GenerateSecretString = new SecretStringGenerator()
                {
                    ExcludeCharacters = "\"@/\\",
                    PasswordLength = 30,
                    SecretStringTemplate = "{\"Username\":\"Admin\"}",
                    GenerateStringKey = "Password"
                },
                SecretName = "MMADAdminSecret"
            });

This snippet will create the random password in Secrets manager, that will be used later when we create the Managed Active Directory. In the Secret Properties object, we pass in the Description and the Secret name, and some values that are used to create the random password. In this case I am creating a password that is 30 characters long, which should be more than sufficient for my purposes. Once the password has been created, users that log into the environment can get access to the password by going to the Secrets Manager service in the AWS Console.

Using the password with AWS Managed Microsoft Active Directory

Now that we have a randomly generated password, we will create a new instance of Managed Microsoft Active Directory, passing in that password to be used for the default Admin user account.

If you are not aware, with AWS MMAD, the high privilege delegated account that you receive is called ‘Admin’ not ‘Administrator’.

            var cfnMicrosoftAD = new CfnMicrosoftAD(this, "MMAD", new CfnMicrosoftADProps
            {
                Name = "example.com",
                ShortName = "EXAMPLE",
                Password = "{{resolve:secretsmanager:MMADAdminSecret:SecretString:Password}}",
                VpcSettings = new VpcSettingsProperty
                {
                    SubnetIds = new[] { vpc.PrivateSubnets[0].SubnetId, vpc.PrivateSubnets[1].SubnetId },
                    VpcId = vpc.VpcId
                },

                // the properties below are optional
                Edition = "Standard"
            });

This snippet will create a new MMAD. The domain name will be ‘EXAMPLE’ and the FQDN will be ‘example.com’. Cloud formation will automatically retrieve the password that was created and stored in Secrets manager. In this case we are creating a Standard Managed Active Directory instead of an Enterprise managed active directory. Standard MMAD is more than sufficient for most lab use cases.

One thing to be conscious of is that you cannot create the MMAD, until after the Secrets Manager portion of your template has finished creation. In order to force this to be the case we can add the following code after your code to create the MMAD instance:

cfnMicrosoftAD.Node.AddDependency(adminSecret);

This will make the MMAD entry dependent on the admin secret, ensuring that the admin secret completes successfully before any attempt is made to start creating the MMAD. In my testing, a MMAD takes around 20 minutes to become fully operational, so sit back and have a coffee while you wait.

Putting it all together

Once you have a Managed Active Directory, you can start using that as an Identity provider for your other resources. For example in my last blog post I wrote about creating an Automation document for joining an instance to your MMAD. You can use the code in that blog post to help you get your instances joined up as part of the EC2 creation process.

Users can obtain access the the random password by going into the AWS Secrets Manager service, and decrypting the password. Retrieve Password

Wrap Up

By using AWS Managed Microsoft Active Directory and random passwords, you can increase the security posture of your temporary environments and stop using hard coded passwords that can become easily compromised. These random passwords are easily created by using AWS Secrets Manager and CDK or Cloud Formation.

Please be aware: The code in this blog post will result in charges on your account for the resources that you have created. Secrets manager is charged per secret per month, and Managed Microsoft Active Directory is charged per hour.

Pricing for AWS Managed Microsoft Active Directory can be found here:

https://aws.amazon.com/directoryservice/pricing/

Pricing for AWS Secrets Manager can be found here:

https://aws.amazon.com/secrets-manager/pricing/

If you have any feedback, please feel free to drop me a line at:

tom@basementprogrammer.com