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

proposal: crypto/tls: support kernel-provided TLS #44506

Open
howardjohn opened this issue Feb 22, 2021 · 23 comments
Open

proposal: crypto/tls: support kernel-provided TLS #44506

howardjohn opened this issue Feb 22, 2021 · 23 comments
Labels
Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Milestone

Comments

@howardjohn
Copy link
Contributor

Lots of background and a implementation, albeit from 3+ years ago: https://blog.filippo.io/playing-with-kernel-tls-in-linux-4-13-and-go/

Basically, Linux now supports handling TLS encryption in the kernel. The primary benefit here is the possibility of sendfile/splice to work with TLS. Currently, we need to choose between TLS and splice (or a custom TLS implementation, I suppose).

It would be great to have first class support in go for this.

@seankhliao seankhliao changed the title crypto/tls: support Kernal TLS proposal: crypto/tls: support Kernal TLS Feb 22, 2021
@seankhliao seankhliao added Proposal Proposal-Crypto Proposal related to crypto packages or other security issues labels Feb 22, 2021
@gopherbot gopherbot added this to the Proposal milestone Feb 22, 2021
@seankhliao
Copy link
Member

cc @FiloSottile

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Feb 24, 2021
@rsc rsc changed the title proposal: crypto/tls: support Kernal TLS proposal: crypto/tls: support kernel-provided TLS Feb 24, 2021
@ShivanshVij
Copy link

I would love to have this happen as well! It's a major use case for L7 load balancers written in golang, and could transparently provide significant performance boosts for a lot of systems (including Kubernetes)

@FiloSottile
Copy link
Contributor

Can we get some benchmarks and numbers for the performance improvement? My patch linked above might be a good starting point. It's a lot of complexity and it would have to be justified by very good numbers.

@jim3ma
Copy link

jim3ma commented Nov 29, 2021

Hi, all

I have updated kernel tls support based on @FiloSottile's original code. It now supports more ciphers like AES_GCM_256, AES_CCM_128 and CHACHA20_POLY1305.

Code: https://github.com/jim3ma/go/tree/dev.ktls.1.16.3.

And I have fixed some kernel issues when in coding: torvalds/linux@974271e, torvalds/linux@d8654f4

In my simple tests, when enable kernel tls, I have got 30% time cost decreased.

@totallyunknown
Copy link

I made some real-world tests with one of our internal applications (CDN node specialised in delivering video segments for DASH and HLS streams).

  • Kernel 5.13.12
  • Curve: prime256v1

I compared https vs http, vs http + sendfile and ktls + sendfile.

Most of the TLS stuff is working, except TLS 1.3 with Chrome and k6. k6 reports tls: oversized record received with length 62464.

With ktls, the latency is increased - but this can also be related to the difference in the used Go-Versions.

The ktls implementation reduces overall CPU usage, around 10%. We'll deploy the Nvidia ConnectX-6 (200 Gbit/s) in our latest hardware setup, and we hope we can use the TLS NIC offloading in the future.

https://docs.google.com/spreadsheets/d/1XaiFczae9GLixu__8y2kuKPsw7RGqW9vMDkYxuTLx28/edit#gid=0

@jrfastab
Copy link

@totallyunknown If the latency issue is related to the kernel implementation (rule out golang side) we can take a look at kernel side improvements. We've been using the openssl implementation lately so I'll check there as well, but I don't recall extra latency last time I did metrics. Having a golang implementation would be very useful on my side as well. fwiw I'm one of the ktls maintainers on kernel side so we shouldn't have trouble getting improvements there as needed and happy to help where I can to get this moving forward.

@jim3ma
Copy link

jim3ma commented Feb 15, 2022

I made some real-world tests with one of our internal applications (CDN node specialised in delivering video segments for DASH and HLS streams).

  • Kernel 5.13.12
  • Curve: prime256v1

I compared https vs http, vs http + sendfile and ktls + sendfile.

Most of the TLS stuff is working, except TLS 1.3 with Chrome and k6. k6 reports tls: oversized record received with length 62464.

With ktls, the latency is increased - but this can also be related to the difference in the used Go-Versions.

