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

Ticket30924 042 01 #1232

Closed
wants to merge 23 commits into from
Closed

Conversation

Labels
None yet
Projects
None yet
4 participants
@dgoulet-tor
Copy link
Contributor

@dgoulet-tor dgoulet-tor commented Aug 13, 2019

No description provided.

dgoulet-tor added 2 commits Aug 12, 2019
There can be multiple fields in a cell extension but individually, it is
singular.

Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
@dgoulet-tor dgoulet-tor force-pushed the ticket30924_042_01 branch 2 times, most recently from d39e7c4 to 2e0840d Aug 13, 2019
src/feature/hs/hs_intropoint.c Outdated Show resolved Hide resolved
src/feature/hs/hs_intropoint.c Outdated Show resolved Hide resolved
src/feature/hs/hs_cell.c Outdated Show resolved Hide resolved
@@ -156,8 +156,10 @@ hs_dos_can_send_intro2(or_circuit_t *s_intro_circ)
{
tor_assert(s_intro_circ);

/* Always allowed if the defense is disabled. */
Copy link
Member

@asn-d6 asn-d6 Aug 14, 2019

Hmm this commit was confusing to me. I need to look into this more. But perhaps we can make param_introduce_defense_enabled private so that it's obvious that it should not be used by public functions like this one?

In general, I'm kinda confused by the various priorities and interactions between consensusparam variables and other dos variaables.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 14, 2019

param_introduce_defense_enabled needs to be public from a function. I believe one of the last commits makes it public so the intro point sets the service intro circuit with that value by default to know if it enables the defenses or not.

See hs_dos_get_intro2_enabled_param()

Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Hmm, I'm still confused by this. Here are some reasons:

  • I don't like the name of hs_dos_get_intro2_rate_param() and its two friends. The name I don't like because "param" is an ambiguous word in general, but even more so in this particular context given that the code means "consensus param" but the first thing that came to my mind were the new params from the ESTABLISH_INTRO cell.

  • I don't like that hs_dos_get_intro2_enabled_param() is public since it's not clear whether that function knows the ground truth, or I need to consult the s_intro_circ->introduce2_dos_defense_enabled to know the ground truth.

  • It's a bit confusing to have get_param_intro_dos_enabled() and also hs_dos_get_intro2_rate_param() and neither of these two things gives me the ground truth in some cases (because if the values are specified in the establish_intro cell the ground truth is different).

Here is a suggestion. Please tell me if you like it:

  • Dump the get_param_intro_dos_enabled etc. functions and do the consensus check inline in set_consensus_parameters(). This way we dont have two similarly named functions doing almost the same thing.

  • Abstract the following code of hs_intropoint.c into its own hs_dos_setup_default_introduce2_defences() hs_dos function:

    circ->introduce2_dos_defense_enabled = hs_dos_get_intro2_enabled_param();
    token_bucket_ctr_init(&circ->introduce2_bucket,
                          hs_dos_get_intro2_rate_param(),
                          hs_dos_get_intro2_burst_param(),
                          (uint32_t) approx_time());
    

    This way we can then make the hs_dos_get_intro2_ functions into private for the hs_dos module.

  • Finally, rename the hs_dos_get_intro2_rate_param() functions into get_intro2_rate_default_consensus_value() because now they are private.

I can also try to do this if you want me , and then we can see if we like it.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Ok I've pushed several new commits to address this. Not very complicated. I did not follow exactly what you said, made some changes, you'll see. Main thing is that I kept the consensus parameter variables (see start of hs_dos.c) but now I only use those in the hs_dos.c code.

Last commit is also a fix that I found while doing this refactoring.

src/app/config/config.c Show resolved Hide resolved
dgoulet-tor added 11 commits Aug 14, 2019
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Make it clear that these functions return the consensus param only.
Introduction point can not set those values with a torrc option.

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit makes tor add the DoS cell extension to the ESTABLISH_INTRO cell
if the defense is enabled on the service side with a torrc option.

Furthermore, the cell extension is only added if the introduction point
supports it. The protover version HSIntro=5 is looked for.

Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
We added a flag on the circuit to know if the DoS defenses are enabled or not.
Before, it was solely the consensus parameter.

Part of #30924

Signed-off-by: David Goulet <dgoulet@torproject.org>
This also adds a "subsection" to the HIDDEN SERVICE OPTIONS section to
seperate per-service and per-instance options. It is a bit less messy this
way.

The HS DoS options are added to the per-service section.

Part of #30924

Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
@dgoulet-tor dgoulet-tor force-pushed the ticket30924_042_01 branch from 2e0840d to 0128217 Aug 14, 2019
@coveralls
Copy link

@coveralls coveralls commented Aug 14, 2019

Pull Request Test Coverage Report for Build 5811

  • 112 of 136 (82.35%) changed or added relevant lines in 7 files are covered.
  • 13 unchanged lines in 3 files lost coverage.
  • Overall coverage remained the same at 62.887%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/feature/hs/hs_config.c 6 30 20.0%
Files with Coverage Reduction New Missed Lines %
src/feature/hs/hs_dos.c 1 95.12%
src/feature/dirauth/shared_random.c 3 85.54%
src/feature/dirauth/dirvote.c 9 64.99%
Totals Coverage Status
Change from base Build 5808: 0.0%
Covered Lines: 47366
Relevant Lines: 75319

💛 - Coveralls

The introduction point honors the consensus parameters except if this is
specifically set by the service operator using this option. The service
never looks at the consensus parameters in order to enable or disable this
defense. (Default: 0)
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

What happens if HiddenServiceEnableIntroDoSDefense is enabled but no rate/burst values are set in the torrc? I was assuming that the default rate/burst values are picked (as documented below) but I think that's not the case, and the defense stays disabled. Is this true? Maybe this should be documented on the man page, or add a warn in the code?

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Default rate and burst are used. See set_service_default_config().

The allowed client introduction rate per second at the introduction
point. If this option is 0, it is consider infinite and thus if
**HiddenServiceEnableIntroDoSDefense** is set, it then effectively
disables the defenses. (Default: 25)
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

s/consider/considered ?

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Fixup commit done.

/* Extra safety. We should never send an unknown parameter type. */
tor_assert(param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC ||
param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC);

Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Let's add a log_info here with the values we chose, because there is no service-side log about this I think. We can have it log_info since building intro circuits is not so frequent.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Commit 5e256d5

@@ -15,6 +15,14 @@
#define HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT 65535
/* Maximum number of intro points per version 3 services. */
#define HS_CONFIG_V3_MAX_INTRO_POINTS 20
/* Default value for the introduction DoS defenses. */
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Let's document all of these and specify how each of them is used. For validation or as default values? By the service or the intro point?

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Well hmmm... you sure that is necessary? We have man page explaining each of them. We have a full proposal explaining what they do.

And there is _DEFAULT for each param for the exact purpose of indicating the default value? And MIN/MAX is obviously for validation.

Not sure what more would be useful here without duplicating quite a bit the same documentation?

@@ -46,11 +46,11 @@
#define HS_DOS_INTRODUCE_ENABLED_DEFAULT 0

/* Consensus parameters. */
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Perhaps we should document that if there is a value in establish_intro cell these values get lower priority over the cell values?

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Commit 9eeb2a5

}

/* Validation. A value of 0 on either of them means the defenses are
* disabled so we ignore. */
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Let's split these three checks into individual if blocks and document each of them on what exactly they are doing, so that it's more clear what we are checking exactly.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

I've majorly refactor this. And fixed a bug in there! There was a typo between RATE/BURST... And now even unit testing that ;)

Commit 24c49a5

* disabled so we ignore. */
if ((intro2_rate_per_sec > HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX ||
intro2_rate_per_sec <= HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN) ||
(intro2_burst_per_sec > HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX ||
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Why isn't intro2_burst_per_sec > HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX allowed? Is there an implicit limit to burst values based on the rate values? As suggested above some documentation on these checks would be useful.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

This is one of the bug I fixed in previous commit.

intro2_burst_per_sec <= HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN) ||
(intro2_burst_per_sec < intro2_rate_per_sec)) {
circ->introduce2_dos_defense_enabled = 0;
log_info(LD_REND, "Intro point DoS defenses disabled due to bad values");
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Let's print the offending values in this case also.

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

Done in the refactored commit above.

@@ -334,6 +348,48 @@ config_service_v3(const config_line_t *line_,
export_circuit_id = true;
continue;
}
if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSDefense")) {
Copy link
Member

@asn-d6 asn-d6 Aug 19, 2019

Perhaps we need some unittests for the torrc parsing and validation? And maybe cross-checking them with the intro-point validation checks?

Copy link
Contributor Author

@dgoulet-tor dgoulet-tor Aug 20, 2019

See commit 667e6db

dgoulet-tor added 10 commits Aug 20, 2019
A bit cleaner especially that the next commit(s) will make the consensus param
interface private to hs_dos.c so we expose as little as we can outside of the
subsystem.

Part of #30924

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit makes it that the hs_dos.c file only uses the consensus parameter
variables set when we initialize and when the consensus changes.

There is no need to call each time networkstatus_get_param(), which is
expensive, when we want access to a consensus value.

Signed-off-by: David Goulet <dgoulet@torproject.org>
Remove the public functions returning the HS DoS consensus param or default
values as it is exclusively used internally now.

Rename the param_* variables to consensus_param_* for better code semantic.

Finally, make some private functions available to unit tests.

Signed-off-by: David Goulet <dgoulet@torproject.org>
When consensus changes, we also need to update the circuit INTRO2 defenses
enabled flag and not only the token bucket.

Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Move everything to its own function in order to better log, document and tests
the introduction point validation process.

Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
Signed-off-by: David Goulet <dgoulet@torproject.org>
@torproject-pusher torproject-pusher deleted the branch torproject:master May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment