52

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.
  • 1
    It's almost 2019 and no way to put CIDR in no_proxy environment variable? What the hell Linus Torvalds!! – 7_R3X Nov 12 '18 at 7:41
  • 4
    @7_R3X it's GNU wget so I expect you wanted to curse Richard Stallman? – Jakub Bochenski Jan 9 at 15:10
42

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;
  • Thank's a lot, I'm going to wrap my wget (and use hostnames instead of IP addresses). – SamK Oct 28 '11 at 14:27
  • 9
    Will having 255*255 addresses in no_proxy risk performance issues? – jtpereyda Dec 16 '15 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 '16 at 10:13
  • 4
    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 '16 at 18:47
  • 5
    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. – Thomas Decaux Dec 4 '17 at 15:56
16

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.

  • 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 – Piotr Dobrogost Dec 10 '18 at 15:52
12

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...

  • 1
    Can get around using sed by doing "export no_proxy=`echo 10.1.1.{1..254},`10.1.1.255" – Cory Ringdahl Jul 2 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 at 1:06
11

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.

  • 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? – Sorin Postelnicu Mar 26 '18 at 16:19
  • For data center server this is a very clever trick. Has side effect, but acceptable. – notes-jj Jul 4 '18 at 17:20
  • this didn't work for myself .. had to use @iconoclast solution – Erik Nov 5 '18 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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