The ktls implementation reduces overall CPU usage, around 10%. We'll deploy the Nvidia ConnectX-6 (200 Gbit/s) in our latest hardware setup, and we hope we can use the TLS NIC offloading in the future.

https://docs.google.com/spreadsheets/d/1XaiFczae9GLixu__8y2kuKPsw7RGqW9vMDkYxuTLx28/edit#gid=0

Which version do you test ? I have update some go code for http with ktls.

@totallyunknown
Copy link

@jim3ma
Copy link

jim3ma commented Feb 15, 2022

@jim3ma Your branch: https://github.com/jim3ma/go/tree/dev.ktls.1.16.3

Okay, I will merge some optimized code into this branch tomorrow.

@kkkygytb

This comment was marked as duplicate.

@kolinfluence

This comment was marked as duplicate.

@VirrageS
Copy link

@jim3ma are there any plans to introduce the changes into the Go code?

@jim3ma
Copy link

jim3ma commented Jul 29, 2023

@jim3ma are there any plans to introduce the changes into the Go code?

Sorry for busy work. I will rebase kTLS code in latest branch and test it again.

@zyxkad
Copy link

zyxkad commented Mar 18, 2024

any updates?

@ouvaa
Copy link

ouvaa commented Mar 28, 2024

@jim3ma curious about the updates too

been checking here
https://github.com/0-haha/gnet-tls-go1-20/
and ref:
panjf2000/gnet#534

@FiloSottile i've been watching ktls progress for golang since you started the blog in 2021.
this is sort of the final huge golang performance benchmark penalty ever.

once this is ktls-ed, i believe will be one of golang's greatest milestone ever.

@ShivanshVij
Copy link

I did some rough benchmarks late last year where I had Golang call into rust's TLS library via CGO to do the handshake and then handed off the established TCP connection to Golang.

I found that the performance (throughput/latency on sustained traffic) ended up being about the same as golang's built-in TLS or slightly worse.

I'm not sure why to be honest - maybe I did something wrong? But I would like to see some numbers hopefully from someone else on the actual performance of the kTLS implementation in the linux kernel.

@ouvaa
Copy link

ouvaa commented Mar 28, 2024

@ShivanshVij u hv the code for helping to debug? but ktls is better for sure.

@zyxkad
Copy link

zyxkad commented Mar 29, 2024

I did some rough benchmarks late last year where I had Golang call into rust's TLS library via CGO to do the handshake and then handed off the established TCP connection to Golang.

Based on my understanding, kTLS does not magically works, it's used for zero copy, so you have to send a fd through syscall

@ShivanshVij
Copy link

ShivanshVij commented Mar 29, 2024 via email

@kanocz
Copy link

kanocz commented Mar 29, 2024

One more thing - many better network card have crypto-acceleration and this can be accessed by ktls API, so supporting ktls in golang we are able to offload encryption to network card
so please don't compare only software encryption in golang vs software encryption in kernel - it's not so relevant for many production environments

@kolinfluence
Copy link

i've used gnet's ktls and other ktls version but i found that if going through cgo, and with multiple goroutines, it seems to crash. e.g. 1000000 goroutines calling cgo seemed not possible. u can probably do 80k max.
so not sure if ktls will be available to do so or if this will be an issue crashing if doing cgo syscall etc.

@rsc
Copy link
Contributor

rsc commented Apr 24, 2024

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rhysh
Copy link
Contributor

rhysh commented Apr 26, 2024

It looks like rustls (for Rust) makes kTLS possible by allowing access to the key material after the handshake completes. Could that be the right stance for Go as well, to allow use of kTLS without the crypto/tls maintainers needing to take on ownership of all of the moving parts?

The QUIC support in crypto/tls is in a similar position, where crypto/tls does the initial handshake and then hands the key material over to its caller.

From what I can tell, the discussion at rustls/rustls#198 led to https://docs.rs/rustls/latest/rustls/struct.ExtractedSecrets.html, which in turn enables users to provide their own kTLS wiring. (There's support in crypto/tls already for a Config.KeyLogWriter — but as the rustls maintainers also discovered, that format doesn't include all of the information that the kernel needs to continue the symmetric encryption.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Projects
Status: Active
Development

No branches or pull requests