Skip to content

How to manage Security Groups and Rules via IaaS-API

Security groups and security group rules are a mechanism to protect VMs from unwanted traffic, akin to a “host firewall”. One or more security group rules belong to a security group. A security group can be applied to one or more server network interfaces (NICs) and changes to a security group affect all assigned network interfaces at the same time.

Attention: The standard set of rules (“Default”) stipulates that all outgoing traffic is allowed and all incoming traffic is forbidden (traffic from systems in the same security group is an exception to the ban on incoming traffic). This means that inbound traffic must always be explicitly allowed before it is effectively allowed. This avoids external access being possible due to forgotten setting of security groups.

This page shows how to create, modify and delete security groups and rules using the IaaS API.

Each project has a default, stateful security group with the name default and a predefined set of four rules:

  • an IPv4 and an IPv6 rule that allows all outgoing (egress) traffic
  • an IPv4 and an IPv6 rule that allows incoming (ingress) traffic from the same security group

Other ingress traffic will be rejected, unless it is belonging to already established connections.

In a newly created project, the default security group will be the only security group. You can list the security group with the following command (replace $PROJECT_ID with the id of your STACKIT project):

Terminal window
stackit curl https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups

It should return an output similar to this (here we pretty-printed it by piping through jq):

Terminal window
{
"items": [
{
"createdAt": "2024-09-26T09:33:04Z",
"description": "Default security group",
"id": "48d2f405-71e6-45df-9687-f1052edcdd59",
"labels": {},
"name": "default",
"rules": [
{
"direction": "ingress",
"ethertype": "IPv4",
"id": "211c1fb1-e725-45c7-993b-ad308306e867",
"remoteSecurityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59",
"securityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59"
},
{
"direction": "ingress",
"ethertype": "IPv6",
"id": "7351e769-7bd6-4533-9dcd-652beda8923b",
"remoteSecurityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59",
"securityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59"
},
{
"direction": "egress",
"ethertype": "IPv4",
"id": "742671a7-deaa-44a0-b3e5-3ede9b5aa226",
"securityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59"
},
{
"direction": "egress",
"ethertype": "IPv6",
"id": "7aafe8cf-9d9b-48a4-87b7-be6ddc1f3f11",
"securityGroupId": "48d2f405-71e6-45df-9687-f1052edcdd59"
}
],
"stateful": true,
"updatedAt": "2024-09-26T09:33:04Z"
}
]
}

Notice how both ingress rules reference a remote security group (remoteSecurityGroupId), which happens to be the same default security group. This is the configuration bit that allows the incoming traffic from within the same security group.

Based on that output, we know that the ID of the default security group in the project is 48d2f405-71e6-45df-9687-f1052edcdd59. Instead of listing all security groups in the project, you can query the details of a specific security group directly with:

Terminal window
SECURITY_GROUP_ID=48d2f405-71e6-45df-9687-f1052edcdd59
stackit curl https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups/$SECURITY_GROUP_ID

A security group acts as a container for security group rules and must have a name. Optionally, you can give it a description and mark it as either a stateful (which is the default) or stateless.

For example, to create a security group named “icmp-allow” with a corresponding description, you can issue the following request (again, replace $PROJECT_ID with the id of your STACKIT project):

Terminal window
stackit curl -X POST "https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups" \
--header "Content-Type: application/json" \
--data '{
"name": "icmp-allow",
"description": "Allow ICMP traffic"
}'

The response looks similar to this:

Terminal window
{
"createdAt": "2024-12-17T10:53:51Z",
"description": "Allow ICMP traffic",
"id": "7b6cd135-fcc5-4dde-adb0-1e4accaeba0b",
"labels": {},
"name": "icmp-allow",
"rules": [
{
"direction": "egress",
"ethertype": "IPv4",
"id": "0f3d3688-83f6-4fe5-869b-29a98c43e335",
"securityGroupId": "7b6cd135-fcc5-4dde-adb0-1e4accaeba0b"
},
{
"direction": "egress",
"ethertype": "IPv6",
"id": "fbde526b-e4e1-460c-9335-94140caeba9f",
"securityGroupId": "7b6cd135-fcc5-4dde-adb0-1e4accaeba0b"
}
],
"stateful": true,
"updatedAt": "2024-12-17T10:53:51Z"
}

