dev@trafficserver.apache.org,

Bryan Call and I have been working on an idea for ip_allow.yaml. At Yahoo,
we have an internal API which categorizes IPs under certain groups via a
database lookup. Each of the IP categories have potentially different
requirements for which HTTP methods are accessible to them. For instance,
IP addresses in something like ACME_INTERNAL may be able to initiate HTTP
requests using modifying methods such as PUSH and DELETE as well as GET and
HEAD requests, while IP addresses labeled ANY_IP may only be able to use
requests with GET and HEAD methods. While the general filtering
functionality of ip_allow.yaml would be ideal for controlling these HTTP
method restrictions, the current ip_addrs node of ip_allow.yaml, while good
for explicit IP range specification, does not allow for programmatic IP
categorization like that described above.

Currently, Yahoo implements the required filtering by basically stripping
ip_allow.yaml to nothing but the absolute minimum denominator of method
restrictions and then uses an internal plugin to implement the method
filtering based upon the categories of the database.

In discussing this method filtering by IP category, Bryan Call had the idea
that this feature could be implemented as a general solution for the
community by a relatively simple extension of ip_allow.yaml itself. I spent
some time working on this and have a draft PR demonstrating the feature
here:

https://github.com/apache/trafficserver/pull/10840

The feature includes the following new user interfaces:

ip_category
The feature adds ip_category to ip_allow.yaml record as an alternative to
the ip_addrs key. Here is an example record specification using an
ip_category of ACME_INTERNAL:

- apply: in  ip_category: ACME_INTERNAL  action: allow  methods:    -
GET    - HEAD    - POST    - DELETE

TS_HTTP_IP_ALLOW_CATEGORY_HOOK hook
The user then supplies a plugin that implements the
TS_HTTP_IP_ALLOW_CATEGORY_HOOK callback which the core uses to query
whether a given incoming IP is applicable to a given category, such as
ACME_INTERNAL above. Knowing this informs the core whether a particular
ip_allow.yaml rule applies to an incoming or outgoing connection.

New Category Plugin API Functions
The plugin that implements the TS_HTTP_IP_ALLOW_CATEGORY_HOOK handler then
uses the following API to communicate with the core about whether an IP
belongs to a category:

  /** Obtain the category name being inspected.
   * @param[in] infop The ip_allow info object.
   * @param[out] category The category name being inspected whether it
contains
   *   the address obtained via @a TSHttpIpAllowInfoAddrGet.
   * @return TS_SUCCESS if the category name was obtained, TS_ERROR
otherwise.
   */
  TSReturnCode TSHttpIpAllowInfoCategoryGet(TSHttpIpAllowInfo infop,
std::string_view &category);

  /** Obtain the address being queried whether it belongs to a category.
   * @param[in] infop The ip_allow info object.
   * @param[out] addr The address being queried against a category obtained
via
   *   @a TSHttpIpAllowInfoCategoryGet.
   * @return TS_SUCCESS if the address was obtained, TS_ERROR otherwise.
   */
  TSReturnCode TSHttpIpAllowInfoAddrGet(TSHttpIpAllowInfo infop, sockaddr
&addr);

  /** Set whether an address applies to a category.
   * @param[in] infop The ip_allow info object.
   * @param[in] contains Whether the address obtained via
   *  @a TSHttpIpAllowInfoAddrGet is contained in the category obtained via
   *  @a TSHttpIpAllowInfoCategoryGet.
   */
  void TSHttpIpAllowInfoContainsSet(TSHttpIpAllowInfo infop, bool contains);

The TSHttpIpAllowInfo is an opaque structure, but in the backend it simply
contains the three pieces of data represented above:

struct HttpIpAllowInfo {

  /// A user-specified name for IP categories.
  std::string_view category;

  /// The IP address to query whether it is contained in @a category.
  swoc::IPAddr const &addr;

  /// The result of the query: the hook sets this to true of @a addr is in
@a
  /// category, false otherwise.
  bool contains = false;
};

An example plugin that makes use of this API can be found in the draft PR
here:

https://github.com/bneradt/trafficserver/blob/ip_allow_categories/example/plugins/c-api/ip_category/ip_category.cc

We hope that this feature can be generally helpful to other users in the
community who have IP categories that cannot be statically specified in the
ip_addrs node of ip_allow.yaml. We welcome any thoughts or suggestions for
improvement concerning the above suggested API.

Thanks,
Brian


-- 
"Come to Me, all who are weary and heavy-laden, and I will
give you rest. Take My yoke upon you and learn from Me, for
I am gentle and humble in heart, and you will find rest for
your souls. For My yoke is easy and My burden is light."

    ~ Matthew 11:28-30

Reply via email to