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

Merged
merged 7 commits into from
Jan 31, 2025

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-and-mls-on-wire-c... 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
@jschaul jschaul requested a review from supersven November 14, 2024 16:09

/* Check the mtime of the allow list, do we need to update? */
struct stat fstat;
if (stat(allowlist, &fstat) == 0) {
Copy link

Choose a reason for hiding this comment

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

question: are we opening, reading and closing the allowlist file for each request?

Copy link
Author

@e-lisa e-lisa Nov 14, 2024

Choose a reason for hiding this comment

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

We are doing stat() and then opening the file if and only if the mtime changes between rate-limited 401 requests

We could try setting a "timeout" for how often the allow-list is updated, but then we'd still take a small hit for comparing the times, in addition to checking the mtime and opening the file. Both way seem valid. But to me this seems like less bloat.

Copy link

Choose a reason for hiding this comment

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

Was there a requirement that the allow list be editable without restarting? If not, I suppose another option is to just put the entire allow list in the configuration file and load it one at startup.

Copy link
Author

@e-lisa e-lisa Nov 14, 2024

Choose a reason for hiding this comment

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

@sgodin so @julialongtin told me that it needs to be updated during runtime, otherwise yes we can move this to the server initialization code. I suspect we want it to update during runtime to prevent having to disruptions during adding/removing federated servers and adding larger users to the allow list.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, this is an operational requirement. A restart of this service is a Big Deal(TM).

Copy link

Choose a reason for hiding this comment

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

Thank you for elaborating, that sounds very reasonable.

Copy link

@z-dule z-dule Dec 16, 2024

Choose a reason for hiding this comment

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

I think a stat does a system call which reads inode info, I think we should avoid doing this.
Better to update the allowlist on a signal?

Copy link

Choose a reason for hiding this comment

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

signal would safer and avoid potential blocking from filesystem IO :) There is a signal handler already that re-reads certificate files, perhaps you can attach to that.

Copy link
Author

Choose a reason for hiding this comment

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

Let me look to see how viable this is. Mind you this wouldn't be every request, as this is only run when we do the rate-limiting - not every request

But still, I will try to figure out ASAP if its possible to attach this to a signal to reload the file

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

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

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. :)

@e-lisa
Copy link
Author

e-lisa commented Dec 16, 2024

@sgodin Added a global lock for the ur_addr_map_get() method. Let me know if you think there are more changes required.

Copy link

@z-dule z-dule left a comment

Choose a reason for hiding this comment

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

I made a few inline comments.

@e-lisa
Copy link
Author

e-lisa commented Dec 26, 2024

Moved all the allowlist loading and initialization code to the mainserver startup in mainrelay.c

Assigned the real-time signal SIGRTMIN+3 to reloading the allowlist.

SIGUSR1 and SIGUSR2 are already used for single task jobs (drain and loading the TLS certificates), SIGHUP is used for reloading the configuration files (we could hook into this if wanted). SIGRTMIN+3 seemed like the best option with out changing the functionality or reloading the configuration files.

@e-lisa e-lisa requested review from z-dule, sgodin and typfel December 26, 2024 11:56
char line[1024];
/* Rebuild map */
TURN_MUTEX_LOCK(&rate_limit_allowlist_mutex);
ur_addr_map_clean(rate_limit_allowlist_map);
Copy link

Choose a reason for hiding this comment

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

You probably want to hold the lock for the entire read process, otherwise you run the risk of rate limiting an allowed endpoint between the list being cleared and the entries being added back.

Copy link

@z-dule z-dule left a comment

Choose a reason for hiding this comment

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

LGTM not much more to add.

@mastaab
Copy link

mastaab commented Jan 17, 2025

@z-dule can you please go ahead and merge it?

@z-dule z-dule merged commit 0c959ed into wireapp:wireapp/4.6.2-federation Jan 31, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
echoes/initiative: federation-and-mls-on-wire-c... Activate Federation with MLS on Wire Cloud
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants