|
| 1 | +# HTTP callout with the rewrite and responder policy |
| 2 | + |
| 3 | +An HTTP callout allows Citrix ADC to generate and send an HTTP or HTTPS request to an external server (callout agent) as part of the policy evaluation. The information that is retrieved from the server (callout agent) can be analyzed by advanced policy expressions and an appropriate action can be performed. For more information about the HTTP callout, see the [Citrix ADC documentation](https://docs.citrix.com/en-us/citrix-adc/current-release/appexpert/http-callout.html). |
| 4 | + |
| 5 | +You can initiate the HTTP callout through the following expressions with the [rewrite and responder CRD](https://github.com/citrix/citrix-k8s-ingress-controller/blob/master/crd/rewrite-responder-policies-deployment.yaml) provided by Citrix: |
| 6 | + |
| 7 | +- `sys.http_callout()`: This expression is used for blocking the call when the httpcallout agent response needs to be evaluated. |
| 8 | + |
| 9 | +- `sys.non_blocking_http_callout()`: This expression is used for non-blocking calls (for example: traffic mirroring) |
| 10 | + |
| 11 | +These expressions accept the `httpcallout_policy` name defined in the CRD as a parameter, where the name needs to be specified in double quotes. |
| 12 | + |
| 13 | +For example: `sys.http_callout("callout_name")`. |
| 14 | +In this expression, `callout_name` refers to the appropriate `httpcallout_policy` defined in the rewrite and responder CRD YAML file. |
| 15 | + |
| 16 | +The following table explains the attributes of the HTTP callout request in the rewrite and responder CRD. |
| 17 | + |
| 18 | +|Parameter|Description| |
| 19 | +|--- |--- | |
| 20 | +|`name`|Specifies the name of the callout, maximum is up to 32 characters.| |
| 21 | +|`server_ip`|Specifies the IP Address of the server (callout agent) to which the callout is sent.| |
| 22 | +|`server_port`|Specifies the Port of the server (callout agent) to which the callout is sent.| |
| 23 | +|`http_method`|Specifies the method used in the HTTP request that this callout sends. The default value is GET.| |
| 24 | +|`host_expr`| Specifies the text expression to configure the host header. This expression can be a literal value (for example, 10.101.10.11) or it can be an advanced expression (for example, http.req.header("Host")) that derives the value. The literal value can be an IP address or a fully qualified domain name. Mutually exclusive with the full HTTP request expression.| |
| 25 | +|`url_stem_expr`| Specifies a string expression for generating the URL stem. The string expression can contain a literal string (for example, "/mysite/index.html") or an expression that derives the value (for example, http.req.url).| |
| 26 | +|`headers`| Specifies one or more headers to insert into the HTTP request. Each header `name` and `exp`, where `exp` is an expression that is evaluated at runtime to provide the value for the named header. | |
| 27 | +|`parameters`|Specifies one or more query parameters to insert into the HTTP request URL (for a GET request) or into the request body (for a POST request). Each parameter is represented by a `name` and an `expr`, where `expr` is an expression that is evaluated at run time to provide the value for the named parameter (name=value). The parameter values are URL encoded.| |
| 28 | +|`body_expr`|An advanced string expression for generating the body of the request. The expression can contain a literal string or an expression that derives the value (for example, client.ip.src).| |
| 29 | +|`full_req_expr`|Specifies the exact HTTP request, in the form of an expression, which the Citrix ADC sends to the callout agent. The request expression is constrained by the feature for which the callout is used. For example, an HTTP.RES expression cannot be used in a request-time policy bank or in a TCP content switching policy bank.| |
| 30 | +|`scheme`| Specifies the type of scheme for the callout server. Example: HTTP, HTTPS| |
| 31 | +|`return_type`|Specifies the type of data that the target callout agent returns in response to the callout. The available settings function as follows: TEXT - Treat the returned value as a text string. NUM - Treat the returned value as a number. BOOL - Treat the returned value as a boolean value.| |
| 32 | +|`cache_for_secs`|Specifies the duration, in seconds, for which the callout response is cached. The cached responses are stored in an integrated caching content group named `calloutContentGroup`. If the duration is not configured, the callout responses are not cached unless a normal caching configuration is used to cache them. This parameter takes precedence over any normal caching configuration that would otherwise apply to these responses.| |
| 33 | +|`result_expr`| Specifies the expression that extracts the callout results from the response sent by the HTTP callout agent. This expression must be a response based expression, that is, it must begin with `HTTP.RES`. The operations in this expression must match the return type. For example, if you configure a return type of `TEXT`, the result expression must be a text based expression. If the return type is `NUM`, the result expression (result_expr) must return a numeric value, as in the following example: `http.res.body(10000).length`| |
| 34 | +|`comment`|Specifies any comments to preserve the information about this HTTP callout.| |
| 35 | + |
| 36 | +## Using the rewrite and responder CRD to validate whether a client IP address is blacklisted |
| 37 | + |
| 38 | +This section shows how to initiate an HTTP callout using the rewrite and responder CRD to validate whether a client IP address is blacklisted or not and take appropriate action. |
| 39 | + |
| 40 | +The following diagram explains the workflow of a request where each number in the diagram denotes a step in the workflow: |
| 41 | + |
| 42 | + |
| 43 | +1. Client request |
| 44 | + |
| 45 | +2. HTTP callout request to check if the client is blacklisted (The client IP address is sent as a query parameter with the name `Cip`) |
| 46 | + |
| 47 | +3. Response from the HTTP callout server |
| 48 | + |
| 49 | +4. Request is forwarded to the service if the response in step 3 indicates a safe IP address (the client IP address is not matching with the blacklisted IP addresses on the callout server). |
| 50 | + |
| 51 | +5. Respond to the client as `Access denied`, if the response in step 3 indicates a bad IP address (the client IP address is matching with the blacklisted IP addresses on the callout server). |
| 52 | + |
| 53 | +The following is a sample YAML file (`ip_validate_responder.yaml`) for validating a blacklisted IP address: |
| 54 | + |
| 55 | +**Note:** You must deploy the [rewrite and responder CRD](https://github.com/citrix/citrix-k8s-ingress-controller/blob/master/crd/rewrite-responder-policies-deployment.yaml) before deploying the `ip_validate_responder` YAML file. |
| 56 | + |
| 57 | +```yml |
| 58 | +apiVersion: citrix.com/v1 |
| 59 | +kind: rewritepolicy |
| 60 | +metadata: |
| 61 | + name: validateip |
| 62 | +spec: |
| 63 | + responder-policies: |
| 64 | + - servicenames: |
| 65 | + - frontend |
| 66 | + responder-policy: |
| 67 | + respondwith: |
| 68 | + http-payload-string: '"HTTP/1.1 401 Access denied\r\n\r\n"' |
| 69 | + respond-criteria: 'sys.http_callout("blacklist_callout").CONTAINS("IP Matched")' #Callout name needs to be given in double quotes to pick httpcallout_policy |
| 70 | + comment: 'Invalid access' |
| 71 | + |
| 72 | + httpcallout_policy: |
| 73 | + - name: blacklist_callout |
| 74 | + server_ip: "192.2.156.160" |
| 75 | + server_port: 80 |
| 76 | + http_method: GET |
| 77 | + host_expr: '"192.2.156.160"' |
| 78 | + url_stem_expr: '"/validateIP.pl"' |
| 79 | + headers: |
| 80 | + - name: X-Request |
| 81 | + expr: '"Callout Request"' |
| 82 | + parameters: |
| 83 | + - name: Cip |
| 84 | + expr: 'CLIENT.IP.SRC' |
| 85 | + return_type: TEXT |
| 86 | + result_expr: 'HTTP.RES.BODY(100)' |
| 87 | +``` |
| 88 | +
|
| 89 | +
|
| 90 | +## Using the rewrite and responder CRD to update the URL with a valid path requested by the client. |
| 91 | +
|
| 92 | +This section shows how to initiate an HTTP callout using the rewrite and responder CRD when a path exposed to the client is different from the actual path due to security reasons. |
| 93 | +
|
| 94 | +The work flow of a request is explained in the following diagram where each number in the diagram denotes a step in the workflow. |
| 95 | +
|
| 96 | + |
| 97 | +
|
| 98 | +
|
| 99 | +1. Client request |
| 100 | +
|
| 101 | +2. HTTP callout request to get the valid path (the path requested from the client is sent as a query parameter with the name path to the callout server) |
| 102 | +
|
| 103 | +3. Response from the HTTP callout server |
| 104 | +
|
| 105 | +4. The URL request is rewritten with a valid path and forwarded to the service (where the valid path is mentioned between tags <path> and </path> in the callout response) |
| 106 | +
|
| 107 | +The following is a sample YAML (`path_rewrite`) file. |
| 108 | + |
| 109 | +**Note:** You must deploy the [rewrite and responder CRD](https://github.com/citrix/citrix-k8s-ingress-controller/blob/master/crd/rewrite-responder-policies-deployment.yaml) before deploying the `path_rewrite` YAML file. |
| 110 | + |
| 111 | +```yml |
| 112 | +apiVersion: citrix.com/v1 |
| 113 | +kind: rewritepolicy |
| 114 | +metadata: |
| 115 | + name: getvalidpath |
| 116 | +spec: |
| 117 | + rewrite-policies: |
| 118 | + - servicenames: |
| 119 | + - frontend |
| 120 | + rewrite-policy: |
| 121 | + operation: replace |
| 122 | + target: http.req.url |
| 123 | + modify-expression: 'sys.http_callout("mapping_callout")' #Callout name needs to be given in double quotes to pick httpcallout_policy |
| 124 | + comment: 'Get the valid path' |
| 125 | + direction: REQUEST |
| 126 | + rewrite-criteria: 'TRUE' |
| 127 | +
|
| 128 | + httpcallout_policy: |
| 129 | + - name: mapping_callout |
| 130 | + server_ip: "192.2.156.160" |
| 131 | + server_port: 80 |
| 132 | + http_method: GET |
| 133 | + host_expr: '"192.2.156.160"' |
| 134 | + url_stem_expr: '"/getPath.pl"' |
| 135 | + headers: |
| 136 | + - name: X-Request |
| 137 | + expr: '"Callout Request"' |
| 138 | + parameters: |
| 139 | + - name: path |
| 140 | + expr: 'http.req.url' |
| 141 | + return_type: TEXT |
| 142 | + result_expr: '"HTTP.RES.BODY(500).AFTER_STR(\"<path>\").BEFORE_STR(\"</path>\")"' |
| 143 | +``` |
| 144 | + |
0 commit comments