AScript Fine-Grained Traffic Management Practices
AScript is a flexible and powerful scripting language for Alibaba Cloud Application Load Balancer (ALB). It lets you use custom scripts to implement fine-grained traffic management policies on ALB instances, overcoming the limitations of traditional load balancers. This topic introduces AScript through three common scenarios: identifying abnormal requests, implementing custom authentication, and controlling request and response headers.
AScript overview
AScript executes custom rules triggered at different phases of the request and response lifecycle for custom traffic management. These rules use custom scripts to flexibly manage request and response flows, providing fine-grained control over your business logic.
Key features
Business logic isolation: AScript rules isolate different business functions and requirements into separate scripts. This prevents rules from interfering with each other.
Execution flow control: You can define the priority and trigger conditions for each rule to match your specific business scenarios.
Execution phases: You can configure a rule to run at a specific execution phase.
Before rule execution in the request flow: This phase is ideal for pre-processing request paths. Use cases include automatically rewriting URIs, adding URI prefixes, and converting file extensions to lowercase.
After a request direction rule is executed: This applies to scenarios where requests are further processed after they are handled by standard forwarding rules, such as rewriting filenames and types.
Before rule execution in the response flow: This phase is suitable for final processing before a response is sent to the client. Use cases include modifying the HTTP header or the response body.
Listener-level scope: AScript rules operate at the listener level, ensuring each rule is closely aligned with the traffic patterns of its associated listener.
Limitations
Only standard and WAF-enabled ALB instances support AScript. Basic instances do not.
AScript includes a free quota of 25 script lines. You are charged for any lines that exceed this quota. For detailed billing rules, see ALB billing rules.
Prerequisites
You have created a standard or WAF-enabled Internet-facing ALB instance and a server group. For more information, see Create and manage ALB instances and Create and manage a server group.
You have configured an HTTP listener and associated the listener with the server group. For more information, see Add an HTTP listener.
You have added two ECS instances, ECS01 and ECS02, to the server group and deployed an application on each instance.
You have registered a domain name and completed an ICP filing. For more information, see Register a domain name on Alibaba Cloud and ICP filing process.
Use cases
The following sections describe three use cases that demonstrate the capabilities of AScript programmable script rules.
Use case 1: Abnormal request identification
A company uses Application Load Balancer (ALB) to host its services in an Alibaba Cloud region and frequently encounters abnormal requests. Large volumes of malicious requests and traffic from unknown sources put a heavy load on the backend servers, slowing down normal services and impacting the user experience.
To resolve this issue, the company decides to use ALB to block abnormal requests. Although standard ALB forwarding rules can route requests based on domain names and paths, they have limited capabilities for deeper user behavior analysis, such as inspecting the User-Agent header. Therefore, the company chooses to use AScript to extend the capabilities of ALB.
With AScript, ALB can match and analyze the User-Agent field in HTTP request headers. By writing AScript rules, you can implement custom logic to identify abnormal or malicious behaviors, such as requests from bots or automated scripts. If a request is identified as abnormal, AScript can return a custom response, blocking potential security threats and ensuring service stability and data security.
In this example, a company uses an AScript programmable script rule to check the following conditions when a request is sent to its ALB instance:
The hostname is
example.com.The URI path starts with
/order/create.The User-Agent in the HTTP request header does not contain the string
trusted.
If all the preceding conditions are met, AScript sets the status code to 403 and returns the custom response message The order data is abnormal. Otherwise, ALB forwards the request to the backend service as normal.
Procedure
Step 1: Add an AScript rule
Log on to the Application Load Balancer (ALB) console.
On the Instances page, click the ID of the target instance.
Click the Listener tab, and then click the ID of the target listener.
Click the Forwarding Rules tab. On the Inbound Forwarding Rules tab, click Add Script Before Forwarding Rule Is Applied.
NoteIf you select the Outbound Forwarding Rules tab, you can only select Add Script Before Forwarding Rule Is Applied.
On the Add Script page, configure the rule and click OK.
Parameter
Description
Name
Enter a custom name for the rule.
Script Code
Enter the rule code. This example uses the following code.
if and(eq($host,'example.com'),eq(get(split($request_uri, '?'),1),'/order/create')){ if not(match_re($http_user_agent,'.*trusted.*')){ exit(403,'{"code":10063,"msg":"The order data is abnormal","data":{}}') } }Run Script At
The rule's execution position. This parameter cannot be changed. In this example, the value is Not Executed.
Status
The status of the rule. The default setting (enabled) is used in this example.
Advanced Settings
This example uses the default setting, which is unselected.
Step 2: Configure DNS settings
Copy the DNS name of your ALB instance. Then, add a CNAME record to point your domain name to the instance's DNS name.
Log on to the Alibaba Cloud DNS console.
On the Public Zone page, click Add Zone.
In the Add Zone dialog box, enter your host's domain name, and then click OK.
ImportantYour domain must be verified with a TXT record.
Find the target domain name and click Settings in the Actions column.
On the Settings page, click Add Record.
In the Add Record panel, configure the following parameters to add a CNAME record, and then click OK.
Parameter
Description
Record Type
Select CNAME from the drop-down list.
Hostname
The prefix for your domain name.
DNS Query Source
Use the default setting.
Record Value
Enter the DNS name of the ALB instance that you copied earlier.
TTL
Time to Live (TTL) is the duration for which a DNS record is cached on a DNS server. This example uses the default value.
Step 3: Verify the results
Test normal requests.
Use any client with internet access.
You can access the backend service by visiting
http://<access_address>in a browser. If you refresh the browser multiple times, the returned content alternates between ECS01 and ECS02.Open a command-line interface on the client and run the following command multiple times. The response message switches between ECS01 and ECS02.
curl http://<your_access_address>C:\Users\xxx>curl http://xxx Hello World ! This is ECS01. C:\Users\xxx>curl http://xxx Hello World ! This is ECS02.
Test abnormal requests.
Run the command. A response of
{"code":10063,"msg":"The order data is abnormal","data":{}}indicates that the forwarding rule defined by the AScript programmable script has taken effect.curl -v -H "Host:example.com" -H "User-Agent:suspicious test" http://<your_access_address>/order/createC:\Users\xxx>curl -v -H "Host:example.com" -H "User-Agent:suspicious test" http://xxx/order/create * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET /order/create HTTP/1.1 > Host:example.com > Accept: */* > User-Agent:suspicious test > < HTTP/1.1 403 Forbidden < Date: Wed, 10 Jul 2024 08:08:42 GMT < Content-Type: application/octet-stream < Transfer-Encoding: chunked < Connection: keep-alive < {"code":10063,"msg":"The order data is abnormal","data":0} * Connection #0 to host xxx left intact
Use case 2: Custom authentication
A company uses ALB to host its services in an Alibaba Cloud region. The backend server group includes multiple servers that run different applications. The company faces a challenge: users must log on multiple times to access different applications, which degrades the user experience and increases management overhead. The company wants to implement Single Sign-On (SSO) so that users can use a unified authentication credential to access all applications.
To achieve this, the company decides to use AScript to implement custom logic. By writing custom AScript rules, the company can perform detailed checks and operations on request headers such as Authorization and Cookie. This allows an SSO token from a cookie to be converted into a unified authentication credential. AScript can also inject detailed log information into response headers to facilitate debugging and tracing of the authentication process. This programmable logging capability surpasses traditional load balancers and enhances ALB's ability to maintain system security.
In this example, a company uses AScript to check whether the request header contains an Authorization field:
If the header exists, the rule logs the length of the
Authorizationvalue and related information.If the header does not exist, the rule checks whether the
Cookieheader contains anSSO_token.If the
SSO_tokenexists, the rule logs its length, injects it as a Bearer Token into theAuthorizationrequest header, and logs this action.If the
SSO_tokenis also missing, the rule logs that both are missing.
Procedure
Step 1: Add an AScript rule
Log on to the Application Load Balancer (ALB) console.
On the Instances page, click the ID of the target instance.
Click the Listener tab, and then click the ID of the target listener.
Click the Forwarding Rules tab. On the Inbound Forwarding Rules tab, click Add Script Before Forwarding Rule Is Applied.
NoteIf you select the Outbound Forwarding Rules tab, you can only select Add Script Before Forwarding Rule Is Applied.
On the Add Script page, configure the rule and click OK.
Parameter
Description
Name
Enter a custom name for the rule.
Script Code
Enter the rule code. This example uses the following code.
def is_missing(val){ if val{ return or(null(val),le(len(val),1)) }else{ return true } } def log_on_rsp_header(key, msg) { add_rsp_header(concat('ascript-log_', key), msg) } if $http_authorization { log_on_rsp_header('authorization', concat('len=', len($http_authorization))) } if $cookie_sso_token { log_on_rsp_header('sso_token', concat('len=', len($cookie_sso_token))) } if is_missing($http_authorization) { if not(is_missing($cookie_sso_token)) { add_req_header('authorization', concat('Bearer ',$cookie_sso_token)) add_rsp_header('ascript-log', 'use sso_token as authorization in request header') } else { add_rsp_header('ascript-log', 'authorization is missing and cookie sso_token is missing too') } } else { log_on_rsp_header('miss-authorization', 'val = false') }Run Script At
The rule's execution position. This parameter cannot be changed. In this example, the value is Not Executed.
Status
The status of the rule. The default setting (enabled) is used in this example.
Advanced Settings
This example uses the default setting, which is unselected.
Step 2: Configure DNS settings
Copy the DNS name of your ALB instance. Then, add a CNAME record to point your domain name to the instance's DNS name.
Log on to the Alibaba Cloud DNS console.
On the Public Zone page, click Add Zone.
In the Add Zone dialog box, enter your host's domain name, and then click OK.
ImportantYour domain must be verified with a TXT record.
Find the target domain name and click Settings in the Actions column.
On the Settings page, click Add Record.
In the Add Record panel, configure the following parameters to add a CNAME record, and then click OK.
Parameter
Description
Record Type
Select CNAME from the drop-down list.
Hostname
The prefix for your domain name.
DNS Query Source
Use the default setting.
Record Value
Enter the DNS name of the ALB instance that you copied earlier.
TTL
Time to Live (TTL) is the duration for which a DNS record is cached on a DNS server. This example uses the default value.
Step 3: Verify the results
Test a request with no authentication credentials.
This example uses a client that can access the public network. Open the cmd window on the client and run the following command. Because the request header does not contain
Authorizationand the cookie does not containSSO_token, the response header returns the log messageauthorization is missing and cookie sso_token is missing too.curl -v http://<your_access_address>C:\Users\xxx>curl -v http://xxx * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET / HTTP/1.1 > Host: xxx > User-Agent: curl/8.4.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Wed, 10 Jul 2024 08:33:17 GMT < Content-Type: text/html < Content-Length: 29 < Connection: keep-alive < Last-Modified: Wed, 10 Jul 2024 07:19:48 GMT < ETag: "668e3614-1d" < Accept-Ranges: bytes < ascript-log: authorization is missing and cookie sso_token is missing too < Hello World ! This is ECS01. * Connection #0 to host xxx left intactTest sending a request with the
SSO_tokenin the cookie.Run the following command to add
SSO_tokento theCookierequest header. You can see that the log output in the response header isascript-log_sso_token: len=13anduse sso_token as authorization in request header.curl -v -b "sso_token=ah$sgdj#sgava" http://<your_access_address>C:\Users\xxx>curl -v -b "sso_token=ah$sgdj#sgava" http://xxx * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET / HTTP/1.1 > Host: xxx > User-Agent: curl/8.4.0 > Accept: */* > Cookie: sso_token=ah$sgdj#sgava > < HTTP/1.1 200 OK < Date: Wed, 10 Jul 2024 08:36:08 GMT < Content-Type: text/html < Content-Length: 29 < Connection: keep-alive < Last-Modified: Wed, 10 Jul 2024 07:21:29 GMT < ETag: "668e3679-1d" < Accept-Ranges: bytes < ascript-log_sso_token: len=13 < ascript-log: use sso_token as authorization in request header < Hello World ! This is ECS02. * Connection #0 to host xxx left intactTo test, send a request with the
Authorizationrequest header.Run the following command to add
Authorizationto the request header. You can see the log outputascript-log_authorization: len=20andascript-log_miss-authorization: val = falsein the response header.curl -v -H "authorization: Bearer ah$sgdj#sgava" http://<your_access_address>C:\Users\xxx>curl -v -H "authorization: Bearer ah$sgdj#sgava" http://xxx * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET / HTTP/1.1 > Host: xxx > User-Agent: curl/8.4.0 > Accept: */* > authorization: Bearer ah$sgdj#sgava > < HTTP/1.1 200 OK < Date: Wed, 10 Jul 2024 08:38:12 GMT < Content-Type: text/html < Content-Length: 29 < Connection: keep-alive < Last-Modified: Wed, 10 Jul 2024 07:19:48 GMT < ETag: "668e3614-1d" < Accept-Ranges: bytes < ascript-log_authorization: len=20 < ascript-log_miss-authorization: val = false < Hello World ! This is ECS01. * Connection #0 to host xxx left intact
The test results demonstrate that AScript allows you to manage the content and format of authentication credentials, including how they are replaced or enhanced. You can write custom authentication rules to meet your specific business requirements.
Use case 3: Custom request and response headers
A company uses ALB to host its services in an Alibaba Cloud region. The backend server group includes multiple servers that run applications. As the business grows, the company needs to implement Cross-Origin Resource Sharing (CORS). Specifically, frontend applications from different domains need to access resources and services hosted on these servers. Due to the browser's same-origin policy, cross-origin requests are blocked by default, which prevents resources from loading and disrupts the user experience and business workflows. The company also needs flexible cross-origin policies based on different request headers to meet various access requirements.
Standard ALB forwarding rules lack the flexibility for complex CORS policies. You cannot use a single forwarding rule to implement effective cross-origin policies for different request headers. To resolve this, the company uses the customization capabilities of AScript.
With AScript, the company can achieve the following:
Determine if a request has a valid cross-origin header.
Identify the request origin (from the
OriginorRefererheader) to determine whether the request is from an allowed domain.Dynamically add
Access-Control-Allow-Originand other relevant CORS response headers to allow cross-origin requests from specific domains.Provide more granular control, such as restricting available HTTP methods, headers, and frame options.
In this example, an AScript rule checks if the request origin is from an allowed domain (such as example.com, example.org, or test.com). If a match is found, ALB dynamically adds the required CORS response headers to enable valid cross-origin interactions.
Procedure
Step 1: Add an AScript rule
Log on to the Application Load Balancer (ALB) console.
On the Instances page, click the ID of the target instance.
Click the Listener tab, and then click the ID of the target listener.
Click the Forwarding Rules tab. On the Inbound Forwarding Rules tab, click Add Script Before Forwarding Rule Is Applied.
NoteIf you select the Outbound Forwarding Rules tab, you can only select Add Script Before Forwarding Rule Is Applied.
On the Add Script page, configure the rule and click OK.
Parameter
Description
Name
Enter a custom name for the rule.
Script Code
Enter the rule code. This example uses the following code.
h = $http_origin if not(h) { h = $http_referer } pcs = capture_re(h, '^(.*?)(\.example\.com|\.example\.org|\.test\.com)(:\d+)?') sec1 = get(pcs, 1) sec2 = get(pcs, 2) sec3 = get(pcs, 3) if (sec2) { add_rsp_header('cross-origin-resource-policy', 'cross-origin') add_rsp_header('access-control-allow-methods', 'GET,PUT,POST,DELETE,UPDATE,OPTIONS') add_rsp_header('access-control-allow-credentials', 'true') add_rsp_header('access-control-allow-headers', 'Cookie,Set-Cookie,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Host,Origin,csrf-token-fe1a2a3s12,xhrFields') if not(sec3) { add_rsp_header('access-control-allow-origin', concat(sec1, sec2)) add_rsp_header('x-frame-options', concat('ALLOW-FROM ', sec1, sec2)) } else { add_rsp_header('access-control-allow-origin', concat(sec1, sec2, sec3)) } }Run Script At
The rule's execution position. This parameter cannot be changed. In this example, the value is Not Executed.
Status
The status of the rule. The default setting (enabled) is used in this example.
Advanced Settings
This example uses the default setting, which is unselected.
Step 2: Configure DNS settings
Copy the DNS name of your ALB instance. Then, add a CNAME record to point your domain name to the instance's DNS name.
Log on to the Alibaba Cloud DNS console.
On the Public Zone page, click Add Zone.
In the Add Zone dialog box, enter your host's domain name, and then click OK.
ImportantYour domain must be verified with a TXT record.
Find the target domain name and click Settings in the Actions column.
On the Settings page, click Add Record.
In the Add Record panel, configure the following parameters to add a CNAME record, and then click OK.
Parameter
Description
Record Type
Select CNAME from the drop-down list.
Hostname
The prefix for your domain name.
DNS Query Source
Use the default setting.
Record Value
Enter the DNS name of the ALB instance that you copied earlier.
TTL
Time to Live (TTL) is the duration for which a DNS record is cached on a DNS server. This example uses the default value.
Step 3: Verify the results
Test a request from a disallowed origin.
For this example, use any client that can access the public internet. Open the cmd window on the client and run the following command to set the request origin to
http://www.example.cn. You can see that the response header does not containAccess-Control-Allow-Originor other related CORS response headers.curl -H "Origin: http://www.example.cn" -v http://<your_access_address>C:\Users\xxx>curl -H "Origin: http://www.example.cn" -v http://xxx * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET / HTTP/1.1 > Host: xxx > User-Agent: curl/8.4.0 > Accept: */* > Origin: http://www.example.cn > < HTTP/1.1 200 OK < Date: Wed, 10 Jul 2024 08:44:08 GMT < Content-Type: text/html < Content-Length: 29 < Connection: keep-alive < Last-Modified: Wed, 10 Jul 2024 07:19:48 GMT < ETag: "668e3614-1d" < Accept-Ranges: bytes < Hello World ! This is ECS01. * Connection #0 to host xxx left intactTest a request from an allowed origin.
Run the following command to set the request origin to
http://www.example.com. You can see that the response header now includes the relevant cross-origin headers.curl -H "Origin: http://example.com" -v http://<your_access_address>C:\Users\xxx>curl -H "Origin: http://example.com" -v http://xxx * Trying xxx:80... * Connected to xxx (xxx) port 80 > GET / HTTP/1.1 > Host: xxx > User-Agent: curl/8.4.0 > Accept: */* > Origin: http://example.com > < HTTP/1.1 200 OK < Date: Wed, 10 Jul 2024 08:46:23 GMT < Content-Type: text/html < Content-Length: 29 < Connection: keep-alive < Last-Modified: Wed, 10 Jul 2024 07:19:48 GMT < ETag: "668e3614-1d" < Accept-Ranges: bytes < < cross-origin-resource-policy: cross-origin < access-control-allow-methods: GET, PUT, POST, DELETE, UPDATE, OPTIONS < access-control-allow-credentials: true < access-control-allow-headers: Cookie, Set-Cookie, DNT, X-Mx-ReqToken, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization, Host, Origin, csrf-token-fela2a3s12, xhrFields < access-control-allow-origin: http://example.com < x-frame-options: ALLOW-FROM http://example.com < Hello World ! This is ECS01. * Connection #0 to host xxx left intact
Related documents
For an overview of AScript, see AScript Overview.
For more AScript scenarios, see AScript Scenario Examples.
For AScript syntax rules, see AScript Syntax Rules.
For AScript built-in variables, see AScript Built-in Variable List.
For AScript built-in functions, see AScript Built-in Function Library.