Skip to content

Commit

Permalink
Merge pull request #15 from ana-cozma/new-layout-markdown
Browse files Browse the repository at this point in the history
New layout markdown
  • Loading branch information
ana-cozma authored Aug 13, 2024
2 parents 28c45ef + 7049d1b commit 038c9c0
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 145 deletions.
61 changes: 60 additions & 1 deletion assets/css/custom.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,63 @@
#TOCView {
max-width: 250px !important;
font-size: 0.95em;
}
}

:root {
--color-tip: #57ab5a;
--color-warn: #f08453;
--color-caution: #ee293d;
--color-note: #5cc1dd;
}


.alert {
border-left: .25em solid;
padding: 0 16px;
border-radius: 8px;
}

.alert-tip {
border-left-color: var(--color-tip)
}

.alert-caution {
border-left-color: var(--color-caution)
}

.alert-note {
border-left-color: var(--color-note)
}

.alert-warn {
border-left-color: var(--color-warn)
}

.alert-title {
display: flex;
align-items: center;
color: inherit;
}

.alert-tip .alert-title {
color: var(--color-tip)
}

.alert-caution .alert-title {
color: var(--color-caution)
}

.alert-note .alert-title {
color: var(--color-note)
}

.alert-warn .alert-title {
color: var(--color-warn)
}

.alert-title > svg {
width: 16px;
height: 16px;
margin-right: 8px;
color: inherit;
}
20 changes: 11 additions & 9 deletions content/posts/aws-iam-deleting-users/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
title: "AWS: Handling 'Cannot delete entity, must remove tokens from principal first' error"
description: "How to handle deleting IAM users in AWS when you are asked to delete the token from the principal first."
date: 2024-02-07T13:32:57+01:00
draft: false
tags: ["aws", "iam", "terraform"]
---

This blog post will be a quick one focusing on troubleshooting a less clear error, _'Cannot delete entity, must remove tokens from principal first'_, that Terraform can throw when you try to delete IAM users from AWS.

Let's assume that in your Terraform configuration you manage IAM users and you want to delete one of them. You'd think that by simply removing the Terraform code and then running `terraform apply` it will delete the users. Which was my case. But then as soon as I ran the command to destroy the resource I ran into an issue:
Let's assume that in your Terraform configuration, you manage IAM users and you want to delete one of them. You'd think that by simply removing the Terraform code and then running `terraform apply` it will delete the users. Which was my case. But then as soon as I ran the command to destroy the resource I ran into an issue:

```console
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
Expand Down Expand Up @@ -47,42 +48,43 @@ Do you want to perform these actions?
aws_iam_user.little_tester: Destroying... [id=little_tester]
│ Error: deleting IAM User (little_tester): DeleteConflict: Cannot delete entity, must remove tokens from principal first.
status code: 409, request id: ...
status code: 409, request id: ...
```

## So what does this mean?

The error `Cannot delete entity, must remove tokens from principal first.` says that the user has some tokens that need to be removed before the user itself can be deleted. The tokens it refers to can be active access keys or registered MFA devices.

The decision to prevent the deletion of a user if any of these active tokens are associated to it makes sense since from a security perspective because it aims to prevent accidental deletion of users that are still active.
The decision to prevent the deletion of a user if any of these active tokens are associated with it makes sense from a security perspective because it aims to prevent the accidental deletion of users that are still active.

A way to confirm if this is the case is to go to AWS Console and check the user's Security credentials. There you should see any active access keys or registered MFA devices.

Having checked that, I saw that the user had an Access key that was still active and had an active MFA device. I removed both manually and then ran `terraform apply` again. And it worked! The user was deleted successfully.

## How can this happen?

The user's access token and the MFA device configured to his account were not managed by Terraform, meaning they were created manually. So Terraform was not aware of them and could not delete them. And this was preventing the deletion of the user.
The user's access token and the MFA device configured to his account were not managed by Terraform, meaning they were created manually. So Terraform was not aware of them and could not delete them. This was preventing the deletion of the user.

