神楽坂雪紀的投研笔记

呐、现在可以和你见面吗?我、等着你哟......

0%

局域网主机通过内网跳板连接外网的一个方案

故事是这样的,原导师离职,所以更换了导师,加入了一个搞分布式文件系统的课题组。暂时给的课题是先学习 ceph 和 ipfs,并把环境搭建起来分析源码。导师留下了几台电脑没人用,所有就拿过来重整了一下。

本学期校园网打击个人 WiFi 的行为可谓到了极端的地步,根据脚本日志显示,路由器通过 drcom.py 连接的方式平均每天要掉 8 次以上,而且还会每隔十几分钟就中断连接数十秒,真是非常难受了。于是暂时的解决方案是这样的:

上网账号只有一个,只能一台设备登录,让路由器作为登录终端的方式已经逐渐不好用了,这里让实验室的主机登录,寝室的路由器只作为发射 WiFi 之用,无线设备通过 WiFi 连接到校园网,然后通过全局的 shadowsocks 代理到实验室主机,从而实现到外网的连接。基于这个思路,记录一个 Linux 上通过代理连接外网的方案。


数据传递的过程

两台主机分别取名叫 Client 和 SS。其中 SS 是登录了上网账号的主机;Client 是希望被代理的主机。

  1. 首先 Client 将所有 http/https 的数据包转到 socks 协议转发到本机 shadowsocks-local 监听的端口处;
  2. shadowsocks-local 再将接收到的数据转发给 SS 上的 shadowsocks-server 监听的端口;
  3. shadowsocks-server 代理 Client 的数据转发给目的服务器。

http/https 转发到 shadowsocks-local 的配置

Linux:privoxy - 如果系统是 Linux,则可以使用 privoxy 实现 http/https 到 socks 的转发。在 CentOS 中,privoxy 在 epel 软件仓库中,可以通过 yum 直接安装 epel,之后更新包列表,再安装 privoxy 即可:

1
2
3
$ yum install epel-release
$ yum makecache
$ yum install privoxy
- 修改配置文件配置 privoxy,添加如下代码,第一行说明 privoxy 监听本机的 8118 端口,第二行是转发到本机的 1080 端口:
1
2
3
$ vim /etc/privoxy/config
listen-address 0.0.0.0:8118
forward-socks5t / 127.0.0.1:1080 .
- 修改完毕后启动 privoxy 服务:
1
2
$ systemctl enable privoxy
$ systemctl restart privoxy
- 配置 profile 将本机的所有 http/https 转发到 8118 端口,可以修改本用户的环境变量 ~/.bashrc 或 ~/.bash_profile 或者全局环境变量 /etc/profile,添加如下环境变量:
1
2
3
4
$ vim /etc/profile
export http_proxy=http://127.0.0.1:8118
export https_proxy=http://127.0.0.1:8118
$ source /etc/profile
完成以上步骤后即完成了 http/https 转发到 shadowsocks-local 的配置

ssh 的转发配置 上面的配置只能转发 http/https 请求,但是 ssh 并不会被转发,例如 git 只能使用 http 不能使用 ssh 很难受,所以再加个 ssh 的转发。修改 ~/.ssh/config,没有则创建,添加如下代码:

1
2
$ vim ~/.ssh/config
proxyCommand connect -S 127.0.0.1:1080 %h %p
其中在 CentOS 中 connect 需要下载编译,如下:
1
2
3
4
5
$ yum install hg
hg clone https://bitbucket.org/gotoh/connect
cd connect
make # 如果没有安装 gcc 则 yum install gcc 安装之
mv connect /usr/local/bin/connect
以上设置直接将 ssh 的包转发给 shadowsocks-local。

Windows:proxifier 如果系统是 Windows,则可以使用 proxifier 实现全局的转发。


shadowsocks-local 转发到 shadowsocks-server 的配置

  • 安装 pip 并在 pip 中安装 shadowsocks:
    1
    2
    yum install python2-pip
    pip install shadowsocks
  • 添加配置文件如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ vim /etc/shadowsocks.json
    {
    "server":"xx.xx.xx.xx", 运行 shadowsocks-server 的主机 IP 地址
    "server_port":xxx, 运行 shadowsocks-server 的主机监听的端口
    "local_address":"127.0.0.1",
    "local_port":1080, 本地 shadowsocks-local 监听的端口
    "password":"xxxx", shadowsocks-server 上设置的口令
    "timeout":300,
    "method":"aes-256-cfb",
    "fast_open":false,
    "workers":1
    }
  • 启动 shadowsocks-local 服务
    1
    $ nohup sslocal -c /etc/shadowsocks.json 2>&1 /dev/null &
    也可以将 sslocal 注册为 systemd 的服务,添加如下代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ vim /etc/systemd/system/shadowsocks-local.service
    [Unit]
    Description=Shadowsocks Local
    After=network.target
    [Service]
    User=nobody
    Group=nobody
    ExecStart=/usr/bin/sslocal -c /etc/shadowsocks.json
    Restart=on-abort
    [Install]
    WantedBy=multi-user.target
    再通过 systemctl 启动:
    1
    2
    $ systemctl enable shadowsocks-local
    $ systemctl start shadowsocks-local

shadowsocks-server 上的配置

在能够连接外网的主机上,配置 shadowsocks-server 服务,这里仍然采用 pip 提供的 shadowsocks。

  • Linux 上的配置,添加配置文件如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ vim /etc/shadowsocks.json
    {
    "server":"0.0.0.0",
    "server_port":xxx, shadowsocks-server 监听的端口
    "local_address":"127.0.0.1",
    "local_port":12450, shadowsocks-server 对外转发请求时的端口,随便填
    "password":"xxxx", shadowsocks-server 接受 local 连接的口令
    "timeout":300,
    "method":"aes-256-cfb",
    "fast_open":false,
    "workers":1
    }

  • 启动 shadowsocks-server 服务

    1
    $ nohup ssserver -c /etc/shadowsocks.json 2>&1 /dev/null &
    也可以将 ssserver 注册为 systemd 的服务,添加如下代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ vim /etc/systemd/system/shadowsocks-server.service
    [Unit]
    Description=Shadowsocks Server
    After=network.target
    [Service]
    User=nobody
    Group=nobody
    ExecStart=/usr/bin/ssserver -c /etc/shadowsocks.json
    Restart=on-abort
    [Install]
    WantedBy=multi-user.target
    再通过 systemctl 启动:
    1
    2
    $ systemctl enable shadowsocks-server
    $ systemctl start shadowsocks-server

  • Windows 上的配置 同上配置好 shadowsocks.json 文件后,这里采用的批处理脚本启动。新建一个 ssserver.cmd,输入:

    1
    ssserver.exe -c shadowsocks.json
    之后双击启动。


总结

整体组织如下图,有几个比较重要的端口设置。

  1. 首先 ssserver 监听一个端口,将所有发到该端口的数据包进行解包并进行转发;因此 sslocal 就必须要设置正确的服务器 IP 和 端口以及连接的口令。
  2. sslocal 监听本机 127.0.0.1 的某一个端口,将所有转发到该端口的数据包进行加密并发到 ssserver 上;因此 privoxy 和 connect 以及 proxifier 都必须要设置正确的 sslocal 端口,使得能够成功的将数据包转发给 sslocal。
  3. proxifier 可以设置直接将所有 IP 数据包转发给 sslocal,而 privoxy 需要在环境变量中设定代理;connect 也需要在 ssh 的配置文件中指定代理。

(完)