阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

HTTP/HTTPS自动加密上网方案

35次阅读
没有评论

共计 6171 个字符,预计需要花费 16 分钟才能阅读完成。

方案介绍
涉及到的软件
  1. BIND: 一个流行的域名解析服务器,我们可以设置哪些域名需要走加密线路。
  2. Stunnel: 使用 TLS 对 tcp 协议进行加密,也就是对 tcp 建立一条加密线路。
  3. SNI Proxy: 代理软件。对于 HTTP 协议,它可以根据 Host 请求头解析得出目标站 IP; 对于 HTTPS 协议,它可以根据 SNI 扩展中的域名解析得出目标站 IP。
此方案优缺点

优点:
无需手动设置任何代理,就能够自动加密代理特定网站的 HTTP 或 HTTPS 协议
相对于我们常用的 ssh 隧道,ssh 隧道是单路,而此方案是支持多并发连接,可以极大加速网站访问。

缺点:
对于代理 HTTPS 协议,需要发起 HTTPS 连接的客户端,比如浏览器支持 TLS 的 SNI 扩展。好消息是目前浏览器几乎都支持此扩展,但对于一些非浏览器的客户端,不支持 SNI 扩展。我们只能设置正向代理来解决此问题。

方案原理

流程图:
HTTP/HTTPS 自动加密上网方案
原理介绍:
1、首先我们需要准备三台服务器,一台是内网 DNS 服务器(安装 bind),一台是内网代理服务器(安装 stunnel),另一台国外服务器(安装 stunnel,sniproxy)。
2、我们还需要设置 DNS 为内网的 DNS,并在内网 bind dns 设置谷歌域名解析的 IP 为内网代理服务器
3、当我们访问谷歌网站时,首先会向内网 DNS 服务器发送 DNS A 记录查询,此时内网 DNS 服务器会返回内网代理服务器的 IP。
4、浏览器得到谷歌域名的解析 IP 后(即内网代理服务器的 IP),会向内网代理服务器发送 HTTP 或 HTTPS 请求。
5、此时内网代理服务器(即 stunnel),会接收到请求,经过加密,把请求转发到国外服务器 (stunnel) 的指定端口上。
6、国外服务器 (stunnel) 接收到来自国内服务器 (stunnel) 的加密数据后,经过解密,把请求转发到 sniproxy。
7、sniproxy 再根据 HTTP Host 请求头或者 HTTPS sni 扩展的域名解析出谷歌服务器的 IP,并把请求转发给谷歌服务器。
8、谷歌服务器收到来自 sniproxy 发送的请求后,马上返回网页内容给 sniproxy,sniproxy 再原路返回数据给浏览器。

方案实施

由于时间有限,我们仅在 Ubuntu server 12.04 演示安装。

环境介绍

系统:Ubuntu server 12.04

内网 DNS IP: 10.96.153.201(主),10.96.153.204(从)

内网代理服务器:10.96.153.204

国外服务器 IP: 1.2.3.4

安装 BIND9

1、在主 DNS 和从 DNS 安装 bind, 即 10.96.153.201(主),10.96.153.204(从)。

wget http://www.isc.org/downloads/file/bind-9-10-0b1-2/?version=tar.gz -O bind-9-10-0b1-2.tar.gz
    tar xzf bind-9-10-0b1-2.tar.gz
    cd bind-9-10-0b1-2
    ./configure --prefix=/usr/local/bind
    make && make install

2、配置主 DNS 服务器(10.96.153.201)

2.1、生成 /usr/local/bind/etc/rndc.key 密钥文件

/usr/local/bind/sbin/rndc-confgen -a -k rndckey -c /usr/local/bind/etc/rndc.key

2.2、编辑 /usr/local/bind/etc/named.conf,写入如何内容:

include "/usr/local/bind/etc/rndc.key";
    controls {inet 127.0.0.1 port 953 allow { 127.0.0.1;} keys {"rndckey";}; };
    logging {channel default_syslog { syslog local2; severity notice;};
    channel audit_log {file "/var/log/bind.log"; severity notice; print-time yes;};
    category default {default_syslog;};
    category general {default_syslog;};
    category security {audit_log; default_syslog;};
    category config {default_syslog;};
    category resolver {audit_log;};
    category xfer-in {audit_log;};
    category xfer-out {audit_log;};
    category notify {audit_log;};
    category client {audit_log;};
    category network {audit_log;};
    category update {audit_log;};
    category queries {audit_log;};
    category lame-servers {audit_log;};
    };
    options {
        directory "/usr/local/bind/etc";
    pid-file "/usr/local/bind/var/run/bind.pid";
    transfer-format many-answers;
    interface-interval 0;
    forward only;
    forwarders {202.96.128.166;202.96.134.133;};
    allow-query {any;};
    };
    zone "google.com" {
    type master;
    file "google.com.zone";
    allow-transfer {10.96.153.204;};
    };

在这个 named.conf 文件中,我们只需要关心如下内容:

对于 options{}区域,202.96.128.166 和 202.96.134.133 这两个是 ISP 提供的本地 DNS,需要修改为自己所在 ISP 的本地 DNS。
对于 zone“google.com”{}区域,这里定义了 google.com 域名的区域文件 google.com.zone,还有允许 10.96.153.204(即从 DNS)同步区域文件。

2.3、建立 google.com.zone 区域文件:

$TTL 3600
    @ IN SOA ns1.google.com. hostmaster.google.com. (
    2014072015  ; Serial
    3600 ; Refresh
    900 ; Retry
    3600000 ; Expire
    3600 ) ; Minimum
    @ IN NS ns1.google.com.
    @ IN NS ns2.google.com.
    ns1 IN A 10.96.153.201
    ns2 IN A 10.96.153.204
    @ IN A 10.96.153.204
    * IN A 10.96.153.204

对于这个区域文件:
ns1 IN A 10.96.153.201 指向第一个 dns 服务器,即主 DNS。
ns2 IN A 10.96.153.204 指向第二个 dns 服务器,即从 DNS。
@ IN A 10.96.153.204 和 * IN A 10.96.153.204 指向内网的代理服务器(stunnel)。我们只需要修改这三个地方就好了。

3、配置从 DNS 服务器(10.96.153.204)
编辑 named.conf,写入如下内容

logging {channel default_syslog { syslog local2; severity notice;};
    channel audit_log {file "/var/log/bind.log"; severity notice; print-time yes;};
    category default {default_syslog;};
    category general {default_syslog;};
    category security {audit_log; default_syslog;};
    category config {default_syslog;};
    category resolver {audit_log;};
    category xfer-in {audit_log;};
    category xfer-out {audit_log;};
    category notify {audit_log;};
    category client {audit_log;};
    category network {audit_log;};
    category update {audit_log;};
    category queries {audit_log;};
    category lame-servers {audit_log;};
    };
    options {
        directory "/usr/local/bind/etc";
    pid-file "/usr/local/bind/var/run/bind.pid";
    transfer-format many-answers;
    interface-interval 0;
    forward only;
    forwarders {202.96.128.166;202.96.134.133;};
    allow-query {any;};
    };
     
    zone "google.com" {
    type slave;
    file "google.com.zone";
    masters {10.96.153.201;};
    };

配置从 DNS 就简单得多,只需要写入如上内容到 named.conf 文件。同样的,options{}中 202.96.128.166 和 202.96.134.133 这两个是当地 ISP 本地 dns。zone“google.com”{}中 10.96.153.201 指明主 DNS 服务器 IP。
4、启动 bind dns 服务器

/usr/local/bind/sbin/named
安装 Stunnel

1、在内网代理服务器和国外主机安装 stunnel

apt-get install stunnel4

2、内网代理服务器 stunnel 配置
编辑 /etc/default/stunnel4,设置 ENABLED=1。

client = yes
    pid = /etc/stunnel/stunnel.pid
    [http]
    accept = 80
    connect = 1.2.3.4:8082
     
    [https]
    accept = 443
    connect = 1.2.3.4:4433

此配置文件表示,监听了 80 端口,并把此端口流量转发到 1.2.3.4:8082,监听了 443 端口,并把此端口流量转发到 1.2.3.4:4433

3、国外服务器 stunnel 配置

3.1、生成 ssl 证书 stunnel.pem 文件

openssl genrsa -out key.pem 2048
    openssl req -new -x509 -key key.pem -out cert.pem -days 1095
    cat key.pem cert.pem >> /etc/stunnel/stunnel.pem

3.2、编辑 /etc/stunnel/stunnel.conf 文件

client = no
    [http]
    accept = 1.2.3.4:8082
    connect = 127.0.0.1:8082
    cert = /etc/stunnel/stunnel.pem
     
    [https]
    accept = 1.2.3.4:4433
    connect = 127.0.0.1:4433
    cert = /etc/stunnel/stunnel.pem

此配置文件表示,监听了 1.2.3.4:8082,并转发此地址流量到 127.0.0.1:8082,监听了 1.2.3.4:4433,并转发给地址流量到 127.0.0.1:4433。

3.3、编辑 /etc/default/stunnel4,设置 ENABLED=1。

4、启动 stunnel

service stunnel4 start
安装 sniproxy

sniproxy 项目地址:https://github.com/dlundquist/sniproxy

1、安装 sniproxy
同样只演示在 ubuntu server 12.04 安装。

1.1、安装 UDNS

mkdir udns_packaging
    cd udns_packaging
    wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4-1.dsc
    wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4.orig.tar.gz
    wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4-1.debian.tar.gz
    tar xfz udns_0.4.orig.tar.gz
    cd udns-0.4/
    tar xfz ../udns_0.4-1.debian.tar.gz
    dpkg-buildpackage
    cd ..
    dpkg -i *.deb

1.2、安装 sniproxy

apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre3-dev libudns-dev pkg-config
    wget https://github.com/dlundquist/sniproxy/archive/master.zip
    unzip master.zip
    cd sniproxy-master/
    dpkg-buildpackage
    cd ..
    dpkg -i *.deb

2、配置 sniproxy
/etc/sniproxy.conf 内容如下:

user daemon
    pidfile /var/run/sniproxy.pid
    error_log {
        syslog deamon
        priority notice
    }
    listen 127.0.0.1:8082 {
        proto http
        table http_hosts
    }
    table http_hosts {.*      *:80}
     
    listen 127.0.0.1:4433 {
        proto tls
        table https_hosts
    }
    table https_hosts {.* *:443}

此配置文件表示,监听了 127.0.0.1:8082 地址,并解析 http 协议中的 Host 请求头为 IP,然后转发请求到此 IP; 监听了 127.0.0.1:4433 地址,并解析 TLS 中 SNI 扩展中的域名为 IP,并转发请求到此 IP。

3、启动 sniproxy

sniproxy

结束
到目前为止,我们已经搭建完成了整套 HTTP/HTTPS 加密代理方案。方案中的 HTTP 明文协议,利用 stunnel 使用了 TLS 加密,变成了 HTTPS 协议,使得数据包无法被解析出明文。方案中的 HTTPS 协议,本身是加密的,但为了防止 SNI 扩展的中域名被嗅探,还是走了 stunnel 的加密通道。对于发送 HTTPS 请求而不支持 SNI 扩展的客户端,需要手动设置下代理。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计6171字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中