How this could come to be is if the user was created through Terraform code, but all the other configurations were done manually after the user was created: adding an access key, adding an MFA device, etc. So then you end up with a mix of Terraform-managed and non-Terraform-managed resources.

Something to think about for future cases, this could also happen if you create a user group in Terraform and then add users to it manually later on. These users will be part of the group, but Terraform will not be aware of them and will not be able to manage them. Or in any other scenario where you mix non-Terraform-managed and Terraform-managed resources.

## What can you do?

First option, is to add the access key and MFA device to the Terraform configuration so then creation and removal of the users will be part of a complete flow fully managed by Terraform.
The first option is to add the access key and MFA device to the Terraform configuration so the creation and removal of the users will be part of a complete flow fully managed by Terraform.

Second option is to simply manually go to AWS Console > IAM, and check the user's Security credentials and MFA devices. For the active ones simply deactivate them and remove them manually. Then simply run to your configuration and run `terraform apply` again.
The second option is to simply manually go to AWS Console > IAM, and check the user's Security credentials and MFA devices. For the active ones simply deactivate them and remove them manually. Then simply run to your configuration and run `terraform apply` again.

And lastly, you can add the [`force_destroy` argument](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user#force_destroy) to the `aws_iam_user` resource in your Terraform configuration.
And lastly, you can add the [`force_destroy` argument](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user#force_destroy) to the `aws_iam_user` resource in your Terraform configuration.

> _force_destroy - (Optional, default false) When destroying this user, destroy even if it has non-Terraform-managed IAM access keys, login profile or MFA devices. Without force_destroy a user with non-Terraform-managed access keys and login profile will fail to be destroyed._
By enabling it, it will allow Terraform to delete the user even if it has non-Terraform-managed access keys and MFA devices.
By enabling it, it will allow Terraform to delete the user even if it has non-Terraform-managed access keys and MFA devices.

**Warning!**

While it does seem a convenient option, be very careful with this argument, as it can lead to accidental deletion of users that are still active. So I would advise you to use it only if you are sure that the user is not active (maybe have a check in place that runs before the destruction of the resources), that you are aware of the security implications and lastly check the access of the team members that can run the Terraform code.
While it does seem a convenient option, be very careful with this argument, as it can lead to the accidental deletion of users that are still active. So I would advise you to use it only if you are sure that the user is not active (maybe have a check in place that runs before the destruction of the resources), that you are aware of the security implications and lastly check the access of the team members that can run the Terraform code.

## Conclusion

Expand Down
39 changes: 21 additions & 18 deletions content/posts/azure-waf-configurations/index.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
---
title: "Azure Application Gateway WAF config vs WAF policy"
description: "Azure Application Gateway WAF configuration vs WAF policy. Check the key differences and best practices to help you secure your web applications effectively."
date: 2023-10-31T13:35:49+02:00
draft: false
tags: ["azure", "terraform", "security"]
---
Recently, I had to enable WAF on our Azure Application Gateway. Because of our infrastructure setup, I wanted to have all the rules from OWASP 3.2 enabled, but I needed to be able to exclude some of our (valid) requests from being blocked as well. To achieve this, I could either try to configure the WAF Config section on our Gateway or create a WAF policy.
Recently, I had to enable WAF on our Azure Application Gateway. Because of our infrastructure setup, I wanted to have all the rules from OWASP 3.2 enabled, but I needed to be able to exclude some of our (valid) requests from being blocked as well. To achieve this, I could either try to configure the WAF Config section on our Gateway or create a WAF policy.

Given that it was not entirely clear how you can use proper exclusions and filters based on what you need, I decided to write this post to explain the differences I found between the two and how you can use them.

## What is WAF?

To recap what Web Application Firewall (WAF) is, here is a brief explanation from the official documentation:

> Azure Web Application Firewall (WAF) on Azure Application Gateway provides centralized protection of your web applications from common exploits and vulnerabilities. Web applications are increasingly targeted by malicious attacks that exploit commonly known vulnerabilities. SQL injection and cross-site scripting are among the most common attacks.
> WAF on Application Gateway is based on the Core Rule Set (CRS) from the Open Web Application Security Project (OWASP).
Before being able to enable and benefit from WAF capabilities, you will need to check the **SKU** of the Application Gateway you have. WAF can only be enabled on the **WAF_v2** SKU and not the Standard SKU. As this was my case as well, I first had to change the SKU of the Application Gateway. This can be done either from the Azure Portal or using Terraform (or any other tool for IaC, in my case, I used this one).
Before being able to enable and benefit from WAF capabilities, you will need to check the **SKU** of the Application Gateway you have. WAF can only be enabled on the **WAF_v2** SKU and not the Standard SKU. As this was my case as well, I first had to change the SKU of the Application Gateway. This can be done either from the Azure Portal or using Terraform (or any other tool for IaC, in my case, I used this one).

After this, you can proceed with configuring WAF. This can be done in two ways: either using the built-in __WAF Config section__ of the Application Gateway or creating a __WAF policy__ for the Azure Application Gateway.
After this, you can proceed with configuring WAF. This can be done in two ways: either using the built-in **WAF Config section** of the Application Gateway or creating a **WAF policy** for the Azure Application Gateway.

Let's look at what each one is and how you can use them.

## WAF config

The WAF config section is a built-in part of the Application Gateway configuration as can be seen in the image below:

![Waf Config](waf_config.png)
Expand All @@ -30,7 +32,7 @@ WAF Config is the Application Gateway's built-in method to configure WAF and it

When using Terraform you can find the `waf_configuration` block under the `azurerm_application_gateway` [resource](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/application_gateway#waf_configuration).

Let's look at an example of how you can configure it using Terraform.
Let's look at an example of how you can configure it using Terraform.

_Scenario:_ I would like to configure it to use OWASP 3.2 rules, enable the WAF, and exclude some of our telemetry requests from being blocked while also disabling some rules. This is how the basic configuration would look like:

Expand Down Expand Up @@ -75,33 +77,34 @@ The scenario was simple and while the configuration itself is not hard to do, th

- it does not allow you to add _custom rules_ from the Azure Portal UI. This means that if you want to add a custom rule, you will have to do it using the Azure CLI (or PowerShell). I would like to ideally have all my configurations in one place and not have to use multiple tools to configure or maintain my resources.

- if you have multiple Application Gateways, you will have to configure each one of them separately. Because WAF Config is built-in the Application Gateway this also means it is _managed locally to that specific Application Gateway_. While it's configuration applies to everything in the Azure Application Gateway resource. Which was my case as well as I don't manage just one Application Gateway.
- if you have multiple Application Gateways, you will have to configure each one of them separately. Because WAF Config is built-in in the Application Gateway this also means it is _managed locally to that specific Application Gateway_. While its configuration applies to everything in the Azure Application Gateway resource. This was my case as well as I don't manage just one Application Gateway.

- if you are working with Azure Front Door it's good to know that you cannot use WAF Config in that context. This is because _Azure Front Door does not support WAF Config._

## WAF policy

As opposed to WAF Config, which is a built-in functionality in the Application Gateway, WAF policies are a __standalone resource__ that enables you to configure WAF. This means that you can create a WAF policy and then apply it to multiple Application Gateways or even Azure Front Door resources as well.
As opposed to WAF Config, which is a built-in functionality in the Application Gateway, WAF policies are a **standalone resource** that enables you to configure WAF. This means that you can create a WAF policy and then apply it to multiple Application Gateways or even Azure Front Door resources as well.

WAF policy allows you to have a __centralized configuration__ for all your WAF resources. This means that you can have the same configuration for all your WAF resources and you can also have a __single place__ where you can manage your WAF configuration.
WAF policy allows you to have a **centralized configuration** for all your WAF resources. This means that you can have the same configuration for all your WAF resources and you can also have a **single place** where you can manage your WAF configuration.

Because it is a standalone resource the first benefit is you will be able to find all the configurations necessary in the Azure Portal UI: TODO: Rephrase

You have your Managed rules:

![Alt text](managed_rules.png)
![Managed rules](managed_rules.png)

Your Custom rules:

![Alt text](custom_rules.png)
![Custom rules](custom_rules.png)

And your associated gateways:

![Alt text](gws.png)
![GWS](gws.png)

As you can already guess from the screenshots, WAF Policy gives you a bit more control over your configuration as you can be more detailed in what you want to exclude or include in your rules.
As you can already guess from the screenshots, the WAF Policy gives you a bit more control over your configuration as you can be more detailed in what you want to exclude or include in your rules.

You have the flexibility to link a WAF (Web Application Firewall) policy in various ways: you can connect it:

- **globally** by assigning it to an Azure Application Gateway resource
- **per-site** level by linking it to a listener
- **per URI** level by associating it with a particular route path
Expand Down Expand Up @@ -180,28 +183,28 @@ resource "azurerm_web_application_firewall_policy" "waf_policy" {
```

After creating the WAF Policy you will need to associate it to the Application Gateway which will be done by adding the following parameters to the `azurerm_application_gateway` resource:
After creating the WAF Policy you will need to associate it with the Application Gateway which will be done by adding the following parameters to the `azurerm_application_gateway` resource:

```hcl
firewall_policy_id = azurerm_web_application_firewall_policy.wafpolicy.id
force_firewall_policy_association = true
```

The first thing you will notice, if you go to Azure Portal, is that in your Application Gatway resource you will no longer have the WAF Config section available, but a link to the WAF Policy you just created:
The first thing you will notice, if you go to Azure Portal, is that in your Application Gateway resource, you will no longer have the WAF Config section available, but a link to the WAF Policy you just created:

![Alt text](waf_policy.png)
![Waf policy](waf_policy.png)

This means that any change you want to make to your WAF configuration you will need to do it in the WAF Policy resource itself and not in the Application Gateway resource.
This offered me the granularity I needed to be able to exclude the requests I wanted and also have the same configuration for all my Application Gateways.

In my case, WAF Config was not the right answer for what I needed: have the same exclusions on all our gateways and also have the same custom rules regradless of environment and allow me to exclude the requests that were coming from our services.
In my case, WAF Config was not the right answer for what I needed: have the same exclusions on all our gateways and also have the same custom rules regardless of the environment and allow me to exclude the requests that were coming from our services.
This is why I decided to look into WAF policies instead.

## Final thoughts

WAF Config is a good option if you want to configure WAF settings at Application Gateway level that applies to all the listeners and rules within it. It's quite suitable if you have a single set of WAF settings that you want to apply to all your web applications behind the Application Gateway.
WAF Config is a good option if you want to configure WAF settings at the Application Gateway level that applies to all the listeners and rules within it. It's quite suitable if you have a single set of WAF settings that you want to apply to all your web applications behind the Application Gateway.

Whereas, WAF Policy will be a good choice when you need to have a more granular control over your WAF settings, where you need to define custom WAF settings and rules per-application or per-bath basis. One use-case for this could be if you have several applications behind the Application Gateway that have different security concerns and require configuring different WAF settings.
Whereas, WAF Policy will be a good choice when you need to have more granular control over your WAF settings, where you need to define custom WAF settings and rules per application or per-bath basis. One use case for this could be if you have several applications behind the Application Gateway that have different security concerns and require configuring different WAF settings.

I did not dive into all the rules and settings you can configure for WAF, which will be the topic of a separate more in-depth article, but I hope this post will help you decide which one is the best option for you.

Expand Down
Loading

0 comments on commit 038c9c0

Please sign in to comment.