http代理服务器

作过运维的都知道一个常识,生产环境不可以链接外网,主要仍是为了安全。可是总有链接外网的需求,好比时间同步、镜像站同步、邮件发送、钉钉/微信告警什么的,这些需求每每涉及到多台服务器,咱们不能为这些服务器都开通访问外网的策略,因此最好的作法是将一台服务开通外网访问,其余有外网需求的经过它来上网。linux

这就是典型的代理服务器了,客户端请求发送给代理器,由代理服务器进行转发,而后将响应的内容发送给客户端。能够用于代理服务器的软件有很多,squid 和 goproxy 均可以,它们都是开源软件,也是今天要提到的,它们使用起来都很是简单。git

本次服务器操做系统为 CentOS7。github

squid

squid 是一个 http 代理服务器,它还能够作静态资源的缓存,这里就简单介绍它的代理功能。它能够代理 http 协议,可是 tcp/udp 的就不知道行不行了。不过不要紧,并且这里只是对它略做介绍,毕竟它不是今天的重点。golang

闲话很少说,首先安装:web

yum install -y squid
复制代码

启动并设置开机自启:shell

# CentOS6
/etc/init.d/squid start
chkconfig squid on

# CentOS7
systemctl start squid
systemctl enable squid
复制代码

关闭防火墙和 selinux:macos

# CentOS6
/etc/init.d/iptables stop
setenforce 0

# CentOS7
systemctl stop firewalld
setenforce 0
复制代码

默认监听端口为 3128,确保未被其余服务所监听。OK,服务端就配置好了,如今客户端就能够经过它来上网了。客户端要怎么配置呢?很是简单,Linux 上只须要配置 http_proxy 这个环境变量便可。vim

你先登陆一台须要上网的 Linux 服务器(确保它能够链接 squid 所在服务器),执行以下命令(将 SERVER_IP 替换成 squid 所在服务器 ip):windows

export http_proxy=SERVER_IP:3128
export https_proxy=SERVER_IP:3128
复制代码

配置两个环境变量,一个是 http 协议,一个是 https 协议,表示在当前 shell 环境下面启动的全部服务、命令等发送的 http/https 请求都转发给代理服务器,由代理服务器帮忙请求。而后就能够测试了:缓存

curl www.qq.com
复制代码

会返回 302,表示链接成功。

squid 配置文件为 /etc/squid/squid.conf,从中能够看到这样的内容:

acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

http_access allow localnet
复制代码

从中能够看出,三个基本的内网网段均可以经过代理上网。若是有其余需求,能够自行修改,改完后记得重启 squid 服务。OK,关于 squid 的内容就这么多了,它毕竟不是专门作代理上网的软件,只是它安装方便、使用简单、知名度广、资格够老因此就顺便提提,重点仍是 goproxy。

goproxy

goproxy 是国内做者开发的开源的、专业的代理软件。做者的简介是:golang 实现的高性能 http、https、websocket、tcp、防污染 DNS、socks5 代理服务器,支持内网穿透、链式代理、通信加密、智能 HTTP/SOCKS5 代理、域名黑白名单、跨平台、KCP 协议支持、集成外部 API。

单从代理这块,它能够实现了 squid 作不到的功能有:

  • 全平台:windows/macos/linux 都一网打尽;
  • 限速:这个功能虽然不起眼,可是很是有用,尤为针对大量请求好比镜像站同步时很是有用,你不能由于你搞同步就把带宽打满了吧,那你公司还开不开了?
  • tcp 代理:光是 http 代理并不能知足需求,好比邮件/smtp、ftp 等都不是 http;
  • udp 代理:这就更不用说了,dns、ntp 走的都是 udp,没它不行。tcp+udp 基本上就知足了全部应用的代理需求了;
  • 多级代理:这个看起来好像也用不着,可是你想要生产环境实现科学上网就得靠它。
  • https:这个并非代理 https 协议啊,而是这个代理到另外一个代理服务器之间的通讯内容都是经过 ssl 加密的。通常用不上,使用它和多级代理能够实现生产环境科学上网。

安装

它的安装很是简单,由于是 go 语言写的,它只依赖 glibc 而不限 Linux 发行版。因此只要 glibc 版本够了,任何 Linux 发行版使用的二进制文件都同样,固然 windows 和 macos 因为操做系统不同,版本确定也是不同的。这里只针对 Linux,若是有想法也能够在其余操做系统上运行,用法都同样。

做者提供了一键安装的脚本,可是须要你服务器能够科学上网才行,若是能够你能够直接使用:

curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.sh | bash
复制代码

不行的话,你就只能手动下载安装了。首先来到项目主页,点击 release,选择最上面也就是最新版本,点击 linux-amd64 进行下载。注意是 amd 而不是 arm,它们的 CPU 架构不一样,通常服务器都是 x86 也是 amd 架构,其余 Linux 架构不用管。若是 32 位系统选择 32 位便可。

若是是 MacOS 选择 darwin,windows 就选 windows,这些就很少提了。下载完成后随便放在哪一个目录,并在当前目录下执行下面的命令便可:

tar zxvf proxy-linux-amd64.tar.gz
cp proxy /usr/bin/
chmod +x /usr/bin/proxy
if [ ! -e /etc/proxy ]; then
    mkdir /etc/proxy
    cp blocked /etc/proxy
    cp direct  /etc/proxy
fi

