Block and allow traffic by country, IP and list
You create source policies for country and IP rules, reuse a custom IP list and assign the policies to a group.
Note: Balancer is in beta. Endpoints, fields and behavior may change before general availability, and the feature must be enabled on your account before use. Contact your NetActuate account manager to request access.
Prerequisites
- Balancer access and a key in the BALANCER_API_KEY environment variable with permission for these operations.
- The API host shown in the Balancer portal. Replace
<your-api-host>in every example with that host. - A shell, curl and Python 3 for examples that build JSON from environment variables.
- An HTTP group and reviewed source ranges and country codes. The documentation range is an example; use your own trusted range when configuring access.
Resource identifiers come from your API responses. Set each variable when its value is available, before the first step that uses it.
| Environment variable | Value |
|---|---|
ALLOW_POLICY_ID | Returned resource identifier, or your selected scope identifier. |
BLOCK_POLICY_ID | Returned resource identifier, or your selected scope identifier. |
CUSTOM_LIST_ID | Returned resource identifier, or your selected scope identifier. |
GROUP_ID | Returned resource identifier, or your selected scope identifier. |
HTTP_LB_ID | Returned resource identifier, or your selected scope identifier. |
For an identifier, enter the value returned for your resource and export it:
read -r -p 'ALLOW_POLICY_ID: ' ALLOW_POLICY_ID
export ALLOW_POLICY_ID
Steps
-
Create a reusable IP list.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/custom-lists" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"name":"trusted_ips","kind":"ip"}'API reference: Create a reusable account-wide custom list
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"customListId": 1
}
}Set CUSTOM_LIST_ID to the returned customListId.
-
Add a range.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/custom-lists/$CUSTOM_LIST_ID/items" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"value":"192.0.2.0/24"}'API reference: Create one custom list item
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"customListItemId": 1
}
} -
Create an allow policy.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/allow-policies" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"name":"trusted_sources"}'API reference: Create a reusable allow policy
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"allowPolicyId": 1
}
}Set ALLOW_POLICY_ID to the returned allowPolicyId.
-
Reference the trusted list.
python3 - <<'PYBODY' | \
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/allow-policies/$ALLOW_POLICY_ID/rules" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary @-
import json, os
print(json.dumps({'rule': {'type': 'ip_custom_list', 'customListId': int(os.environ['CUSTOM_LIST_ID'])}}))
PYBODYAPI reference: Create an allow policy rule
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"allowPolicyRuleId": 1
}
} -
Create a block policy.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/block-policies" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"name":"blocked_sources"}'API reference: Create a reusable block policy
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"blockPolicyId": 1
}
}Set BLOCK_POLICY_ID to the returned blockPolicyId.
-
Block one country.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/block-policies/$BLOCK_POLICY_ID/rules" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"rule":{"type":"country","value":"BR"}}'API reference: Create a block policy rule
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"blockPolicyRuleId": 1
}
} -
Block an IP range.
curl --silent --show-error --include \
--request POST \
--url "https://<your-api-host>/block-policies/$BLOCK_POLICY_ID/rules" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary '{"rule":{"type":"ip_cidr","value":"198.51.100.0/24"}}'API reference: Create a block policy rule
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"blockPolicyRuleId": 1
}
} -
Assign both policies.
python3 - <<'PYBODY' | \
curl --silent --show-error --include \
--request PATCH \
--url "https://<your-api-host>/http-loadbalancers/$HTTP_LB_ID/groups/$GROUP_ID" \
--header "x-api-key: $BALANCER_API_KEY" \
--header "Content-Type: application/json" \
--data-binary @-
import json, os
print(json.dumps({'allowPolicyId': int(os.environ['ALLOW_POLICY_ID']), 'blockPolicyId': int(os.environ['BLOCK_POLICY_ID'])}))
PYBODYAPI reference: Update an HTTP group configuration
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"groupId": 1
}
} -
Read the effective assignment.
curl --silent --show-error --include \
--request GET \
--url "https://<your-api-host>/http-loadbalancers/$HTTP_LB_ID/groups/$GROUP_ID" \
--header "x-api-key: $BALANCER_API_KEY"API reference: Get HTTP group
Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.
{
"code": 200,
"result": "success",
"data": {
"groupId": 1
}
}
Verify
Test from a controlled matching source and a source outside the rules. A source block returns 403 before origin. A source allow is evaluated before source blocking, request budgets and WAF. Under-attack handling can run earlier. For a literal allow, use an allow rule of type country or ip_cidr with its value; for a list block, use a block rule of type ip_custom_list with customListId.
Use your configured site domain in this traffic check:
curl --silent --show-error --include "https://example.com/"
Expected: the site behavior described above. The application response body and status depend on your origin and selected policies.
An API mutation saves desired configuration first. Readback and a live traffic check answer different questions. No fixed propagation time is established.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Block is bypassed | An earlier source allow matches | Review trusted ranges and allow policy assignment. |
| List reference is rejected | List kind, ownership or permissions do not match | Use a same-account list of the expected kind. |
| Policy deletion fails | A group or route still references it | Remove assignments before deleting the policy. |
| Traffic returns 502 | Selected policy is missing or inactive | Check the effective policy and its state. |
Limits and defaults
| Setting | Limit or default |
|---|---|
| Custom list name | Maximum 64 characters; starts with a lowercase letter; remaining characters are lowercase letters, digits or underscores |
| Custom list kinds | ip, asn, hostname or country |
| Source rule kinds | country, asn, ip_cidr, ip_custom_list, asn_custom_list or country_custom_list |
| Literal source rule | One match value per rule |
| List item value | Maximum 255 characters |
| Active lists per account | 100 |
| Active items per list | 1000 |
| Active items per account | 10000 |
API status codes
| Status | Meaning |
|---|---|
| 200 | Request succeeds; inspect returned data. |
| 400 | Invalid arguments or configuration. |
| 401 | Authentication or authorization denied. |
| 404 | Resource or parent is unavailable. |
| 409 | Resource state conflicts with the operation. |
| 412 | Inspect the returned error details. |
| 500 | The request encounters a server error. |
Related API operations
DELETE /allow-policies/{allowPolicyId}DELETE /allow-policies/{allowPolicyId}/rules/{allowPolicyRuleId}DELETE /block-policies/{blockPolicyId}DELETE /block-policies/{blockPolicyId}/rules/{blockPolicyRuleId}DELETE /custom-lists/{customListId}DELETE /custom-lists/{customListId}/items/{customListItemId}GET /allow-policiesGET /allow-policies/{allowPolicyId}GET /allow-policies/{allowPolicyId}/rulesGET /allow-policies/{allowPolicyId}/rules/{allowPolicyRuleId}GET /block-policiesGET /block-policies/{blockPolicyId}GET /block-policies/{blockPolicyId}/rulesGET /block-policies/{blockPolicyId}/rules/{blockPolicyRuleId}GET /custom-listsGET /custom-lists/{customListId}GET /custom-lists/{customListId}/itemsGET /http-loadbalancers/{httpLbId}/groups/{groupId}PATCH /allow-policies/{allowPolicyId}PATCH /allow-policies/{allowPolicyId}/rules/{allowPolicyRuleId}PATCH /block-policies/{blockPolicyId}PATCH /block-policies/{blockPolicyId}/rules/{blockPolicyRuleId}PATCH /custom-lists/{customListId}PATCH /http-loadbalancers/{httpLbId}/groups/{groupId}POST /allow-policiesPOST /allow-policies/{allowPolicyId}/rulesPOST /block-policiesPOST /block-policies/{blockPolicyId}/rulesPOST /custom-listsPOST /custom-lists/{customListId}/itemsPUT /custom-lists/{customListId}/items
API reference
-
Delete a reusable allow policy after verifying it is not assigned
-
Delete a reusable block policy after verifying it is not assigned
-
Delete a reusable custom list after verifying it is not referenced
Need Help?
Contact your account manager or use the Balancer portal.