Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-48561

JNLP agent doesn't take into account -Dhttp.nonProxyHosts

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • core, remoting
    • None
    • Jenkins 2.73.3 with remoting 3.10.2 on OracleJDK 1.8

      This is a followup of JENKINS-32326 and JENKINS-32326 which aimed to implement full support of proxy and exclusions list in remoting lib.

       

      Our network is behind a corporate proxy which requires us to properly configure our tools to access Internet.

      For most of our CLI tools, we rely on the no_proxy environment variables to set the list of exclusions. Unfortunately, this variable (and the associated logic) does not support wildcard and can only contain a limited number of chars. That means that we can only whitelist some IP addresses and FQDN.

      For Java-based tool, we use the system property http.nonProxyHosts which is much more convenient since it supports wildcard and regex.

      Our Jenkins agents are executed in environment which contain the aforementioned environment variables, in a JVM with the corresponding system properties as well.

      Some part of the remoting lib seems to give precedence to environment variables over system properties. Meaning that if the master IP address is in the system property but not in the env var, the agent will try to go through the proxy and timeout.

      Test case

      • Command: java -cp /path/to/remoting.jar hudson.remoting.jnlp.Main -headless -url http://172.17.0.1:8080 <agent_secret> <agent_name>
      • System properties:
        • -Dhttp.proxyHost=200.xxx.xxx.xxx
        • -Dhttp.proxyPort=80
        • -Dhttp.nonProxyHosts=172.17.0.1
      • Environment variables:

      Expected behavior

      Agent connects to the master since its IP address is in the exclusion list defined by a system property which has precedence over the corresponding environment variable.

      Issue

      Agent successfully validates the provided credentials and checks that the master is up and running, but timeout when trying to open the JNLP channel.

      Analysis

      ProxySelector.getDefault() resolves to sun.net.spi.DefaultProxySelector which is a basic helper to retrieve all available proxy connections defined with system properties and/or provided by the operating system.

      DefaultProxySelector.select() will return a list of Proxy object which are relevant to the provided URL in argument (e.g. http://172.17.0.1).

      The most important information of the Proxy object is its type which can either be:

      • Type.DIRECT: direct connection to the URL without going through a proxy
      • Type.HTTP: connection through a HTTP proxy
      • Type.SOCKS: connection through a SOCK proxy

      By default, a Proxy has a DIRECT type. The static variable Proxy.NO_PROXY is an alias to the default constructor.

      In JnlpAgentEndpointResolver, when the returned proxy is of type DIRECT, the while loop is terminated: JnlpAgentEndpointResolver#338. When exiting the loop, no value has been assigned to targetAddress which is still equal to null.

      At JnlpAgentEndpointResolver#354, the script fallbacks to the proxy environment variables if targetAddress is still null.

      Unfortunately in our case, DefaultProxySelector.select() will return a unique proxy of type DIRECT because the system property http.nonProxyHosts does contain the URL in argument (172.17.0.1).

      Even if you don't go through the entire logic of DefaultProxySelector.select(), it is fairly easy to draw general conclusion from this test: ProxySelector.getDefault().select(URI.create("http://172.17.0.1:80")) will return:

      • Proxy.NO_PROXY when the system property is not set
      • Proxy.NO_PROXY when the system property is http.nonProxyHosts=172.17.0.1
      • "HTTP @ 200.xxx.xxx.xxx:80" when the system property is http.nonProxyHosts=127.0.0.1

            etiennebec Etienne Bec
            etiennebec Etienne Bec
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: