Layer 7 Cookbook

Introduction

This document gives several examples of common L7 load balancer usage. For a description of L7 load balancing see: Layer 7 Load Balancing

For the puposes of this guide we assume that the neutron command-line interface is going to be used to configure all features of Neutron LBaaS with an Octavia back-end. Also, in order to keep these examples short, we assume that many non-L7 configuration tasks (such as deploying loadbalancers, listeners, pools, members, healthmonitors, etc.) have already been accomplished. A description of the starting conditions is given in each example below.

Examples

Redirect http://www.example.com/ to https://www.example.com/

Scenario description:

  • Load balancer lb1 has been set up with TERMINATED_HTTPS listener tls_listener on TCP port 443.
  • tls_listener has been populated with a default pool, members, etc.
  • tls_listener is available under the DNS name https://www.example.com/
  • We want any regular HTTP requests to TCP port 80 on lb1 to be redirected to tls_listener on TCP port 443.

Solution:

  1. Create listener http_listener as an HTTP listener on lb1 port 80.
  2. Set up an L7 Policy policy1 on http_listener with action REDIRECT_TO_URL pointed at the URL https://www.example.com/
  3. Add an L7 Rule to policy1 which matches all requests.

CLI commands:

neutron lbaas-listener-create --name http_listener --loadbalancer lb1 --protocol HTTP --protocol-port 80
neutron lbaas-l7policy-create --action REDIRECT_TO_URL --redirect-url https://www.example.com/ --listener http_listener --name policy1
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value / policy1

Send requests starting with /js or /images to static_pool

Scenario description:

  • Listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • We are introducing static content servers 10.0.0.10 and 10.0.0.11 on subnet private-subnet, and want any HTTP requests with a URL that starts with either “/js” or “/images” to be sent to those two servers instead of pool1.

Solution:

  1. Create pool static_pool on lb1.
  2. Populate static_pool with the new back-end members.
  3. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at static_pool.
  4. Create an L7 Rule on policy1 which looks for “/js” at the start of the request path.
  5. Create L7 Policy policy2 with action REDIRECT_TO_POOL pointed at static_pool.
  6. Create an L7 Rule on policy2 which looks for “/images” at the start of the request path.

CLI commands:

neutron lbaas-pool-create --name static_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.10 --protocol-port 80 static_pool
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.11 --protocol-port 80 static_pool
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy1
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /js policy1
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy2
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /images policy2

Alternate solution (using regular expressions):

  1. Create pool static_pool on lb1.
  2. Populate static_pool with the new back-end members.
  3. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at static_pool.
  4. Create an L7 Rule on policy1 which uses a regular expression to match either “/js” or “/images” at the start of the request path.

CLI commands:

neutron lbaas-pool-create --name static_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.10 --protocol-port 80 static_pool
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.11 --protocol-port 80 static_pool
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy1
neutron lbaas-l7rule-create --type PATH --compare-type REGEX --value '^/(js|images)' policy1

Send requests for http://www2.example.com/ to pool2

Scenario description:

  • Listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • We have set up a new pool pool2 on lb1 and want any requests using the HTTP/1.1 hostname www2.example.com to be sent to pool2 instead.

Solution:

  1. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at pool2.
  2. Create an L7 Rule on policy1 which matches the hostname www2.example.com.

CLI commands:

neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool pool2 --listener listener1 --name policy1
neutron lbaas-l7rule-create --type HOST_NAME --compare-type EQUAL_TO --value www2.example.com policy1

Send requests for *.example.com to pool2

Scenario description:

  • Listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • We have set up a new pool pool2 on lb1 and want any requests using any HTTP/1.1 hostname like *.example.com to be sent to pool2 instead.

Solution:

  1. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at pool2.
  2. Create an L7 Rule on policy1 which matches any hostname that ends with example.com.

CLI commands:

neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool pool2 --listener listener1 --name policy1
neutron lbaas-l7rule-create --type HOST_NAME --compare-type ENDS_WITH --value example.com policy1

