科学上网-零基础搭建个人专线shadowsocks

一、首先购买一个海外vps ,安装centos7系统

VPS有:BandwagonHost,dataocean,vultr,linode。选择服务器地址时,可以先测试一下速度,选速度快的机房。

二、登录vps 并加固

1、利用SSH远程 登入 centos7,方便后续操作。(有些vps的ip可能被屏蔽了,所以需要换一个vps试试看)
SSH远程连接入门

2、加固 centos7 安全性:

(1)、更新centos7系统
(2)、解决系统编码问题
(3)、开启 防火墙。

systemctl start firewalld

(4)、修改SSH默认端口SSH只用密钥登录

3、安装VNC软件,进行远程访问。(可选操作,如果不适应用命令行操作,可以借助vnc 进行远程桌面操作)
(为了提高安全性,使用SSH端口转发,登入服务器)
vnc远程连接配置与入门

三、安装shadowsocks服务端

我们安装的是python版本的。因为centos7 默认自带了 python,所以不需要安装了。如果没有安装的话,可以运行

yum install python

这样子 也可以检查出,是否安装了python。

安装 pip :
1、可以用 VNC 远程登录 vps 主机,然后用浏览器 下载 pip 安装包。
下载页面:https://pypi.org/project/pip/9.0.1/
文件链接地址:https://files.pythonhosted.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz

为什么不选最新版,因为最新版pip 和 python 有一点 兼容性问题。
也可以在SSH中用命令行的方式 下载文件:

curl https://files.pythonhosted.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz -o pip.tar.gz --progress

文件下载完,可以用 VNC 桌面方式进行 解压。或者 在 SSH 中 用命令行 进行解压。

tar zxvf pip-9.0.1.tar.gz -C /root/mydir

将文件 解压到了mydir目录下面。
解压完成后,进入 mydir 文件夹。可以用vnc 直接进入。也可以用命令行

cd /root/mydir

只有进入到 mydir文件夹以后,下面的安装才能成功。
在SSH下或者vnc的终端运行命令行:

python setup.py install

(其实 用命令行 可以直接装 pip,但是安装的是最新版的pip,好像与python存在兼容性问题)

curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py

2.安装 shadowsocks
在SSH或者VNC的终端下运行如下代码:

