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.