if [ ! -e /etc/proxy/proxy.crt ]; then
    cd /etc/proxy/
    proxy keygen -C proxy >/dev/null 2>&1
fi
rm -rf /tmp/proxy
echo "install done"
复制代码

不排除这个脚本再也不适用于之后的版本,一切仍是以官方文档为准,反正都有中文,看着也不费事。安装完成后 proxy 命令就可使用了(确保系统上以前没有这个命令),代理服务就经过这个命令启动,输入 proxy help 就能看出这个命令的帮助信息了。

启动

官方文档说的还比较详细,咱们就拿 http 代理举例,相信看完以后,tcp/udp 等代理你也会了。

首先启动 http 代理服务:

/usr/bin/proxy http -t tcp -p :2121
复制代码

这就启动服务,而且监听在 tcp 2121 端口了,服务端也就完成了。客户端的使用方式和 squid 同样,只不过要将 3128 端口换成这里的 2121。

限速

到这里代理服务器的就已经完成,下面提到的都是一些扩展的内容了。限速很是简单,使用 -l 选项指定便可,好比 100K 2M 等,0 意味着无限制。做者举例使用了 1.5M,你们不要这么加 .,使用 1M 或者 2M 代替,否则会报错。

/usr/bin/proxy http -t tcp -p :2121 -l 2M
复制代码

表示将速度限制在 2MB/s,可使用 dstat 命令进行验证。

认证

goproxy 启动以后,默认什么人均可以使用它进行代理,若是你以为不安全,可使用 basic 认证。虽然 basic 认证不安全,抓包以后 base64 解码下就能拿到用户名密码,可是聊胜无于。使用方式为经过 -a 指定用户名和密码,文档在这里

固然这种方式只能针对 http 代理,由于只有 http 协议才支持 basic 认证。

service 文件

上面的启动方式服务会运行在前台,虽然可使用 & 能够将之放入后台,可是咱们彻底可使用 systemd 对其进行管理。CentOS7 使用 systemd 代替了 init,所以咱们可使用 systemd 来管理 proxy 的启动和中止。

首先建立 service 文件:

# vim /etc/systemd/system/proxy.service
[Unit]
After=network.target

[Service]
ExecStart=/usr/bin/proxy http -t tcp -p :2121 -l 2M

[Install]
WantedBy=multi-user.target
复制代码

而后启动:

systemctl daemon-reload
systemctl start proxy
systemctl enable proxy
复制代码

systemd 会自动将服务置于后台运行,proxy 输出的日志能够这个查看:

journalctl -u proxy
复制代码

journalctl 命令还有不少用法,这里就很少提了。

goproxy 的用法就这么多了,至于科学上网这里就很少提了,反正很简单,只须要注意两个代理服务器之间要使用 ssl 加密。

Linux 客户端使用

服务器搭建完成以后,那就要在客户端使用起来了。前面讲到了使用 http_proxy/https_proxy 进行代理上网的方式,这也是最经常使用的方式,不过它也有些注意事项。

咱们使用 ssh 登陆到服务器以后,就至关于开启了一个 shell,咱们在当前 shell 下设置的环境变量 export http_proxy=SERVER_IP:3128 只对当前 shell 有效,在其余 shell 下是没有效果的。所以当你要启动一个要进行 http 代理的服务以前,能够先使用 echo $http_proxy 查看环境变量是否设置,只有设置了服务才能加载到。

不建议将其写入到 /etc/profile /etc/bashrc 等这样的文件让其永远生效,由于难保服务器上还会跑其余应用,而这个应用不须要走代理。真遇到这样的状况,排查起来也蛮费劲的。

最好的解决办法是使用一个脚原本封装服务的启动命令,将环境变量配置到脚本中,这样就不会产生干扰。

与 http_proxy 对应的是 no_proxy,咱们虽然可使用不一样的 shell 来区别哪些应用使用代理,哪些不使用。可是不免会有这么一个需求:一个应用会发出多个 http 请求,其中有一个不能使用代理,其余请求要使用代理。面对这样的状况,只能使用 no_proxy 这个环境变量了,它用来排除不使用代理请求的 ip。它的是一个一堆用逗号分隔的 ip 列表,不能使用网段,不能使用域名。

好比咱们访问 10.0.0.1 和 10.2.2.2 不使用代理,就能够这么作:

export no_proxy="10.0.0.1,10.2.2.2"
复制代码

有些应用启动时不会加载 http_proxy 这样的环境变量(好比 jenkins、Maven),即便你配置了也没用。面对这样的状况不要慌,服务自己是会提供配置代理的方式的。好比 jenkins 会在插件管理中提供,Maven 会经过配置文件提供。

还有一点须要注意的是,使用 systemd 启动的服务一样不会加载系统环境变量,它自己和 shell 就没啥关系。这时你就能够在 service 文件中进行配置。

[Service]
Environment="https_proxy=SERVER_IP:2121"
复制代码

在 Service 下面这么配置就行。

windows 客户端

windows 上的软件基本上均可以配置代理,设置里面找找 http 代理就能够,输入 ip 和端口、用户名和密码(如何设置了的话)。若是你想设置全局代理,也就是系统级别的话,在 win10 上是在网络 -> 网络和 Internet -> 代理 -> 手动设置代理。和 Linux 同样,有些软件可能不吃这一套,你还得去软件中设置。

我的用户在 windows 上使用仍是科学上网居多。