Send unauthenticated users to login_pool (scenario 1)

Scenario description:

  • TERMINATED_HTTPS listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • The site behind listener1 requires all web users to authenticate, after which a browser cookie auth_token will be set.
  • When web users log out, or if the auth_token is invalid, the application servers in pool1 clear the auth_token.
  • We want to introduce new secure authentication server 10.0.1.10 on Neutron subnet secure_subnet (a different Neutron subnet from the default application servers) which handles authenticating web users and sets the auth_token.

Note: Obviously, to have a more secure authentication system that is less vulnerable to attacks like XSS, the new secure authentication server will need to set session variables to which the default_pool servers will have access outside the data path with the web client. There may be other security concerns as well. This example is not meant to address how these are to be accomplished–it’s mainly meant to show how L7 application routing can be done based on a browser cookie.

Solution:

  1. Create pool login_pool on lb1.
  2. Add member 10.0.1.10 on secure_subnet to login_pool.
  3. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at login_pool.
  4. Create an L7 Rule on policy1 which looks for browser cookie auth_token (with any value) and matches if it is NOT present.

CLI commands:

neutron lbaas-pool-create --name login_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
neutron lbaas-member-create --subnet secure_subnet --address 10.0.1.10 --protocol-port 80 login_pool
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy1
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type REGEX --value '.*' --invert policy1

Send unauthenticated users to login_pool (scenario 2)

Scenario description:

  • TERMINATED_HTTPS listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • The site behind listener1 requires all web users to authenticate, after which a browser cookie auth_token will be set.
  • When web users log out, or if the auth_token is invalid, the application servers in pool1 set auth_token to the literal string “INVALID”.
  • We want to introduce new secure authentication server 10.0.1.10 on Neutron subnet secure_subnet (a different Neutron subnet from the default application servers) which handles authenticating web users and sets the auth_token.

Note: Obviously, to have a more secure authentication system that is less vulnerable to attacks like XSS, the new secure authentication server will need to set session variables to which the default_pool servers will have access outside the data path with the web client. There may be other security concerns as well. This example is not meant to address how these are to be accomplished– it’s mainly meant to show how L7 application routing can be done based on a browser cookie.

Solution:

  1. Create pool login_pool on lb1.
  2. Add member 10.0.1.10 on secure_subnet to login_pool.
  3. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at login_pool.
  4. Create an L7 Rule on policy1 which looks for browser cookie auth_token (with any value) and matches if it is NOT present.
  5. Create L7 Policy policy2 with action REDIRECT_TO_POOL pointed at login_pool.
  6. Create an L7 Rule on policy2 which looks for browser cookie auth_token and matches if it is equal to the literal string “INVALID”.

CLI commands:

neutron lbaas-pool-create --name login_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
neutron lbaas-member-create --subnet secure_subnet --address 10.0.1.10 --protocol-port 80 login_pool
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy1
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type REGEX --value '.*' --invert policy1
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy2
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type EQUAL_TO --value INVALID policy2

Send requests for http://api.example.com/api to api_pool

Scenario description:

  • Listener listener1 on load balancer lb1 is set up to send all requests to its default_pool pool1.
  • We have created pool api_pool on lb1, however, for legacy business logic reasons, we only want requests sent to this pool if they match the hostname api.example.com AND the request path starts with /api.

Solution:

  1. Create L7 Policy policy1 with action REDIRECT_TO_POOL pointed at api_pool.
  2. Create an L7 Rule on policy1 which matches the hostname api.example.com.
  3. Create an L7 Rule on policy1 which matches /api at the start of the request path. (This rule will be logically ANDed with the previous rule.)

CLI commands:

neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool api_pool --listener listener1 --name policy1
neutron lbaas-l7rule-create --type HOST_NAME --compare-type EQUAL_TO --value api.example.com policy1
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /api policy1