Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPB-11455 Allow List for 401 rate limiting #24

Open
wants to merge 1 commit into
base: wireapp/4.6.2-federation
Choose a base branch
from

Conversation

e-lisa
Copy link

@e-lisa e-lisa commented Nov 12, 2024


PR Submission Checklist for internal contributors

  • The PR Title

    • conforms to the style of semantic commits messages¹ supported in Wire's Github Workflow²
    • contains a reference JIRA issue number like SQPIT-764
    • answers the question: If merged, this PR will: ... ³
  • The PR Description

    • is free of optional paragraphs and you have filled the relevant parts to the best of your ability

What's new in this PR?

Allowlist for the 401 rate-limit features.

Added a new --401-allowlist to allow adding a path of an allow-list of
IPv4/IPv6 addresses that can bypass the 401 rate-limit settings. This
can also be set in the configuration file via 401-allowlist=.

The allow-list is updated when the allowlist file is updated during
runtime.

The allow-list format is one (1) IP address per line.

Issues

An allow-list to bypass the 401 rate-limit feature is required for federated services and other high volume IP addresses.

Solutions

A new option --401-allowlist= and configuration file setting 401-allowlist= have been added to allow specifying a file to contain the allow list. The allow list is updated every time the allow list file is updated based on its mtime (modification time).

The allow list is formatted with one IPv4/IPv6 address per line as seen in this example allow list:

127.0.0.1
192.168.1.5

Needs releases with:

  • GitHub link to other pull request

Testing

Test Coverage (Optional)

  • I have added automated test to this contribution

How to Test

Briefly describe how this change was tested and if applicable the exact steps taken to verify that it works as expected.

Notes (Optional)

Specify here any other facts that you think are important for this issue.

Attachments (Optional)

Attachments like images, videos, etc. (drag and drop in the text box)


PR Post Submission Checklist for internal contributors (Optional)

  • Wire's Github Workflow has automatically linked the PR to a JIRA issue

PR Post Merge Checklist for internal contributors

  • If any soft of configuration variable was introduced by this PR, it has been added to the relevant documents and the CI jobs have been updated.

References
  1. https://sparkbox.com/foundry/semantic_commit_messages
  2. https://github.com/wireapp/.github#usage
  3. E.g. feat(conversation-list): Sort conversations by most emojis in the title #SQPIT-764.

@echoes-hq echoes-hq bot added the echoes/initiative: federation-wire-cloud Activate Federation with MLS on Wire Cloud label Nov 12, 2024
@e-lisa e-lisa marked this pull request as ready for review November 12, 2024 12:06
return 0;
}
/* Init allow_list map if needed */
if (rate_limit_allowlist_map == NULL) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe multiple threads can end up calling this code. I'm thinking this entire method (from line 76 down) should be under the rate_limit_allowlist_mutex - since it's currently possible for the list to change at runtime (if the file is updated). If we do that, then we can remove the mutex from ratelimit_init_allowlist_map. Or perhaps we can keep the filesystem checks out of the mutex to reduce the lock time.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm of two minds of which way to go. In the last push I went ahead and split the locks up over the different parts that can conflict (the init, the clear/re-init, and put method of the map).

Let me know if you think it might be better for one big lock. I also question if the global for "modified time/mtime" should be in the lock as well.

Let me know your thoughts.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to check if it's thread safe to iterate (ie: get operation) the list while it might be modified. I'll try to look at that later this week. :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@e-lisa I did some digging into the coturn code and from what I can tell, it is NOT thread safe to call ur_addr_map_get while another thread is calling ur_addr_map_put or other ur_addr_map API's. Therefor I think you will need to implement a single global lock.

@@ -87,7 +174,6 @@ int ratelimit_is_address_limited(ioa_addr *address, int max_requests, int window
addr_set_port(address_new, 0);

if (ur_addr_map_get(rate_limit_map, address_new, &ratelimit_ptr)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - this point is more related to the previous PR on rate limit. It seems we are doing a ur_addp_map_get without a mutex. I see you call rate_limit_add_node under the mutex.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is true, perhaps we don't need the entry mutex - we can just keep the main mutex locked for all adjustments.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, we shouldn't need it on get, only the put

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that is true, I would have thought any iterating of the list while it is being written too would be dangerous. I will try to take some more time to review the ur_addr_map code to confirm this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@e-lisa I did some digging into the coturn code and from what I can tell, it is NOT thread safe to call ur_addr_map_get while another thread is calling ur_addr_map_put or other ur_addr_map API's. Therefor I think you will need to implement a single global lock.

src/ns_turn_defs.h Outdated Show resolved Hide resolved
@sgodin
Copy link
Collaborator

sgodin commented Nov 14, 2024

It would be good to add all your new command line / configuration options to the sample turnserver.conf file:
https://github.com/wireapp/coturn/blob/master/examples/etc/turnserver.conf

Added a new `--401-allowlist` to allow adding a path of an allow-list of
IPv4/IPv6 addresses that can bypass the 401 rate-limit settings. This
can also be set in the configuration file via `401-allowlist=.`

The allow-list is updated when the allowlist file is updated during
runtime.

The allow-list format is one (1) IP address per line.
@e-lisa
Copy link
Author

e-lisa commented Nov 18, 2024

It would be good to add all your new command line / configuration options to the sample turnserver.conf file: https://github.com/wireapp/coturn/blob/master/examples/etc/turnserver.conf

added

@sgodin
Copy link
Collaborator

sgodin commented Nov 20, 2024

@e-lisa If you can please avoid squashing the commits (at least for now), it will be easier to see what has been changed from the commits that result from review comments. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
echoes/initiative: federation-wire-cloud Activate Federation with MLS on Wire Cloud
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants