Linux下cURL使用教程之九:代理的使用

这个时代估计很少有人不知道Facebook,也很少有人不知道为啥国内无法直接访问Facebook。
因此,实际应用中,我们会经常使用到代理。
本篇着重讲述在curl命令行中对代理的使用。

代理环境

本篇中,我们将代理分为HTTP代理和socks代理。
可是使用wallproxy+GAE的方式搭建个属于自己的代理,具体请百度或wallproxy官网。wallproxy设置完成后,代理默认为127.0.0.1:8086

选项-x/–proxy

参数格式为: -x/--proxy <proxyhost[:port]>
1、使用指定的HTTP代理
如果未指定端口,默认端口为1080。比如使用我们本机wallproxy搭建的代理:

curl -x 127.0.0.1:8086 -e http://www.ip138.com/ http://iframe.ip138.com/city.asp

即可看到我们的IP变成了代理服务器的IP。

2、此选项优先级高于环境变量中的代理设置。
因此当环境变量中设置使用代理时,可以指定代理为”“而跳过代理。

3、所有通过HTTP代理的操作都会被显示的转化为HTTP,因此某些协议的特殊操作可能无法正常使用。
此问题可以通过使用-p/--proxytunnel选项构建基于代理的通信隧道得到解决。

4、在版本7.14.1之后,可以通过和环境变量相同的方式指定代理。
如使用协议头(http://),或使用内嵌的用户名密码(见下节)。

5、如果有多个-x使用,只有最后一个有效。

6、--proxy1.0 <proxyhost[:port]>
使用HTTP1.0版本的代理。默认使用-x/–proxy时,使用的HTTP/1.1版本的代理。

选项-U/–proxy-user

参数格式为: -U/--proxy-user <user:password>
1、指定用于HTTP代理认证的用户名密码。curl语句如下:

curl -x proxy.xxx.com:8080 -U username:password -e http://www.ip138.com/ \
http://iframe.ip138.com/city.asp

此语句等价于使用内嵌用户名密码的形式:

curl -x 'http://username:password@proxy.xxx.com' -e http://www.ip138.com/ \
http://iframe.ip138.com/city.asp

注:

  • curl中每个需要用户名+密码的参数,你都可以只指定用户名,curl会自动提示你输入密码,这样更安全。
  • 用户名密码中如果有shell特殊字符,如$、引号等,建议放在单引号中,这样不会转义。特殊字符经常造成难以察觉的错误。如密码为$password,则执行以下代码会提示密码错误,因为shell把$password理解为取变量password的值了:
    curl -x http://username:$password@proxy.xxx.com -e http://www.ip138.com/ \
    http://iframe.ip138.com/city.asp

2、如果使用了支持SSIP的curl库而使用NTLM方式认证的话,可以在-U后使用冒号,如”-U :“,从而强制curl从环境中读取用户名密码。

3、同-x,如果有多个-U使用,只有最后一个有效。

认证方式类选项

认证方式介绍请参见HTTP认证模式。

  1. --proxy-anyauth
    让curl自动选择合适的认证方法。这时curl会先发出一次请求来查询认证类型。

  2. --proxy-basic
    让curl使用HTTP基本认证(HTTP Basic authentication)模式与代理服务器通信。这是默认模式。此模式下用户名密码作为明文传递。
    使用–basic选项启用HTTP基础模式。

  3. --proxy-digest
    使用HTTP摘要认证(HTTP Digest authentication)。此模式避免将密码作为明文在网络上传递,相对提高了HTTP认证的安全性。
    使用–digest选项启用HTTP摘要认证模式。

  4. --proxy-negotiate
    使用HTTP协商认证(HTTP Negotiate authentication)。
    使用–negotiate选项启用此模式。

  5. --proxy-ntlm
    使用HTTP NTLM认证(HTTP NTLM authentication)。
    同样,–ntlm启用此模式。

socks代理类选项

因为socks代理与-x选项指定的代理冲突,因此指定socks后,会覆盖掉之前使用-x指定的代理。
同-x,如果多次指定socks代理,只有最后一次有效。
在7.21.7版本之后,可以通过-x使用协议头指定代理类型的方式使用socks代理。

1. --socks4 <host[:port]>

使用socks4代理。
在7.21.7版本之后,可以使用-x socks4:// 代替此参数。
我们可以采用ssh的-D选项构建转发环境搭建socks代理实际测试一下。

1)Linux机器A:10.1.1.2,有PHP服务器,开启ssh
/var/www下新建ip.php:

