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

remotewrite: Use TLS ServerName as Host in all requests #5802

Closed
wants to merge 1 commit into from

Conversation

minor-fixes
Copy link

@minor-fixes minor-fixes commented Feb 13, 2024

This change modifies HTTP requests made via remote-write to set the Host field to the TLS config's ServerName, when a TLS config is present. Otherwise, the empty default is maintained, and the Go stdlib will fall back to using the host component of the URL.

This is useful to work around a somewhat-unfortunate setup we are currently dealing with, involving:

  • a client machine that has limited ability to resolve DNS queries (so we must point to our reverse-proxy instance via IP)
  • a reverse proxy that proxies based on the request's target host

We can almost get this to work by passing both -remoteWrite.url and -remoteWrite.tlsServerName; however, the host will still be the host specified in the former and not the latter, which our reverse proxy mappings will not be able to handle.

With this tweak, we are able to successfully ingest metrics.


This PR as-is is likely not production-worthy:

  • this may not be the best place/way to get the TLS config and set the Host field
  • more similar instances may need to be modified across the codebase for consistency

With this PR, I'm looking to get feedback on:

  • which behavior is the most correct/useful (Host field comes from URL vs Host field comes from TLS ServerName)
  • if this change is desired, then particulars on how would be appreciated!

This change modifies HTTP requests made via remote-write to set the
`Host` field to the TLS config's `ServerName`, when a TLS config is
present. Otherwise, the empty default is maintained, and the Go stdlib
will fall back to using the host component of the URL.

This is useful to work around a somewhat-unfortunate setup we are
currently dealing with, involving:

* a client machine that has limited ability to resolve DNS queries (so
  we must point to our reverse-proxy instance via IP)
* a reverse proxy that proxies based on the request's target host

We can almost get this to work by passing both `-remoteWrite.url` and
`-remoteWrite.tlsServerName`; however, the host will still be the host
specified in the former and not the latter, which our reverse proxy
mappings will not be able to handle.

---

This PR as-is is likely not production-worthy:

* this may not be the best place/way to get the TLS config and set the
  Host field
* more similar instances may need to be modified across the codebase for
  consistency

With this PR, I'm looking to get feedback on:

* which behavior is the most correct/useful (Host field comes from URL
  vs Host field comes from TLS ServerName)
* if this change is desired, then particulars on how would be
  appreciated!
Copy link

codecov bot commented Feb 20, 2024

Codecov Report

Attention: 2 lines in your changes are missing coverage. Please review.

Comparison is base (8aaa828) 60.37% compared to head (e7adee9) 56.48%.
Report is 171 commits behind head on master.

Files Patch % Lines
app/vmagent/remotewrite/client.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5802      +/-   ##
==========================================
- Coverage   60.37%   56.48%   -3.89%     
==========================================
  Files         411      521     +110     
  Lines       76609    71325    -5284     
==========================================
- Hits        46253    40291    -5962     
- Misses      27794    28188     +394     
- Partials     2562     2846     +284     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

valyala added a commit that referenced this pull request Mar 6, 2024
If tlsServerName isn't empty, then it is likely the https request is sent to IP instead of hostname.
In this case the request will fail, since Go automatically sets the Host header to the IP instead
of the desired hostname at tlsServerName. So set the Host header to tlsServerName if itsn't empty.

Updates #5802
valyala added a commit that referenced this pull request Mar 6, 2024
If tlsServerName isn't empty, then it is likely the https request is sent to IP instead of hostname.
In this case the request will fail, since Go automatically sets the Host header to the IP instead
of the desired hostname at tlsServerName. So set the Host header to tlsServerName if itsn't empty.

Updates #5802
@valyala
Copy link
Collaborator

valyala commented Mar 6, 2024

@minor-fixes , thanks for the initial pull request! I implemented it properly at the commit cb25911 . Could you build vmagent from this commit according to these docs and verify whether it works as intended for your use case? If everything is OK, then this commit will be included in the next release.

hardproblems pushed a commit to hardproblems/VictoriaMetrics that referenced this pull request Mar 13, 2024
If tlsServerName isn't empty, then it is likely the https request is sent to IP instead of hostname.
In this case the request will fail, since Go automatically sets the Host header to the IP instead
of the desired hostname at tlsServerName. So set the Host header to tlsServerName if itsn't empty.

Updates VictoriaMetrics#5802
valyala added a commit that referenced this pull request Mar 17, 2024
valyala added a commit that referenced this pull request Mar 17, 2024
@valyala
Copy link
Collaborator

valyala commented Mar 17, 2024

Closing this pull request as obsolete after cb25911

@valyala valyala closed this Mar 17, 2024
possibull pushed a commit to possibull/VictoriaMetrics that referenced this pull request Mar 27, 2024
If tlsServerName isn't empty, then it is likely the https request is sent to IP instead of hostname.
In this case the request will fail, since Go automatically sets the Host header to the IP instead
of the desired hostname at tlsServerName. So set the Host header to tlsServerName if itsn't empty.

Updates VictoriaMetrics#5802
possibull pushed a commit to possibull/VictoriaMetrics that referenced this pull request Mar 27, 2024
possibull pushed a commit to possibull/VictoriaMetrics that referenced this pull request Mar 27, 2024
If tlsServerName isn't empty, then it is likely the https request is sent to IP instead of hostname.
In this case the request will fail, since Go automatically sets the Host header to the IP instead
of the desired hostname at tlsServerName. So set the Host header to tlsServerName if itsn't empty.

Updates VictoriaMetrics#5802
possibull pushed a commit to possibull/VictoriaMetrics that referenced this pull request Mar 27, 2024
@valyala
Copy link
Collaborator

valyala commented Apr 4, 2024

FYI, the commit cb25911 is included in vmagent starting from v1.100.0.

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.

None yet

2 participants