-
Type:
Problem report
-
Resolution: Unresolved
-
Priority:
Trivial
-
None
-
Affects Version/s: 7.0.27
-
Component/s: Agent2 (G)
-
None
Steps to reproduce:
- Configure Zabbix Agent2 on Windows with an item using web.page.get[<url>] or
web.page.perf[<url>], where <url> is an HTTPS resource using TLS 1.2 whose
server requests TLS renegotiation during the session. - Run the item.
- Observe the item error in Zabbix frontend / agent log.
- Compare with PowerShell from the same host: Invoke-WebRequest -Uri <url>
Result:
Zabbix Agent2 fails with:
Cannot get content of web page: Get <url>: local error: tls: no renegotiation
(see attached screenshot)
Invoke-WebRequest against the same URL from the same machine succeeds (200 OK),
returning the expected content (see attached screenshot).
Expected:
The item should retrieve the web page content successfully, consistent with
other HTTP clients (e.g. Invoke-WebRequest) that support TLS renegotiation.
Root cause / analysis:
Go's crypto/tls disables renegotiation by default (tls.RenegotiateNever). In
src/go/pkg/web/web.go, the http.Client's tls.Config does not set the
Renegotiation field, so requests fail when a server initiates renegotiation.
Note: TLS renegotiation only applies to TLS 1.1/1.2 - it was removed entirely
in TLS 1.3 (https://security.stackexchange.com/questions/24554/should-i-use-ssl-tls-renegotiation/230327#230327).
A public URL reproducing this exact scenario could not be located, since it
requires a server still relying on TLS 1.2 renegotiation.
Current code
(src/go/pkg/web/web.go):
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
DisableKeepAlives: true,
DialContext: (&net.Dialer{
LocalAddr: &net.TCPAddr{IP: net.ParseIP(agent.Options.SourceIP), Port: 0},
}).DialContext,
},
Timeout: timeout,
CheckRedirect: disableRedirect,
}
Suggested fix:
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
Renegotiation: tls.RenegotiateOnceAsClient,
},
Proxy: http.ProxyFromEnvironment,
DisableKeepAlives: true,
DialContext: (&net.Dialer{
LocalAddr: &net.TCPAddr{IP: net.ParseIP(agent.Options.SourceIP), Port: 0},
}).DialContext,
},
Timeout: timeout,
CheckRedirect: disableRedirect,
}