Note, however, that this security group doesn’t do anything yet, because it does not contain any rules and is not assigned to a server.

With a security group rule you can allow traffic that would otherwise be rejected.

To create a security group rule:

  • You need the id of the security group to which the rule is to be added.
  • Furthermore, you must provide the direction of the traffic the rule should match (ingress or egress).
  • Optionally, you can further restrict what the rule matches by specifying the IP protocol version, IP and port ranges, protocol names/numbers and a remote security group. If not explicitely specified, a security group rule will match all IPs, ports and protocols.
  • Also optionally, you can provide a description for the rule.

As an example, we will add a rule to the “icmp-allow” security group created in the last section. We want it to matche the ICMP protocol in the ingress direction from everywhere (IP range 0.0.0.0/0), thereby allowing ICMP traffic from the outside:

Terminal window
SECURITY_GROUP_ID=7b6cd135-fcc5-4dde-adb0-1e4accaeba0b
stackit curl -X POST https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups/$SECURITY_GROUP_ID/rules \
--header "Content-Type: application/json" \
--data '{
"direction": "ingress",
"ethertype": "IPv4",
"ipRange": "0.0.0.0/0",
"protocol": "icmp",
"description": "Allow incoming IPv4 ICMP traffic from everywhere"
}'

The output will be similar to this:

Terminal window
{
"description": "Allow incoming IPv4 ICMP traffic from everywhere",
"direction": "ingress",
"ethertype": "IPv4",
"id": "05bd4da7-9ebf-4353-a740-93201fd64766",
"ipRange": "0.0.0.0/0",
"protocol": {
"name": "icmp",
"number": 1
},
"securityGroupId": "7b6cd135-fcc5-4dde-adb0-1e4accaeba0b"
}

Most importantly, take note of the rule ID (field id), which you will need later if you want to delete the rule.

Please note that this rule will immediately affect all servers which are assigned to the security group. Assigning a security group to a server is accomplished by adding the security group to an appropriate network interface of a server and is documented here.

For further details about the API call and the available parameters, have a look at the API documentation at the docs.

To delete a security group rule, you need to provide the security group rule ID, and the ID of the security group the rule is contained in.

Attention: The deletion of the rule will immediately affect all server network interfaces which are assigned to the security group.

For example, to delete the rule identified by 05bd4da7-9ebf-4353-a740-93201fd64766, which we have previously created in the “icmp-allow” security group:

Terminal window
SECURITY_GROUP_ID=7b6cd135-fcc5-4dde-adb0-1e4accaeba0b
RULE_ID=05bd4da7-9ebf-4353-a740-93201fd64766
stackit curl --include -X DELETE \
https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups/$SECURITY_GROUP_ID/rules/$RULE_ID

If successful, you will get a response with status code 204 (No Content) and an empty body.

For further details about the API call, have a look at the API documentation at the docs.

To delete a security group, you need to provide the security group ID.

Attention: Deleting a security group will remove any existing attachments to network interfaces.

As an example, we will remove the “icmp-allow” we created above. This can be achieved with:

Terminal window
SECURITY_GROUP_ID=7b6cd135-fcc5-4dde-adb0-1e4accaeba0b
stackit curl --include -X \
DELETE https://iaas.api.eu01.stackit.cloud/v1/projects/$PROJECT_ID/security-groups/$SECURITY_GROUP_ID

If successful, you will get a response with status code 204 (No Content) and an empty body.

For further details about the API call, have a look at the API documentation at the docs.