fix(tcp): Prevent slow handshake attacks and optimize TLS configuration

- Set a read timeout before the TLS handshake to prevent slow handshake attacks

- Clear the read timeout setting after a successful handshake

- Enable session resumption for server and client TLS configurations

- Explicitly prioritize the use of server-side cipher suites (ignored in TLS 1.3 but retained to ensure consistency)
This commit is contained in:
Gouryella
2025-12-08 13:29:57 +08:00
parent 1a5ffce15c
commit 3d1479900c
2 changed files with 32 additions and 9 deletions

View File

@@ -135,6 +135,15 @@ func (l *Listener) handleConnection(netConn net.Conn) {
return
}
// Set read deadline before handshake to prevent slow handshake attacks
if err := tlsConn.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
l.logger.Warn("Failed to set read deadline",
zap.String("remote_addr", netConn.RemoteAddr().String()),
zap.Error(err),
)
return
}
if err := tlsConn.Handshake(); err != nil {
l.logger.Warn("TLS handshake failed",
zap.String("remote_addr", netConn.RemoteAddr().String()),
@@ -143,6 +152,15 @@ func (l *Listener) handleConnection(netConn net.Conn) {
return
}
// Clear the read deadline after successful handshake
if err := tlsConn.SetReadDeadline(time.Time{}); err != nil {
l.logger.Warn("Failed to clear read deadline",
zap.String("remote_addr", netConn.RemoteAddr().String()),
zap.Error(err),
)
return
}
if tcpConn, ok := tlsConn.NetConn().(*net.TCPConn); ok {
tcpConn.SetNoDelay(true)
tcpConn.SetKeepAlive(true)

View File

@@ -55,9 +55,10 @@ func (c *ServerConfig) LoadTLSConfig() (*tls.Config, error) {
// Force TLS 1.3 only
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
PreferServerCipherSuites: true, // Prefer server cipher suites (ignored in TLS 1.3 but set for consistency)
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
@@ -71,9 +72,11 @@ func (c *ServerConfig) LoadTLSConfig() (*tls.Config, error) {
// GetClientTLSConfig returns TLS config for client connections
func GetClientTLSConfig(serverName string) *tls.Config {
return &tls.Config{
ServerName: serverName,
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
ServerName: serverName,
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
ClientSessionCache: tls.NewLRUClientSessionCache(0), // Enable session resumption (0 = default size)
PreferServerCipherSuites: true, // Prefer server cipher suites (ignored in TLS 1.3 but set for consistency)
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
@@ -86,9 +89,11 @@ func GetClientTLSConfig(serverName string) *tls.Config {
// WARNING: Only use for testing!
func GetClientTLSConfigInsecure() *tls.Config {
return &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS13, // Only TLS 1.3
MaxVersion: tls.VersionTLS13, // Only TLS 1.3
ClientSessionCache: tls.NewLRUClientSessionCache(0), // Enable session resumption (0 = default size)
PreferServerCipherSuites: true, // Prefer server cipher suites (ignored in TLS 1.3 but set for consistency)
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,