78

I'm in a network using a proxy. I've got machines using lots of scripts here and there accessing each other over HTTP.

  • The network is 10.0.0.0/8.
  • My proxy is 10.1.1.1:81, so I set it up accordingly:

    export http_proxy=http://10.1.1.1:81/
    
  • I want to exclude my own range to be accessed with the proxy. I tried any combination available.

    export no_proxy='10.*'
    export no_proxy='10.*.*.*'
    export no_proxy='10.0.0.0/8'
    

None of the above work!

I'm testing with wget and it always tries to query the proxy, whatever IP address I want to connect to.

  • Since lots of scripts lie everywhere in all systems the --no-proxy option is actually not an option. I want to set it system wide.
0

5 Answers 5

55

You're looking at it the wrong way. The no_proxy environment variable lists the domain suffixes, not the prefixes. From the documentation:

no_proxy: This variable should contain a comma-separated list of domain extensions proxy should not be used for.

So for IPs, you have two options:

1) Add each IP in full:

printf -v no_proxy '%s,' 10.1.{1..255}.{1..255};
export no_proxy="${no_proxy%,}";

2) Rename wget to wget-original and write a wrapper script (called wget) that looks up the IP for the given URL's host, and determines if it should use the proxy or not:

#!/bin/bash
ip='';
for arg; do
   # parse arg; if it's a URL, determine the IP address
done;
if [[ "$ip" =~ ^10\.1\. ]]; then
   wget-original --no-proxy "$@";
else
   wget-original "$@";
fi;
8
  • Thank's a lot, I'm going to wrap my wget (and use hostnames instead of IP addresses).
    – SamK
    Oct 28, 2011 at 14:27
  • 12
    Will having 255*255 addresses in no_proxy risk performance issues?
    – jtpereyda
    Dec 16, 2015 at 22:50
  • @dafrazzman: that could well be. After all, it's almost 800 kilobytes large, which is somewhat extreme for an environment variable. It also depends on how large your environment can be. For this extreme case, I would recommend the wrapper approach.
    – janmoesen
    Jan 21, 2016 at 10:13
  • 7
    Do not add each IP in full - it will be too long and you won't be able to execute any commands in bash.
    – Ross
    Jun 1, 2016 at 18:47
  • 7
    NEVER DO THAT, this will generate something too long for any command, and, if you put this in /etc/environment file, this could break your server. Dec 4, 2017 at 15:56
23

info wget says:

 `no_proxy'
     This variable should contain a comma-separated list of domain
     extensions proxy should _not_ be used for.  For instance, if the
     value of `no_proxy' is `.mit.edu', proxy will not be used to
     retrieve documents from MIT.

So the variable should contain a list of domains, not IP ranges. You'll need to set up proper local aliases for your local machines in /etc/hosts file(s).

Apart from this, bear in mind that setting an environment variable does not guarantee that a proxy will or will not be used. It is just an information that may be used by programs that support it.

1
  • 1
    If wget implements this the same way as curl does – and I suspect it does – then there is no difference if it is IP address or domain name as both are treated as strings – see github.com/curl/curl/issues/1208 Dec 10, 2018 at 15:52
20

Not exactly a correct solution but it might solve the problem for you. If you assume that accessing anything from the outside of the proxy will be using DNS-names and not directly using IP-addresses, you can set it like:

export no_proxy=0,1,2,3,4,5,6,7,8,9

As far as I know, no top domain ends with a number so if it does, it must be an IP-address.

6
  • 7
    That's a very smart solution :) Unfortunately, this will bypass the proxy for any IP, not only for local IPs... :( Is there no way (in 2018) to specify IP ranges or CIDR in the "noproxy" variable? Mar 26, 2018 at 16:19
  • For data center server this is a very clever trick. Has side effect, but acceptable.
    – notes-jj
    Jul 4, 2018 at 17:20
  • 1
    this didn't work for myself .. had to use @iconoclast solution
    – Erik
    Nov 5, 2018 at 7:54
  • It's a real hassle. Not all programs follow these variables Apr 17, 2020 at 8:31
  • 2
    I think you need to use all numbers between 0 and 255 for this to work, otherwise, I think this solution only works for ip's ending in 0 and 9 not 0 and 255. At least your existing solution didn't work for me with curl with an IP ending in 67 until I did this: printf -v no_proxy '%s,' {0..255}; May 8, 2020 at 3:29
15

Here's a slightly simpler (one-line) approach based on janmoesen's solution.

export no_proxy=`echo 10.1.1.{1..255} | sed 's/ /,/g'`

which has been further improved based on Cory Ringdahl's input:

export no_proxy="`echo 10.1.1.{1..254},` 10.1.1.255"

sed chokes on all the arguments passed from the expansion of 10.1.{1..255}.{1..255}, either in his code or mine. So if you really need to expand to 256 * 256 IP addresses, you might be able to further adapt Cory Ringdahl's approach, but if you merely need 256 or so, either of these should work perfectly for you.

I'm guessing the version where 2 octets are expanded would look something like this:

export no_proxy="`echo 10.1.{1..255}.{1..254},` 10.1.255.255"

but iTerm is giving me errors about argument lists being too long, so I can't say for sure whether there is a solution to make this work...

2
  • 2
    Can get around using sed by doing "export no_proxy=`echo 10.1.1.{1..254},`10.1.1.255" Jul 2, 2019 at 18:07
  • Nice... I'm tweaking it a bit to make the spacing consistent after commas, and I'll add it.
    – iconoclast
    Jul 4, 2019 at 1:06
0

no_proxy seems to match the tailing part of a host with at least two chars, so set no_proxy containing 100 tailing part of a ipv4 will skip any ipv4 url

printf -v no_proxy '%s,' {10..99}
export no_proxy=".0,.1,.2,.3,.4,.5,.6,.7,.8,.9,$no_proxy"
curl -v http://any-ip/

Not the answer you're looking for? Browse other questions tagged or ask your own question.