<?php
$onlineip = $_SERVER['REMOTE_ADDR'];
echo "ip:".$onlineip;
?>

2)Linux机器B:10.1.1.3,已安装curl、ssh客户端
执行

ssh -D 8086 10.1.1.2

开启转发,搭建socks代理
3)机器B
执行

curl http://10.1.1.2/ip.php

可看到本机IP为10.1.1.3。
执行

curl --socks4 127.0.0.1:8086 http://10.1.1.2/ip.php

可看到代理IP为10.1.1.2。

2. --socks4a <host[:port]>

socks4a是socks4的扩展,主要增加了域名解析,其余相同。
--socks4a参数指定使用代理服务器解析域名,其余使用方法相同。
在7.21.7版本之后,可以使用-x socks4a:// 代替。

3. --socks5 <host[:port]>

socks5在socks4的基础上增加了各种验证的支持。参数使用方法相同。
在7.21.7版本之后,可以使用-x socks5:// 代替。

4. --socks5-hostname <host[:port]>

基本同–socks5参数,但是此参数指定使用代理服务器解析域名,而不是本地解析。而–socks5是使用本地域名解析。
在7.21.7版本之后,可以使用-x socks5h:// 代替。

5. --socks5-gssapi-service <servicename>

设置使用gssapi的socks5代理服务器的服务名。

6. --socks5-gssapi-nec

设置对NEC代理服务器的兼容性。

环境变量及相关选项

1. 环境变量

http_proxy [protocol://]<host>[:port]
设置HTTP协议使用的代理,大小写敏感,只能小写。
继续使用wallproxy+GAE搭建的代理,编写脚本curlvariable.sh如下:

#!/bin/sh
export http_proxy=http://127.0.0.1:8086
curl -e http://www.ip138.com/ http://iframe.ip138.com/city.asp;echo

执行bash curlvariable.sh后将会看到ip变成了代理服务器的IP。

其它常用相关环境变量如下:

  • HTTPS_PROXY [protocol://]<host>[:port]
    设置HTTPS协议使用的代理,大小写都可以,小写优先。
  • FTP_PROXY [protocol://]<host>[:port]
    设置FTP协议使用的代理,大小写都可以,小写优先。
  • ALL_PROXY [protocol://]<host>[:port]
    如果某协议没有指定代理,则使用此代理。大小写都可以,小写优先。
  • NO_PROXY <comma-separated list of hosts>
    后跟host(服务器)列表,访问在列表中的host时,不使用代理。如果列表使用通配符”*“,则匹配所有host。

如使用NO_PROXY, 可更改curlvariable.sh如下:

!/bin/sh
export http_proxy=http://127.0.0.1:8086
export no_proxy=ip138.com
curl -e http://www.ip138.com/ http://iframe.ip138.com/city.asp;echo

执行bash curlvariable.sh后将会看到ip不是代理服务器的IP。

2. 命令选项

--noproxy <no-proxy-list>
指定不使用环境变量中代理的host列表
更改curlvariable.sh如下:

#!/bin/sh
export http_proxy=http://127.0.0.1:8086
curl --noproxy ip138.com -e http://www.ip138.com/ http://iframe.ip138.com/city.asp;echo

执行bash curlvariable.sh后将会看到ip不是代理服务器的IP。

总结

本篇主要介绍与代理相关的curl选项。