-
Notifications
You must be signed in to change notification settings - Fork 1.2k
allow specification of source address for probes (icmp, tcp, dns) #262
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
Conversation
|
Addresses the ICMP part of #3. |
|
Hmm. Check failure seems to be unrelated: |
CONFIGURATION.md
Outdated
| [ payload_size: <int> ] | ||
|
|
||
| # The source IP address. | ||
| [ source_address: <string> ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to support the interface name too? If there's DHCP involved you may not know the IP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be possible. Resolve the interface name to interface index first from net.InterfaceByName(), then set IfIndex in the ipv6.ControlMessage struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brian-brazil how about a source_iface attribute in another PR?
config/config.go
Outdated
| PreferredIPProtocol string `yaml:"preferred_ip_protocol,omitempty"` // Defaults to "ip6". | ||
| PayloadSize int `yaml:"payload_size,omitempty"` | ||
| DontFragment bool `yaml:"dont_fragment,omitempty"` | ||
| SourceAddress string `yaml:"source_address,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should apply to all probes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brian-brazil Okay... Added similar code for tcp, http, dns and moved the config to the module.
|
Now also addresses the TCP part of #3. |
example.yml
Outdated
| - expect: "^:[^ ]+ 001" | ||
| icmp_example: | ||
| prober: icmp | ||
| source_address: "127.0.0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's odd that this is in the probe but preferred_ip_protocol is in the module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. But your "This should apply to all probes" made me agree and also implement source-address specification for the other probers. Is it possible (from a configuration compatibility perspective) to pull preferred_ip_protocol up to this level as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'd be a breaking change, so best to keep it consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you propose to move it back into the prober-specific configuration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
prober/http.go
Outdated
| if ip.IP.To4() == nil { | ||
| sourceNetwork = "ip6" | ||
| } | ||
| // Resolve local bind address |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments should end with a full stop
prober/http.go
Outdated
| sourceNetwork = "ip6" | ||
| } | ||
| // Resolve local bind address | ||
| saddr, err := net.ResolveIPAddr(sourceNetwork, module.SourceAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there is no source address configured?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Condition is indeed missing here. Will update soon.
prober/http.go
Outdated
| // stage because of many possible RoundTripper wrappings. | ||
| // Adding this to the prometheus config is an alternative | ||
| // to this wrapper. | ||
| func NewHTTPClientWithLocalAddr(cfg *pconfig.HTTPClientConfig, laddr *net.TCPAddr) (*http.Client, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is duplicating code with common, it'd be better to extend it. Though that code is just about to get redone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So how should we proceed? Skipping source-address config for http prober and contribute to that common code redoings? Http prober can be made source-address-capable once that work is done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting for that work to complete is probably best.
prober/tcp.go
Outdated
| } | ||
|
|
||
| if len(module.SourceAddress) > 0 { | ||
| saddr, err := net.ResolveIPAddr(sourceNetwork, module.SourceAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you resolve this here and not elsewhere? I don't think there's any need to resolve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When module.SourceAddress is an IP-Address already no resolving will happen. In that case net.ResolveIPAddr will just convert to an net.IPAddr. I did not want to prevent names being used as module.SourceAddress so resolving would be necessary.
As to "why here not elsewhere". dialTcp() is the place where the target is resolved as well (chooseProtocol) and resolving in the dial function seems to be aligned with golang dialers in general. Which place do you think would be better suited for resolving?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm saying that in some probes you support dns names and in others you don't. I'm suggesting not supporting it anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh! Actually resolving is in for DNS, TCP and HTTP. Only ICMP (initial PR) is using net.ParseIp.
The resolving also solves the question of using IPv4 or IPv6 which also depends on the target (You need a local v6 address for a v6 target but a v4 address for a v4 taget).
A DNS name could provide v4 and v6 address. Going with IP-addresses only in configuration would require
us to provide both (v4/v6). That is why I concluded that using a resolve-step to be a good idea.
When only an IP address is specified in config there is no resolving happening but only IP parsing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relying on DNS to handle v4 vs v6 is a bit odd to me. I'd expect the user to provide only the address type that they need. Users requiring this are going to have a good idea of how networking works.
|
@brian-brazil please have a look. |
prober/dns.go
Outdated
| // Use configured SourceIPAddress. | ||
| if len(module.DNS.SourceIPAddress) > 0 { | ||
| if srcip := net.ParseIP(module.DNS.SourceIPAddress); srcip == nil { | ||
| level.Warn(logger).Log("msg", "Error parsing source ip address", "srcip", module.DNS.SourceIPAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should fail the probe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to Error and failure in all probes.
prober/dns.go
Outdated
|
|
||
| // Use configured SourceIPAddress. | ||
| if len(module.DNS.SourceIPAddress) > 0 { | ||
| if srcip := net.ParseIP(module.DNS.SourceIPAddress); srcip == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
srcIP would be clearer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack.
prober/icmp.go
Outdated
| level.Warn(logger).Log("msg", "Error writing to socket", "err", err) | ||
| return | ||
| if socket6 != nil && len(module.ICMP.SourceIPAddress) > 0 { | ||
| // Set source address for IPv6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you handling this in a different place than for v4?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for len() > 0 and parse errors is now in common code.
The actual control message is v6 specific.
|
@brian-brazil, last review feedback is addressed. Commits are squashed. Please have a look. |
| s, err := net.ListenPacket("ip4:icmp", "0.0.0.0") | ||
| if err != nil { | ||
| level.Error(logger).Log("msg", "Error listening to socket:", "err", err) | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explicitly returning false would be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. That is not my code. I just moved it. I am fine with doing a cleanup commit but would separate it from this PR.
prober/icmp.go
Outdated
| level.Error(logger).Log("msg", "Error parsing source ip address", "srcIP", module.ICMP.SourceIPAddress) | ||
| return false | ||
| } | ||
| level.Info(logger).Log("msg", "Using source address:", "srcIP", srcIP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be colons in the msg
|
@brian-brazil |
|
Are you sure you pushed your change? I'm still seeing 2 of those. |
This adds the configuration option source_ip_address to modules ICMP, TCP and DNS which changes the probe's local address.
|
@brian-brazil removed two more |
|
Thanks! |
This is a logical continuation of prometheus#262.
This is a logical continuation of prometheus#262. Signed-off-by: Ivan Babrou <[email protected]>
|
I opened #765 for |
This is a logical continuation of prometheus#262. Signed-off-by: Ivan Babrou <[email protected]>
This is a logical continuation of prometheus#262. Signed-off-by: Ivan Babrou <[email protected]>
This is a logical continuation of prometheus#262. Signed-off-by: Ivan Babrou <[email protected]>
For IPv4 raw socket is used and the source IP address is set in the IP header.
For IPv6 a control message (ancillary data / RFC3542) is passed for specifying
the address.