安装 加密软件 库 用于支持 aes-256-gcm 加密方式 (带#的,都是注释,不需要打 )
 yum install epel-release
 
yum install libsodium
 安装 或升级 最新 软件 版本
 pip install --upgrade git+https://github.com/shadowsocks/shadowsocks.git@master

3.配置shadowsocks
SSH下:

[bash] # 创建 /etc/shadowsocks.json vim /etc/shadowsocks.json [/bash]

上面就创建了配置文件,然后用 vim 编辑 下面内容就行了。

{
"server": "0.0.0.0",
"server_port": 3678,
"password": "sdfsndsfoni",
"method": "aes-256-cfb"
}

多余多个端口可以如下:(顺便说了一下,可以添加PID_FILE和LOG_FILE)

pidfile

{
  "server": "0.0.0.0",
  "port_password": {
        "8850":"hehe2016"
 },
  "method": "aes-256-gcm",
  "PID_FILE": "/var/run/shadowsocks_ssserver.pid",
  "LOG_FILE": "/var/run/shadowsocks_ssserver.log"
}

添加PID_FILE,是因为 执行下面这句话时,需要PID 文件,否则会报错。

ssserver -c /etc/shadowsocks.json -d  stop

这个时候,服务器就可以使用了:

##### 开启 shadowsocks  服务
ssserver -c /etc/shadowsocks.json -d  stop

##### 关闭 shadowsocks  服务
ssserver -c /etc/shadowsocks.json -d  start

后面提到的shadowsocks.service是另一种启动方式。

##### 查看 shadowsocks 状态 
#####(如果 我用ssserver -c /etc/shadowsocks.json -d start 启动,那么这里查看的启动状态是 dead 的,两种启动方法 应该隶属于 不同的管理方式中)
systemctl status shadowsocks

##### 启动 shadowsocks 服务
systemctl start shadowsocks

##### 关闭 shadowsocks 服务
systemctl stop shadowsocks

注意: 加密方式(method),密码(password),服务器端口(server-port)都可以自己设置,只要客户端相同就行。服务器端口 1024以下是系统保留的,从1024-65535是用户使用的。密码 建议选择 aes 系列。method为加密方法,可选aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, chacha20, salsa20, rc4, table

vim编辑器用法可以查看:vim入门基础
VNC桌面环境就直接创建json文件就行了。

4.配置开机自启动。SSH和VNC操作都行。

新建启动脚本文件/etc/systemd/system/shadowsocks.service,内容如下:

[Unit]
Description=Shadowsocks
[Service]
TimeoutStartSec=0
ExecStart=/usr/bin/ssserver -c /etc/shadowsocks.json
[Install]
WantedBy=multi-user.target

然后 , 在SSH或者VNC终端下:输入命令

systemctl enable shadowsocks
systemctl start shadowsocks

为了检查 shadowsocks 服务是否已成功启动,可以继续执行以下命令查看服务的状态:

systemctl status shadowsocks -l 

如果服务启动成功,则控制台显示的信息可能类似这样:

● shadowsocks.service - Shadowsocks
 Loaded: loaded (/etc/systemd/system/shadowsocks.service; enabled; vendor preset: disabled)
 Active: active (running) since Mon 2015-12-21 23:51:48 CST; 11min ago
 Main PID: 19334 (ssserver)
 CGroup: /system.slice/shadowsocks.service
 └─19334 /usr/bin/python /usr/bin/ssserver -c /etc/shadowsocks.json
 Dec 21 23:51:48 morning.work systemd[1]: Started Shadowsocks.
 Dec 21 23:51:48 morning.work systemd[1]: Starting Shadowsocks…
 Dec 21 23:51:48 morning.work ssserver[19334]: INFO: loading config from /etc/shadowsocks.json
 Dec 21 23:51:48 morning.work ssserver[19334]: 2015-12-21 23:51:48 INFO loading libcrypto from libcrypto.so.10
 Dec 21 23:51:48 morning.work ssserver[19334]: 2015-12-21 23:51:48 INFO starting server at 0.0.0.0:8388

不过此时还连接不上服务器,因为CentOS 7默认防火墙是阻止SS端口的,这里需要放行SS端口,由于CentOS 7的防火墙升级为Firewall了,操作方式与之前的iptables有所不同(3678为文中shadowsocks服务器配置端口号,这里要改为你安装SS时设置的端口):
firewall-cmd –permanent –add-port=3678/tcp
firewall-cmd –reload

四、安装kcp加速插件

由于原生shadowsocks速度慢,所以用kcp 插件加速。
访问链接,选择linux-amd64 下载,centos7系统 是 64位的linux系统。
https://github.com/shadowsocks/shadowsocks-windows/releases

解压后有两个文件,其中类似server_linux_amd64这样的文件就是服务端程序了,另一个类似client_linux_amd64的就是客户端程序了。如果客户端在Windows上使用要下载Windows版本的哦。

SSH 里面可以用 tar命令进行解压(前面解压pip文件已经提到过了), ls 命令可以查看 当前目录所有文件 cd 命令表示进入某目录。可以搜索一下bash常用命令操作。
VNC里面直接可视化操作就行了。

先来创建服务端配置文件,创建开机启动项如下供参考:

[bash] vim /etc/systemd/system/kcptun.service [/bash]

然后 配置启动文件如下:

[Unit]
 Description=kcptun
 [Service]
 TimeoutStartSec=20
 ExecStart=/usr/bin/server_linux_amd64 -t "0.0.0.0:3678" -l ":5678" -mode fast2
 [Install]
 WantedBy=multi-user.target

其中TimeoutStartSec为延时启动的时间,这里由于需要等待ShadowSocks启动完成后再启动,所以配置20秒的延迟。ExecStart后的server_linux_amd64为你刚刚下载的文件的位置,建议放到相应的文件夹以便管理。-t后的是服务器的IP和ShadowSocks服务的端口,这里IP配置为本机IP即可。-l表示KCP服务使用的端口,-mode表示速度的模式,从快到慢依次是fast3 > fast2 > fast > normal > default,fast3一般用于游戏,不想要任何的延迟(no lag),但这也意味浪费的流量会增多,这里我选择fast2就够用了。

[bash] systemctl daemon-reload # 创建开机启动 systemctl enable kcptun # 启动kcp服务。 systemctl start kcptun # 防火墙 开放 kcp 端口 (kcp 是 udp 协议,shadowsocks 是tcp协议) firewall-cmd –permanent –add-port=5678/udp # 防火墙 重新 加载 配置 firewall-cmd –reload [/bash]

五、安装客户端

安卓版本:(个人用 3.3.1 版本,因为 好像 不需要 google play 插件吧。并且内置kcp 插件)
https://github.com/shadowsocks/shadowsocks-android/releases
windows版本:
https://github.com/shadowsocks/shadowsocks-windows/releases
需要下载kcp客户端单独进行集成。(Windows-386 32位系统,Windows-amd64 64位系统)
https://github.com/xtaci/kcptun/releases
集成方法可以参考链接:
(总体思路是本地shadowsocks先连接本地的kcptun,然后kcptun 连接 代理服务器的 kcptun,
接着 代理服务器的kcptun 连接 代理服务器的 shadowsocks)
https://blog.csdn.net/farawayzheng_necas/article/details/63255799

mac版本:(内置kcp插件)
https://github.com/shadowsocks/ShadowsocksX-NG
ios版本:
因为大陆已经下架,需要在其他地区搜索:Shadowrocket 等 支持shadowsocks的 应用软件。

之前3.几的安卓客户端,kcp与客户端是集成的,配置文件中,shadowsocks服务器端口就填shadowsocks端口。kcp配置:需要配置kcp端口,kcp参数:

--crypt aes-192 --key "hello"

到了安卓4.x版本,kcp是插件化了。无法启动kcp,可能是1、shadowsocks卸载重装2、手机管家的自启动的链式启动,允许kcptun。

如果要添加kcp插件,那么shadowsocks的端口就要填 kcp的端口,kcp的插件需要配置:[注意与3.x的配置不同,这里的密码,不再需要添加引号了]

key=hello;crypt=aes-192

六、安装obfs 混淆,这个只能与 kcp 二选一

服务器:centos

sudo yum install gcc autoconf libtool automake make zlib-devel openssl-devel asciidoc xmlto

git clone https://github.com/shadowsocks/simple-obfs.git
cd simple-obfs
git submodule update --init --recursive
./autogen.sh
./configure && make
sudo make install

### 会报错 缺少 libev,于是 猜测 shadowsocks libev版本有,
### 于是安装 shadowsocks libev 的依赖库
yum install gcc gettext autoconf libtool automake make pcre-devel asciidoc xmlto c-ares-devel libev-devel libsodium-devel mbedtls-devel -y

服务器配置:

因为是独立模式:vim /etc/systemd/system/obfs-server.service

[Unit]
Description=Simple-obfs
After=network.target

[Service]
Type=simple-obfs
User=nobody
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/obfs-server -s 0.0.0.0 -p 443 --obfs tls -r 127.0.0.1:8866

[Install]
WantedBy=multi-user.target

监听 1024以下端口 需要 root 用户权限,所以采用下面的方法:(应该是绑定服务吧)

setcap cap_net_bind_service=+ep /usr/local/bin/obfs-server
### 最后更新服务并启动:
sudo systemctl enable obfs-server
sudo systemctl daemon-reload
sudo systemctl restart obfs-server

特别注意:复制粘贴时的 问题:【正常情况应该不会出现这个问题,然后我把vim后面的空格给删了,然后用打了一个空格,结果就好了,可以新建文件了】

[root@superguy ~]# vim /etc/systemd/system/obfs-server.service
-bash: vim /etc/systemd/system/obfs-server.service: No such file or directory

这里有编译好的软件可直接放到目标位置  obfs-localobfs-server

有可能 443端口被占用了,导致绑定出错,可以换其他端口再重试。

# 查看端口被占用方法

lsof -i:443

客户端:因为是集成插件模式:

1、客户端连接 服务器 端口 就是 443

2、指定 插件为:  obfs-local【有些地方填:simple-obfs】  ;  并配置插件参数 ,如下面的示例。

--plugin-opts "obfs=tls;obfs-host=www.bing.com"

备注:obfs 类型有 tls和http  主要是 服务器 和客户端 类型要统一。

参考教材:

###Plugin mode with shadowsocks
###Add respective item to --plugin and --plugin-opts arg or as value of plugin and plugin_opts in JSON.

### On the client:

ss-local -c config.json --plugin obfs-local --plugin-opts "obfs=http;obfs-host=www.bing.com"
### On the server:

ss-server -c config.json --plugin obfs-server --plugin-opts "obfs=http"
### Standalone mode
### On the client:

obfs-local -s server_ip -p 8139 -l 1984 --obfs http --obfs-host www.bing.com
ss-local -c config.json -s 127.0.0.1 -p 1984 -l 1080
### On the server:

obfs-server -s server_ip -p 8139 --obfs http -r 127.0.0.1:8388
ss-server -c config.json -s 127.0.0.1 -p 8388

七、nginx与shadowsocks共用443端口伪装

1、shadowsocks 转发给 nginx

最近突发奇想把网站改为https,不可避免的遇到了与shadowsocks的443端口冲突问题(443端口不容易被检出)。废了好大劲才发现原来ss的simple-obfs已经带有非ss流量转发功能。

shadowsocks

# HTTP only with plugin mode
ss-server -c config.json --plugin obfs-server --plugin-opts "obfs=http;failover=example.com:80"

# Both HTTP and HTTPS with standalone mode
obfs-server -s server_ip -p 80 --obfs http -r 127.0.0.1:8388 --failover example.com:80
obfs-server -s server_ip -p 443 --obfs tls -r 127.0.0.1:8388 --failover example.com:443

# suppose you have an HTTP webserver (apache/nginx/whatever) listening on localhost:8080 and HTTPS on 8443
# (you probably shouldn't expose these ports)
obfs-server -s server_ip -p 80 --obfs http -r 127.0.0.1:8388 --failover 127.0.0.1:8080
obfs-server -s server_ip -p 443 --obfs tls -r 127.0.0.1:8388 --failover 127.0.0.1:8443

这样便将web流量转发到了8443端口

nginx

user xx xx;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    types_hash_max_size 1024;

    server {
        listen       80;
        server_name  localhost;
        return       301    https://$host$request_uri;  #redir to https
   #     #charset koi8-r;

   #     #access_log  logs/host.access.log  main;

        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   /usr/share/nginx/html;
        #}

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    server {
        listen       8443 ssl http2;
        server_name  localhost;

        ssl_certificate      /etc/letsencrypt/live/cclin.net/fullchain.pem; #managed by Certbot
        ssl_certificate_key  /etc/letsencrypt/live/cclin.net/privkey.pem; #managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
            uwsgi_pass 127.0.0.1:3031;
            include uwsgi_params;
        }

        }
    #   ssl_session_cache    shared:SSL:1m;
    #   ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    }
}

