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

Hash the value of the sticky cookie #203

Closed
wants to merge 9 commits into from

Conversation

sylr
Copy link
Contributor

@sylr sylr commented Jun 18, 2020

Having private IPs in client cookies is something that have been flagged by external security audits done for my company's software.

@sylr
Copy link
Contributor Author

sylr commented Jun 20, 2020

Related to traefik/traefik#2299

@atomlab
Copy link

atomlab commented Jul 23, 2020

Hi, when do you plan merge this commit? It's very necessary improvement for security.

@sylr
Copy link
Contributor Author

sylr commented Aug 3, 2020

@emilevauge could you take a look a this ?

@pavelmarek77
Copy link

Any update here? I am also eager to get it implemented due our recent Penetration testing findings ..

@jbdoumenjou
Copy link
Contributor

Hello, some questions about this PR.
Why not use the standard go lib for hash?
Could we consider a way to avoid hash recalculation at each call for all URLs?
WDYT?

@sylr
Copy link
Contributor Author

sylr commented Oct 22, 2020

Why not use the standard go lib for hash?

Only for performance reasons, it claims to be more cpu/memory efficient than the standard library.

Could we consider a way to avoid hash recalculation at each call for all URLs?

I guess we could add a map that caches the results of the hashing. Its size should not be greater than the number of backends.

@sylr
Copy link
Contributor Author

sylr commented Oct 23, 2020

I've added several flavours of isBackendAlive(...) with caching and different lock mechanisms in order to benchmark them.

Here the results on my machine:

$ go test -benchmem -benchtime=15s -run='^$' github.com/vulcand/oxy/roundrobin -bench '^(BenchmarkStickysessions)$'                           11:49:40
goos: darwin
goarch: amd64
pkg: github.com/vulcand/oxy/roundrobin
BenchmarkStickysessions/isBackendAlive-12                     	 2197734	      9010 ns/op	    8071 B/op	     504 allocs/op
BenchmarkStickysessions/isBackendAliveRWMutexRlock-12         	 2055895	      8796 ns/op	    5039 B/op	     251 allocs/op
BenchmarkStickysessions/isBackendAliveRWMutexLock-12          	  657480	     28608 ns/op	    5041 B/op	     252 allocs/op
BenchmarkStickysessions/isBackendAliveMutexLock-12            	  889591	     20345 ns/op	    5041 B/op	     252 allocs/op
PASS
ok  	github.com/vulcand/oxy/roundrobin	92.652s

The benchmark has been written so that it replicates a normal behavior where the list of backends does not mutate much. We can consider that the cache will be appended a few times in order to be filled and then will stay the same until the list of backends changes.

In that scenario isBackendAliveRWMutexRlock seems to be the best choice but its code is not the most readable as we need to juggle with the mutex's read and write lock states.

Let me know what you think.

@jbdoumenjou
Copy link
Contributor

Hi,

Thank you very much for the benchmarks and sorry for the response time.

Considering the small performance gain compared to the complexity introduced and the fact that the StickySession architecture is initially intended to be stateless (it can be used in several roundrobin loadbalancers) it seems more relevant not to introduce a cache.

@sylr
Copy link
Contributor Author

sylr commented Jan 4, 2021

I reverted the hash cache experiment.

switch {
case strings.HasPrefix(needle, "http"):
for _, serverURL := range haystack {
if needle == serverURL.String() {
Copy link

Choose a reason for hiding this comment

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

sameURL use to check only for Path, Host and Scheme equality. If this change is intended could you tell us more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's either creating a net.URL out of the needle string to compare it with serverURL with sameURL(...) or Marshaling serverURL into a string to compare it with needle.

I guess both are pretty similar.

Copy link

@jspdown jspdown Jan 7, 2021

Choose a reason for hiding this comment

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

It's really close except that with .String() you will also compare the User if present.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I did not know it was a thing to discard the user info but ok.

roundrobin/stickysessions.go Outdated Show resolved Hide resolved
@sylr sylr force-pushed the stealthy-sticky-cookies branch from 47528c5 to da9c284 Compare January 8, 2021 14:47
@sylr
Copy link
Contributor Author

sylr commented Jan 8, 2021

Ok so since in addition to hash I have to clone the serverURL and marshal it, I benchmarked it again and it became clear adding cache for computed values improves things a lot:

go test -benchmem -benchtime=15s -run='^$' github.com/vulcand/oxy/roundrobin -bench '^(BenchmarkStickysessions)$'
goos: darwin
goarch: amd64
pkg: github.com/vulcand/oxy/roundrobin
BenchmarkStickysessions/isBackendAlive-12         	 3489471	      5354 ns/op	       0 B/op	       0 allocs/op
BenchmarkStickysessions/isBackendAliveOld-12      	 1841678	     10067 ns/op	    8073 B/op	     504 allocs/op
PASS
ok  	github.com/vulcand/oxy/roundrobin	52.678s

The cached version is twice faster and use 0 allocs compared to previous version.

@sylr sylr force-pushed the stealthy-sticky-cookies branch from da9c284 to c859072 Compare January 8, 2021 15:10
@cognusion
Copy link
Contributor

I'll mention #184 again...

@jbdoumenjou
Copy link
Contributor

jbdoumenjou commented Feb 22, 2021

Hi @sylr,

Sorry for the late answer.
For the sake of simplicity and knowing that the sticky mechanism could be used for several load balancers in different use cases, we prefer to have the first step without cache.
Could you please remove it accordingly?

The cache could be addressed in another PR.

@pavelmarek77
Copy link

pavelmarek77 commented Apr 16, 2021

@sylr Can we please proceed with this? Our Penetration testers are complaining about Internal IP Address Disclosed :-(

@sylr
Copy link
Contributor Author

sylr commented Apr 16, 2021

The PR in its current state is the most performant version according to the tests I made so I'm not willing to remove the cache.

@emilevauge
Copy link
Contributor

@sylr we love the fact that you are deeply involved in this project, but open source means being able to work together, within a team. If you don't accept any of the feedback from the maintainers, this PR will never move forward and we all think it's too bad.
There are many good reasons to not include the cache in this PR, and if you don't agree with that, we plan to open a PR on our own in order to unlock this situation.
I strongly hope you will reconsider your decision, you are a great contributor :)

@sylr
Copy link
Contributor Author

sylr commented Apr 16, 2021

If you don't accept any of the feedback from the maintainers, this PR will never move forward and we all think it's too bad.

I believe I responded to all feedbacks except one so this is just an unfair statement.

I'll revert the cash to make this go forward.

@emilevauge
Copy link
Contributor

@sylr It's perfectly fair once you take into account the tone of your answer, which is kind of aggressive.
Thanks a lot for keeping this place peaceful and effective. We are all on the same boat, with the same goal.
And thanks again for removing the cache part, we will merge this one ASAP 🙂

@cognusion
Copy link
Contributor

Or, you know, #184 which allows you to pick how you want to hash it, or if you want to encrypt it.. In use for a few years, billions of requests, numerous external security audits... No cache. Just sayin'. 🕺

@ReillyBrogan
Copy link

If the other PR allows for outright encryption of the sticky cookie value (as well as hashing for those who are fine with that) then that would be preferable for us.

@jbdoumenjou
Copy link
Contributor

PR #216 has been opened to use both the flexibility of #184 and the hash mechanism of #203.
WDYT?

@ldez ldez closed this in #216 Apr 29, 2021
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.

10 participants