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

Implement reuse detection for cipher #165

Merged
merged 2 commits into from
Feb 15, 2020

Conversation

oif
Copy link

@oif oif commented Feb 7, 2020

Use bloom filter to withstand reuse 'attack'.

Same implementation as https://github.com/shadowsocks/shadowsocks-libev/blob/v3.3.4/src/ppbloom.c

@oif oif requested a review from riobard February 7, 2020 07:19
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
go.mod Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
core/saltfilter/bloom.go Outdated Show resolved Hide resolved
@oif oif force-pushed the implement-reuse-detection-filter branch from 573d00d to a8ad0a9 Compare February 12, 2020 15:02
@oif oif changed the title Implement reuse detection for cipher WIP: Implement reuse detection for cipher Feb 12, 2020
@oif
Copy link
Author

oif commented Feb 12, 2020

@riobard re-implement saltfilter and support change filter entries and FPS via ldflags(but saltfilter slot count fixed). And wait riobard/go-bloom#1 merged to modify go.mod

core/saltfilter/bloomring.go Outdated Show resolved Hide resolved
core/saltfilter/bloomring.go Outdated Show resolved Hide resolved
core/saltfilter/bloomring.go Outdated Show resolved Hide resolved
core/saltfilter/filter.go Outdated Show resolved Hide resolved
core/saltfilter/filter.go Outdated Show resolved Hide resolved
core/saltfilter/filter.go Outdated Show resolved Hide resolved
core/saltfilter/filter.go Outdated Show resolved Hide resolved
shadowaead/cipher.go Outdated Show resolved Hide resolved
shadowaead/packet.go Outdated Show resolved Hide resolved
@oif
Copy link
Author

oif commented Feb 12, 2020

pardon me, I should post the general purpose of this PR.

  1. Implements a shared Bloom filter in saltfilter package and expose necessary function(Check and Test);
  2. Ciphers use this shared filter directly without initialize it manually or manage it alone.

@riobard
Copy link

riobard commented Feb 13, 2020

Please make salfilter an internal package. I don't want to export any of its members to avoid outside use.

@oif
Copy link
Author

oif commented Feb 13, 2020

@riobard How about create a github.com/shadowsocks/go-shadowsocks2/internal package and put filter inside?

@riobard
Copy link

riobard commented Feb 13, 2020

I guess that's the way to do it.

@oif oif force-pushed the implement-reuse-detection-filter branch 3 times, most recently from 19b36d3 to 51544cd Compare February 14, 2020 00:59
@oif oif requested a review from riobard February 15, 2020 03:00
@oif oif changed the title WIP: Implement reuse detection for cipher Implement reuse detection for cipher Feb 15, 2020
internal/bloomring.go Outdated Show resolved Hide resolved

func init() {
var (
finalCapacity = DefaultBRCapacity
Copy link

Choose a reason for hiding this comment

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

Is there anyway to change the value from the command line flags?

Copy link
Author

Choose a reason for hiding this comment

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

Absolutely, but I thought about this: low-level flags maybe more suitable to expose to people who known this what to do and how to modify(to make it works as expect), and keep user-end flags as Shadowsocks well known provides.

Copy link

Choose a reason for hiding this comment

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

Makes sense. Maybe we could change it via environment variables?

Copy link
Author

Choose a reason for hiding this comment

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

A good idea as well, with SHADOWSOCKS_ prefix or not?

Copy link
Author

Choose a reason for hiding this comment

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

  • SHADOWSOCKS_SF_CAPACITY
  • SHADOWSOCKS_SF_FPR
  • SHADOWSOCKS_SF_SLOT

Copy link

Choose a reason for hiding this comment

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

Looks good to me. I'm debating if we should default the filter on or off. Maybe off by default?

Copy link
Author

@oif oif Feb 15, 2020

Choose a reason for hiding this comment

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

In my view, it's better to be enabled by default as it can 'protects' connection by withstand reuse detection.

Copy link

Choose a reason for hiding this comment

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

Makes sense.

@oif oif force-pushed the implement-reuse-detection-filter branch from 51544cd to 3e6e339 Compare February 15, 2020 04:38
@oif
Copy link
Author

oif commented Feb 15, 2020

and also suppose public errors like var ErrShortPacket = errors.New("short packet") should define in one place(maybe internal or errors)

@oif oif requested a review from riobard February 15, 2020 05:45
@riobard
Copy link

riobard commented Feb 15, 2020

What do you mean? It's already exported.

@oif
Copy link
Author

oif commented Feb 15, 2020

errors declared both in aead and steam package, it’s not necessary and hard to handle outside as well

@riobard
Copy link

riobard commented Feb 15, 2020

We will remove shadowstream package soon (I've already removed it from my fork), so there's no need to worry about that.

@oif
Copy link
Author

oif commented Feb 15, 2020

@riobard OK, then just keep those declaration

@oif oif force-pushed the implement-reuse-detection-filter branch from 3e6e339 to 5d517aa Compare February 15, 2020 06:42
@riobard riobard merged commit ff604f9 into shadowsocks:master Feb 15, 2020
@riobard
Copy link

riobard commented Feb 15, 2020

We should add the necessary documentation.

@oif
Copy link
Author

oif commented Feb 15, 2020

@riobard yep, I'll create a new PR about this soon.

if finalCapacity <= 0 {
return
}
saltfilter = NewBloomRing(int(finalSlot), int(finalCapacity), finalFPR)
Copy link

Choose a reason for hiding this comment

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

Because this large allocation is done on init(), anyone depending on go-shadowsocks2 will have this allocation done, even client code on memory constrained devices. This caused an issue on the Outline iOS client, where the VpnExtension has a very tight memory limit.

Instead, this could be done on main and injected into the code that needs it, or initialized on demand.

Copy link
Author

Choose a reason for hiding this comment

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

Good point, client needs fewer capacity so maybe provide a manual initialization by giving two kind of capacity, slot and FPR which are identitified by running mode (client/server) to reduce large allocations is a good chooice.

What do you think? @riobard

Copy link
Author

Choose a reason for hiding this comment

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

And on the other hand, saltfilter provide enough ENV to let caller or executor to controll related args while initializing, it's another way to controll allocation directly.

Copy link

Choose a reason for hiding this comment

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

I sent #189 to fix it.

The ENV is not appropriate. Who sets it? Setting it on main leaks implementation details. Setting in a library is messy, since libraries can compete. For example, if client code disables it, we'll have a problem with an integration test that runs both the client and the server code.

The ideal solution would be to inject dependencies instead of using globals, but the code is not designed for injection (doesn't use classes). I implemented a compromise where I get a singleton object when needed. That can be injected later if wiring is made easier.

Copy link

Choose a reason for hiding this comment

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

I agree with @fortuna that the filter should be optional. It was an oversight that the filter is created in init(), causing problems for importing go-ss2 as a library.

Please move to #189 for further discussion about the fix.

xiahaijiao pushed a commit to xiahaijiao/go-shadowsocks2 that referenced this pull request Jan 10, 2024
…-filter

Implement reuse detection for cipher
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants