How to use SOCKS proxy with yum?

Add this line to /etc/yum.conf (got the idea from the post by DaPillow)

proxy=socks5://ip:port

In case host name resolution through proxy is necessary, thanks to Danny from comments this would do it:

proxy=socks5h://ip:port

It worked for me using yum 3.4.3 on Fedora 21.


As pointed out by enzitib,tsocks can be used to use a SOCKS proxy with yum.

To be more detailed, one can use it like this:

$ export TSOCKS_CONF_FILE=$HOME/.tsocks.conf
$ cat .tsocks.conf
server = 127.0.0.1
server_port = 1080
$ tsocks yum ...

By default tsocks uses SOCKS version 4 - but you can configure 5 via the 'server_type' directive. For user/password options there are the 'default_user'/'default_pass' directives and the TSOCKS_USERNAME/TSOCKS_PASSWORD environment variables.


I'm using CentOS6.x with yum-3.2.29-81, curl/libcurl 7.19.7-53 and have this same issue. I have yum servers behind a firewall and want to use yum over a SOCKS5 proxy setup using ssh. Ideally, I want to do this without requiring tsocks, proxychains, or any other "socksification" utilities.

I setup the SOCKS5 connection using:

ssh -D 40000 dmz-server

I poked around in the yum python sources and saw they use pycurl which wraps libcurl (also please note that all proxy environment variables--http_proxy, HTTP_PROXY, all_proxy, ALL_PROXY, etc.--were initially undefined). Furthermore, I verified that ~/.curlrc was empty so it didn't taint my test results.

I wanted to see if I could get curl to talk through the socks5 proxy:

curl --socks5 127.0.0.1:40000 http://some-server/some-url

successfully returned the remote web page, so that was a good sign--showing libcurl can use SOCKS5 proxies. However, defining an environment variable

http_proxy=socks5://127.0.0.1:40000 

wasn't enough:

http_proxy=socks5://127.0.0.1:40000 curl http://some-server/some-url

failed.

At this point, I switched to using a Python test program test.py:

import pycurl
import sys
sys.stderr.write("Testing %s\n" % pycurl.version)
c = pycurl.Curl()
c.setopt(c.URL, 'http://some-server/some-url')
c.setopt(c.WRITEFUNCTION, sys.stdout.write)
c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)
c.perform()
c.close()

Now, running

./test.py

will fail to fetch, but running

http_proxy=socks5://127.0.0.1:40000 ./test.py

will successfully fetch http://some-server/some-url. So it seems to me that this (admittedly ancient) yum/libcurl combination that ships with CentOS6 is not correctly setting the proxy type within libcurl. I think what is happening is that the PROXYTYPE is defaulting to a standard HTTP proxy instead of identifying the socks5:// scheme within the URL specified in the http_proxy environment variable.

In any event, the following patch to /usr/lib/python2.6/site-packages/urlgrabber/grabber.py worked to allow me to access http:// yum repositories through a SOCKS5 proxy. Within PyCurlFileObject#_set_opts(self, opts={}), add:

if self.scheme == 'http':
  proxy = os.getenv('http_proxy') or os.getenv('HTTP_PROXY') or os.getenv('all_proxy') or os.getenv('ALL_PROXY')
  if proxy and proxy.find("socks5://") != -1:
    self.curl_obj.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)

around line 1205, right before

# ssl options
if self.scheme == 'https':

With this change,

http_proxy=socks5://127.0.0.1:40000 yum install <package_name>

successfully connects to all my http:// yum repositories on the other side of the firewall through the SOCKS5 ssh proxy.

Of course, one could export the http_proxy environment variable within one's shell to avoid specifying it before each invocation of yum.

Tags:

Yum