2、利用nginx转发到shadowsocks

下面的方法 可以 ,即访问网站,同时又 ss。 也就是说 simple-obfs 支持 http代理 转发
server {
    listen       80;
     server_name  localhost;
  # server_name  www.huaijiujia.com;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

        if ($http_upgrade = "websocket") {
             proxy_pass http://127.0.0.1:8443;
        }
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "upgrade";
    }

…..

}

下面的 方法 不行,只能访问 网路,但是无法 使用  ss。也就是说 simple-obfs 不支持 tls 代理 转发

server {
    listen   443  default_server;
    server_name  _;
    ssl_certificate     https_cert/huaijiujia_ca_chained.crt;
    ssl_certificate_key https_cert/huaijiujia_private.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
  #  return 404;
   #   return 301 https://www.amazon.com;
      location = / {
        if ($http_upgrade = "websocket") {
             proxy_pass https://127.0.0.1:8443;
        }
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "upgrade";
    }
   return 301 https://www.amazon.com;
}

因为,安卓手机的功能不完善,不完全支持 simpobfs功能,所以需要重新下个 改进版的。点击下载: Simple-obfuscation-fix


补充:

如果 shadowsocks需要支持 aes-256-gcm加密的话:

For CentOS 7, if you need AEAD ciphers(支持aes-256-gcm加密), you need install libsodium

yum install libsodium python34-pip
pip3 install  git+https://github.com/shadowsocks/shadowsocks.git@master