diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 00000000..5d9a1d10 --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,17 @@ +name: 'Shellcheck' + +on: + push: + pull_request: + branches: + - master + +jobs: + shellcheck: + name: Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@master \ No newline at end of file diff --git a/README.md b/README.md index 9ef29bfb..0b91da42 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,146 @@ -# 科学上网 +
If you see this page, the nginx web server is successfully installed and +working. Further configuration is required.
+ +For online documentation and support please refer to
+nginx.org.
+Commercial support is available at
+nginx.com.
Thank you for using nginx.
+ + ``` +然后,在 Gost 的启动上加上这个参数:`probe_resist=file:/var/www/html/index.html`,这样,当有人探测你的端口的时候,会返回这个文件的内容,这样,就会让探测者以为你的端口是一个 Web 服务器,而不是一个代理服务器。 -## 4. 客户端设置 +完整的启动脚本如下: + +```bash +#!/bin/bash + +# 下面的四个参数需要改成你的 +DOMAIN="YOU.DOMAIN.NAME" +USER="username" +PASS="password" +PORT=443 + +BIND_IP=0.0.0.0 +CERT_DIR=/etc/letsencrypt +CERT=${CERT_DIR}/live/${DOMAIN}/fullchain.pem +KEY=${CERT_DIR}/live/${DOMAIN}/privkey.pem +sudo docker run -d --name gost \ + -v ${CERT_DIR}:${CERT_DIR}:ro \ + --net=host ginuerzh/gost \ + -L "http2://${USER}:${PASS}@${BIND_IP}:${PORT}?cert=${CERT}&key=${KEY}&probe_resist=file:/var/www/html/index.html&knock=www.google.com" +``` + +## 7. 针对 IP 被封的解决方案 + +花钱购买的 VPS 即便做了流量伪装依然有很大的几率 IP 被封锁,大多 VPS 服务商并不提供更换 IP 的服务,使用 CDN 可以让被封锁的 VPS 继续发挥翻墙功能。 + +Cloudflare 是一个 CDN 服务商,目前国内依然能正常的访问,可以作为跳板来实现翻墙。 + +注册 Cloudflare 帐号,并有一个空闲域名( 需要使用二级域名),交给 Cloudflare 托管并将域名指向被封的 VPS IP。Cloudflare 只需免费方案足以,不必花钱。 + +使用 Cloudflare 进行套壳需要有如下的条件: + +- 无论是 V2Ray 还是 gost,都需要使用 WebSocket 传输协议 +- Cloudflare 的端口号只能代理有限的几个, 推荐使用: `80`, `8080`, `443` 或 `8443` +- 客户端这边需要使用对应的客户端,比如 gost 或 v2ray 的客户端进行 WebSocket 的连接 + +关于优选IP,可以手动更改本地hosts文件指向最佳IP。 + +目前支持 WebSocket 的免费 CDN 似乎只有 Cloudflare 一家,国内 CDN 服务商既不支持也不安全,不要考虑了。如果有更好的服务商欢迎补充。 + +网络延迟比直连增加不少,如果是频繁操作会很痛苦。网络带宽如果运气好可能比直连还优化了,用来看 Youtube 搞不好更流畅。 + +## 8. 家用透明网关 + +### 8.1 OpenWRT 路由器 + +所谓透明网关的意思是,一切都交给网关来做。最好的方式是你需要一个 OpenWRT 的路由器,推荐使用华硕的路由器,贵是贵一些,但是这几年用下来,非常不错。我用的是 **华硕(ASUS) RT-AC68U 1900M AC 双频智能无线路由路** 。 + +路由器买来后,要刷一下固件。首先 Asuswrt 是华硕公司为他的路由器所开发的固件。Asuswrt-merlin是一个对Asuswrt固件二次开发进行各种改进和修正的项目。源代码在这里:[https://github.com/RMerl/asuswrt-merlin](https://github.com/RMerl/asuswrt-merlin) + +不必担心把路由器刷废了,华硕的路由器可以让你一键重置回来 + +**1)下载固件**。先到 [https://www.asuswrt-merlin.net/download](https://www.asuswrt-merlin.net/download) 下载相应的固件,并解压。(我下载的是 `RT-AC68U_380.61_0.zip` ) + +**2)升级固件**。登录到你的路由器后台 `http://192.168.1.1/` ,在 `系统管理` -> `固件升级` 中上传固件文件(我上传的是:`RT-AC68U_380.61_0.trx`) + +**3)打开 JFFS 分区**。`系统管理` -> `系统设置` -> `Persistent JFFS2 partition` + +- `Format JFFS partition at next boot` - `否` +- `Enable JFFS custom scripts and configs` - `是` + + +**4)打开 ssh 登录**。 `系统管理` -> `系统设置` -> `SSH Daemon` + +- `Allow SSH password login` - `是` + + +接下来,在 WiFi 路由器上安装 Clash,就可以了。 -### 4.1 gost 客户端 +大概的示意图如下所示。 -大多数的代理服务都支持 https 的代理,但是我们需要智能代理(也就是该翻的时候翻,不用翻的时候不翻),那么我们可以重用 Shadowsocks 的客户端。 +``` + Phone/PC/Pad (无需设置) + │ + │ + │ 1 + │ + ┌────────▼──────┐ + │ │ + │ WiFi Router │ (安装 Clash 网关) + │ │ + └─────┬────┬────┘ + │ │ + │ │ 2 + │ └────────► 墙内 - China LAN + 3 │ + ┌─────▼──────┐ + │ VPS │ + │ Proxy │ + └─────┬──────┘ + │ + │ + ▼ + 墙外 - Internet WAN + +``` + + +### 8.2 通过树莓派做旁路网关 + +如果你的路由器不能刷 OpenWRT,也就是没法通过SSH登录上去装软件,你就用一个别的设备。比如用一个树莓派。我正好有一个很老旧的树莓派,刷了一个老旧的 Debian 7.5的操作系统。 + +把它连上你的路由器上,然后, +- 你需要把你设备上的IP地址、网关和DNS服务器都要手动设置到这个树莓派上。 +- 于是,所有的路由就会通过路由器转到树莓派上,再由树莓派决定是否要走代理。 + +大概的示意图如下所示。 + +- 1 --> 2 是设备把所有的请求都发给树莓派。 +- 3 --> 3.1 或 3.2 是由树莓派来决走是否翻墙。 + +``` + Phone/PC/Pad (设置"网关"和"DNS"为树莓派) + │ + │ + │ 1 + │ (安装 Clash 网关) + ┌────────▼──────┐ 2 ┌───────────┐ + │ ├──────────────► │ + │ WiFi Router │ │ 树莓派 │ + │ ◄──────────────┤ │ + └─────┬────┬────┘ 3 └───────────┘ + │ │ + │ │ 3.2 + │ └────────► 墙内 - China LAN + 3.1 │ + ┌─────▼──────┐ + │ VPS │ + │ Proxy │ + └─────┬──────┘ + │ + │ + ▼ + 墙外 - Internet WAN + +``` + +### 8.3 安装 Clash + +Clash 的 Github项目是:[Dreamacro/clash](https://github.com/Dreamacro/clash) ,在它的 Release 页面上,你可以找到相关的下载。(注:在本文更新的时候,如果你需要支持 Tun,你需要下载 Clash 的 [Premium 版本](https://github.com/Dreamacro/clash/releases/tag/premium) + +Clash 支持很多翻墙协议:ShadowSocks(R), Vmess, Socks5, HTTP(s),Snell,Trojan。 + +在你的 OpenWRT 或 树莓派 下用 `uname -m` 查看一下你的硬件架构是什么的,比如,我的是华硕和树莓派都是 `armv7l` 的,所以,需要下载 `clash-linux-armv7-....`的版本(注:根据 clash 官方仓库 [Dreamacro/clash#189](https://github.com/Dreamacro/clash/issues/189) 系列固件不适用 armv7l 架构的 AC68U,需选择 armv5)。 下载完解压后,加个可执行权限 `chmod +x clash` 就可以运行了,不过,还差一个界面和两个配置文件,它们的目录关系如下: + +``` +├── clash <- 建一个 clash 的目录 +│ ├── clash <- 运行文件 +│ ├── config.yaml <- 配置文件 +│ ├── Country.mmdb <- IP地址库 +│ └── ui <- Clash 的 UI +│ ├── index.html +│ ├── ... +``` + +- UI界面可以到 [haishah/yacd](https://github.com/haishanh/yacd) 下载。放到clash的配置目录下 `ui` 目录下 + +- 一个是 `Country.mmdb` 这是IP地址的在哪个国家的数据库。你需要到这里下载 - [Country.mmdb](https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb) (当然,clash启动时,会自动下载,我这里给你一个手动下载的链接) + +- 另一个是 `config.yaml` 文件,这个文件详细解释可参看 - [官方Wiki](https://github.com/Dreamacro/clash/wiki/configuration) + + +下面是个示例: + +```yaml +port: 7890 +socks-port: 7891 +redir-port: 7892 +mixed-port: 7893 +ipv6: false +allow-lan: true +mode: Rule +log-level: info +external-controller: '0.0.0.0:9090' +external-ui: ui +secret: '' +tun: + enable: true + stack: system + dns-hijack: + - tcp://8.8.8.8:53 + - udp://8.8.8.8:53 +dns: + enable: true + ipv6: false + listen: 0.0.0.0:53 + default-nameserver: + - 114.114.114.114 + #enhanced-mode: redir-host + enhanced-mode: fake-ip #如果要玩netflix,需要使用fake-ip + fake-ip-range: 198.18.0.1/16 + nameserver: + - 114.114.114.114 + - 223.5.5.5 + - tls://8.8.8.8:853 + fallback: + - tls://8.8.8.8:853 + +# 两个代理服务器 +proxies: + # http + - name: "https01" + type: http + server: https.server.domain + port: 443 + username: user + password: "password" + tls: true # https + skip-cert-verify: true + - name: "https01" + type: http + server: https.server.domain + port: 443 + username: user + password: "passowrd" + tls: true # https + skip-cert-verify: true + +# 配置 Group +proxy-groups: + # 自动切换 + - name: "auto" + type: url-test + proxies: + - us01_https + #- us02_https + #- hk_https + # tolerance: 150 + url: 'https://www.google.com/' + interval: 300 + # 按需选择 - 可以在UI上选择 + - name: "netflix" + type: select + proxies: + - us01_https + - us02_https + - hk_https + +rules: +# LAN + - DOMAIN-SUFFIX,local,DIRECT + - IP-CIDR,127.0.0.0/8,DIRECT + - IP-CIDR,172.16.0.0/12,DIRECT + - IP-CIDR,192.168.0.0/16,DIRECT + - IP-CIDR,10.0.0.0/8,DIRECT + +# Netflix + - DOMAIN-SUFFIX,fast.com,netflix + - DOMAIN-SUFFIX,api-global.netflix.com,netflix + - DOMAIN-SUFFIX,netflix.com,netflix + - DOMAIN-SUFFIX,netflix.net,netflix + - DOMAIN-SUFFIX,nflxext.com,netflix + - DOMAIN-SUFFIX,nflximg.com,netflix + - DOMAIN-SUFFIX,nflximg.net,netflix + - DOMAIN-SUFFIX,nflxso.net,netflix + - DOMAIN-SUFFIX,nflxvideo.net,netflix + +# 最终规则(除了中国区的IP之外的,全部翻墙) + - GEOIP,CN,DIRECT + - MATCH,auto -对于电脑来说,你同样可以 [下载 gost 程序](https://github.com/ginuerzh/gost/releases),然后使用下面的命令行: +``` +更多的规则网上可以找到很多,也可以参看这里:[SS-Rule-Snippet/LAZY_RULES/clash.yaml](https://github.com/Hackl0us/SS-Rule-Snippet/blob/master/LAZY_RULES/clash.yaml) + +这个时候你就可以启动 clash 了: +```shell +/path/to/clash/cash -d /path/to/clash & ``` -gost -L ss://aes-128-cfb:passcode@:1984 -F 'https://USER:PASS@DOMAIN:443' + +然后,你就可以把你的上网设备上的 路由网关 和 DNS 服务器都手动地配置成这个网关就好了(OpenWRT应该不用配置了,树莓派的方式需要手动配置一下) + +### 8.4 设置 `iptables` 转发 + +```shell +iptables -t nat -N CLASH +iptables -t nat -A CLASH -d 10.0.0.0/8 -j RETURN +iptables -t nat -A CLASH -d 127.0.0.0/8 -j RETURN +iptables -t nat -A CLASH -d 169.254.0.0/16 -j RETURN +iptables -t nat -A CLASH -d 172.16.0.0/12 -j RETURN +iptables -t nat -A CLASH -d 192.168.0.0/16 -j RETURN +iptables -t nat -A CLASH -d 224.0.0.0/4 -j RETURN +iptables -t nat -A CLASH -d 240.0.0.0/4 -j RETURN +iptables -t nat -A CLASH -p tcp -j REDIRECT --to-ports 7892 ``` -这样用 gost 在你的本机启动了一个 `Shadowsocks` 的服务,然后,把请求转到你在上面配置的 HTTPS服务器上,这样就完成转接。 +然后,你可以保存一下这些 iptables 的规则 + +```shell + iptables-save > /etc/iptables.up.rules +``` +编辑 `/etc/network/if-pre-up.d/iptables`,在网卡启动的时候加载这些规则 + +```shell +#!/bin/sh +/sbin/iptables-restore < /etc/iptables.up.rules +``` +然后,再 `chmod +x /etc/network/if-pre-up.d/iptables` 加上可执行权限就好了。 + +## 9. 数据中心透明网关 + +这里仅针对 AWS 进行说明,其它云平台应该大同小异,大家可以补充。 -你的ShadowSocks客户端只需要简单的配置一个本机的 SS 配置就好了。 +### 9.1 AWS 网络构建 + +1. 构建一个 `172.20.0.0/16` 的 VPC,分成两个子网: + - 有公网IP的公有子网 - `172.20.1.0/24` + - 无公网IP的私有子网 - `172.20.2.0/24` + +2. 在公有子网里创建 [EC2 NAT Instance](https://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/VPC_NAT_Instance.html) + - 创建时,指定私网IP为 `172.20.1.1` + - (Option)为该实例分配弹性IP,可成为外网访问内网的跳板机 + +3. 建立路由规则 + - 创建“互联网网关”,并把“互联网网关”添加到公有子网 `172.20.1.0/24` 的路由表中 + - 把 EC2 NAT Instance `172.20.1.1` 添加到私有子网`172.20.2.0/24`的路由表中。 + +于是整个网络就如下所示。 + +``` + ┌──────────┐ + │ │ + │ │ + └──────────┘ + 弹性IP 互联网网关 + ┌───────────────┐ ▲ + │xxx.xxx.xxx.xxx├─┐ │ + └───────────────┘ │ ┌───────────┘ + │ │ + ┌───────┼──┼────────┐ ┌───────────────────┐ + │ │ │ │ │ │ + │ ┌─┴──▼──┐ │ │ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │ + Public Network │ │ │◄────┼───┬───┼─►└─┘ └─┘ └─┘ └─┘ │ Private Network + │ └───────┘ │ │ │ │ + │ EC2 NAT Instance │ │ │ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │ + │ 172.20.1.1 │ ├───┼─►└─┘ └─┘ └─┘ └─┘ │ + │ │ │ │ │ + │ (NAT Instance) │ │ │ ┌─┐ ┌─┐ ┌─┐ │ + │ │ └───┼─► └─┘ └─┘ └─┘ │ + │ │ │ │ + └───────────────────┘ └───────────────────┘ + + 172.20.1.0/24 172.20.2.0/24 + ▲ ▲ + subnet │ │ subnet + │ │ + └────────── VPC ───────────┘ + 172.20.0.0/16 +``` + +注:你需要认真的按照 [EC2 NAT Instance](https://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/VPC_NAT_Instance.html) 的文档进行设置这个NAT实例。尤其需要设置下面几项: + +```shell +sudo sysctl -w net.ipv4.ip_forward=1 +sudo iptables -A FORWARD -i eth0 -j ACCEPT +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +``` +顺便科普一下: -对于手机端,我带用的是iPhone下的 `Potatso Lite` 和 `ShadowRocket` 这两个APP直接支持 HTTPS 的代理,配置上就好了。 +- `net.ipv4.ip_forward` 是内核参数,主要是用来把Linux当成路由器来用的参数。一般来说,一个路由器至少要有两个网络接口,一个是WAN,的一个是LAN的,为了让LAN和WAN的流量相通,需要进行内核上路由。 +- `iptables -A FORWARD -i eth0 -j ACCEPT` 通行所有需要转发的包,只有机器成为一个路由器时,需要在两个网卡间进行网络包转发时,才需要配置这条规则。 +- `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE` 关键字 `MASQUERADE` 意思是“伪装“,NAT的工作原理是就像是一个宿舍收发室对学生宿舍一样,学生宿舍的地址外部不可见,邮递员只看得见整栋宿舍收发室的地址,邮递员把快递交给收发室,收发室再把快递转给学习宿舍(反之,如果学生要对外寄邮件,也是先到收发室,收发室传给邮局)。现在的问题是,所有的学生宿舍如何才能参与到任何快递的通信中,如果把学生宿舍地址发到外部,则没人能把信送回来。如果这个收发室是个自动化的机器人,他要干的事就是,把学生宿舍的地址换成收发室地址。这就是 `MASQUERADE` 的意思——**来自具有接收方 IP 地址的本地网络到达 Internet 某处的数据包必须进行修改,也就是让发送方的地址等于路由器的地**址。 -### 4.2 Shadowsocks 客户端 +### 9.2 安装 Clash -对于 Shadowsocks 客户端,可以到这里查看 [Shadowsocks Clients](https://shadowsocks.org/en/download/clients.html) +在 EC2 NAT Instance 上安装 clash 透明网关,安装配置参看 [8.3 安装 Clash](#83-安装-clash) ,基本一致。 -- MacOS 上你可以下载 [ShadowsocksX-NG](https://github.com/shadowsocks/ShadowsocksX-NG/releases) -- Windows上你可以下载 [Shadowsocks-Windows](https://github.com/shadowsocks/shadowsocks-windows/releases),需要先安装 [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework-runtime) -- Android的客户端,你可以用手机访问并下载 [Shadowsocks-Android](https://github.com/shadowsocks/shadowsocks-android/releases) -- iPhone 端就比较麻烦了。因为国内全都被下架了。 - 1. 你需要注册一个美国的苹果ID. - 2. 然后 iTunes/App Store 用这个美区的ID登录(不是退出iCloud ,而是退出App Store) - 3. 然后搜索 `Potatso Lite` ,`ShadowRocket`, `Wingy`, `Quantumult` 等。(我使用前两个) +> 注:在实际操作中,没有设置 `iptables` 转发规则 -> **注意** + +### 9.3 配置私有子网中的 EC2 + +只需要配置 `/etc/resolv.conf` 文件,把 EC2 NAT Instance 加入其中。如: + +```conf +# /etc/resolv.conf +nameserver 172.20.1.1 #<--- 透明网关 EC2 NAT 实例 +nameserver 172.20.0.2 #<--- AWS 的 DNS 服务 +search [zone].compute.internal +``` +> **Note** +> +> 新版的 Ubuntu 已经把 DNS Resolver 托管给了 systemd 的 `systemd-resolved` 服务,所以需要把 `/etc/resolv.conf` 文件改成软链接,指向 `systemd-resolved` 的配置文件,如: +> +> ```bash +> sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +> ``` > -> - 关于如何注册美区Apple ID账号,你可以参看如下的这几篇文章(我不保证这些文章可不可用,但是你可以自行Google)。 -> - [5分钟注册美国区Apple ID(18年亲测有效)](https://zhuanlan.zhihu.com/p/36574047) -> - [2018年6月亲测:注册美国地区苹果apple ID帐号终极教程](https://www.jianshu.com/p/b32da641e849) -> - [iOS开发之注册美国Apple Id不需要绑定信用卡,亲测可用](https://blog.csdn.net/ziyuzhiye/article/details/82769129) +> 然后,在 `/etc/systemd/resolved.conf` 文件中,把 `DNS` 和 `Domains` 配置项加上,如: +> +> ```conf +> DNS=172.20.0.2 +> ``` +### 9.4 私有子网中的 Kubernetes -### 4.3 VPN 客户端 +K8s 里有两组 CoreDNS 部署和配置,一组是边缘的(或是叫本地的),一组是中心的。 -对于L2TP/IPSec,几乎所有的客户端操作系统(无论是Windows/Mac/Linux的电脑,还是iPhone/Android)都支持,你可以自行Google。 +- 边缘的 Pod 名叫 `nodelocaldns`,侦听在本机。如:`169.254.25.10:53` +- 中心的 Pod 名叫 `coredns`,侦听在 cluster IP 上,如:`10.233.0.3:53` -- [Mac OS X PPTP/L2TP设置教程](https://www.jianshu.com/p/24e48cfb574f) -- [Windows 7操作系统配置L2TP VPN方法](http://nic.upc.edu.cn/2016/0928/c7809a132077/page.htm) +边缘的规则会把k8s的域名 `cluster.local`, `in-addr.arp` `ip6.arpa` 转给中心的 CoreDNS 处理,其它的交给本地的 `/etc/resolv.conf` 处理。 -## 5. 流量伪装和其它方式 +Kubernetes 会把如下内容打到 Pod 里的 `/etc/resolv.conf` -无论你用VPN,SS,SSR,都有可能被识别,**只有使用 HTTP over TLS 的样子,才会跟正常的流量混在一起,很难被识别**,所以,目前来说,V2Ray客户端 + Nginx + V2Ray服务端的方式,或是gost的HTTPS的方式,基本上来说,在网络四层上看到的都是TLS的包,很难被识别。这种代理服务只,我觉得只能做探测,或是得到更多的算力来做统计学分析。所以,V2Ray 和 gost 的服务器端用 nginx 再挡一道,那么就很难被发现了。 +```conf +nameserver 169.254.25.10 +search default.svc.cluster.local svc.cluster.local cluster.local cn-northwest-1.compute.internal +options ndots:5 +``` -> **注:** 说句老实话,我其时并不想害怕别人知道自己的上什么样的网站,因为我觉得我访问的都是合法的网站,但是就今天这个局势我也没办法——为什么要让像我这样的光明正大的良民搞得跟偷鸡摸狗之徒一样…… +查看一下 `nodelocaldns` 的配置: -### 5.1 V2Ray +```sh +$ kubectl get cm nodelocaldns -n kube-system -o yaml +``` -V2Ray 可以配置成一个非常隐蔽的代理软件。 +我们可以看到,除了 K8s 自己的域名外,其它的都交给了本机的 `/etc/resolv.conf`,如下所示: + +```yaml +.:53 { + errors + cache 30 + reload + loop + bind 169.254.25.10 + forward . /etc/resolv.conf # <--- 注意这条语句 + prometheus :9253 +} +``` - - V2Ray 用户手册:[https://www.v2ray.com](https://www.v2ray.com) - - V2Ray 项目地址:[https://github.com/v2ray/v2ray-core](https://github.com/v2ray/v2ray-core) - - V2Ray Telegram 使用群链接:[https://t.me/projectv2ray](https://t.me/projectv2ray) +然而,本机的 `/etc/resolv.conf` 里有两个 DNS,一个是我们的透明网关,一个是AWS的。而 CoreDNS 的 `forward` 策略是随机挑选,所以,这样的会导致,时而交给AWS处理,时而交给我们自己的clash处理。最终导致IP解析紊乱。 -V2Ray 配合一些模块目前来说可以伪装成正常的流量。但是配置相当复杂。大家可以自己Google自己玩吧。 +通过以下命令进行修改: +```sh +$ kubectl edit cm nodelocaldns -n kube-system +``` -### 5.2 Brook +修改如下:(AWS的归 172.20.0.2, 其它的走我们自己的网关) + +```diff ++ compute.internal:53 { ++ errors ++ cache 30 ++ reload ++ loop ++ bind 169.254.25.10 ++ forward . 172.20.0.2 ++ prometheus :9253 ++ } + .:53 { + errors + cache 30 + reload + loop + bind 169.254.25.10 +- forward . /etc/resolv.conf ++ forward . /etc/resolv.conf { ++ policy sequential ++ } + prometheus: 9253 + } +``` + +退出保存后,等大约30秒左右配置就会生效。 + + + +## 10. 代理技巧 -Brook是一个由 Go语言编写的跨平台代理软件,支持 Linux/MacOS/Windows/Android/iOS 各个平台。 +看到这里,相信已经能够按照上面的教程搭建好自己的上网环境,但是灵活的应用网络,你还需要了解一些技巧,比如 SOCKS 协议, http 隧道 和 ssh 网络隧道等。 -- Brook Github项目:[https://github.com/txthinking/brook](https://github.com/txthinking/brook) -- Github Wiki教程:[https://github.com/txthinking/brook/wiki/使用说明(中文)](https://github.com/txthinking/brook/wiki/使用说明(中文)) +1. [SOCKS 协议](https://zh.m.wikipedia.org/zh-hans/SOCKS) +2. [HTTP 隧道](https://zh.m.wikipedia.org/zh-hans/HTTP%E9%9A%A7%E9%81%93) -服务器一行命令安装: +### 10.1 HTTP 隧道 +常见的软件 curl , git, wget 都能通过设置 `HTTP_PROXY`,`HTTPS_PROXY`,`NO_PROXY` 来配置一个网络代理,`NO_PROXY`用来配置不需要代理的主机(多个用逗号隔开), 那么我们就可以编写一个 `bash ` 函数来运行需要走代理的命令: +```shell +with_proxy(){ + HTTPS_PROXY=http://127.0.0.1:7890 HTTP_PROXY=http://127.0.0.1:7890 "$@" +} ``` -wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/brook.sh && chmod +x brook.sh && bash brook.sh +把上面的 `127.0.0.1:7890` 改成你自己的网络代理, 将上面脚本写入到 `~/.bashrc` 中, `source ~/.bashrc` 后就能使用 `with_proxy` 这个函数了,比如我想要使用代理网络下载一个文件 `with_proxy wget https://....`, 想要使用代理网络从 `github` clone 一个项目 `with_proxy git clone https://...`, 当我们不用 `with_proxy` 这个函数的时候命令是不会走代理的,如果在 `windows` 上你也想要使用这样的功能,可以使用这个项目[with-env](https://github.com/hellojukay/with-env)。 + +另外,你也可以使用如下的两个 alias: +```shell +SOCKS="socks5://127.0.0.1:1085" +alias proxy="export http_proxy=${SOCKS} https_proxy=${SOCKS} all_proxy=${SOCKS}" +alias unproxy='unset all_proxy http_proxy https_proxy' ``` +这样,你就可以在需要代理的时候输入 `proxy`,不需要的时候输入 `unproxy`。 -运行 `brook.sh` 会出菜单项,你可以按菜单项来,主要就是设置端口号,密码。很简单的,我这里就不截图了,因为这个脚本运行起来中文菜单式的。 +### 10.2 SSH 隧道 +另外,我们可以使用 SSH Tunnel 来建立 SOCKS5 的代理(假设本地电脑无法访问,但是某台可以 SSH 的服务器能够访问外网,那么我们就可以使用如下的命令来建议翻墙代理: -然后你可以在 Brook 项目的 Github 首页上下载不同平台的客户端。设置起来也很简单! +```shell +ssh -D 1080 -qCN username@server:port +``` +解释: -## 6. 针对 IP 被封的解决方案 +- `-D`:本机SOCKS 服务端口 +- `-q` : quiet 模式,没有输出 +- `-C` : 数据压缩,可以节约一些带宽 +- `-N` : 不运行远程命令,只做端口转发 -花钱购买的 VPS 即便做了流量伪装依然有很大的几率 IP 被封锁,大多 VPS 服务商并不提供更换 IP 的服务,使用 CDN 可以让被封锁的 VPS 继续发挥翻墙功能。 +登录成功以后,本地 `1080`端口会开启一个 `SOCKS5` 协议的代理,只要配置好代理就能使用这个端口上网。 -### 6.1 Cloudflare +```shell +with_proxy(){ + HTTPS_PROXY=socks5://127.0.0.1:1080 HTTP_PROXY=socks5://127.0.0.1:1080 "$@" +} +``` +如果是浏览器,配置好`SwitchyOmega`插件也能实现上外网。 -Cloudflare 是一个 CDN 服务商,目前国内依然能正常的访问,可以作为跳板来实现翻墙。 +### 10.3 Github / Git SSH 代理 -注册 Cloudflare 帐号,并有一个空闲域名(三级域名即可),交给 Cloudflare 托管并将域名指向被封的 VPS IP,注意开启 Proxied 并且 SSL-TLS 使用 Flexible 选项。 +现在访问 Github 速度很慢甚至不通,我们可以使用代理来加速,首先我们需要配置好代理,然后配置好 `git` 的代理,这样就能加速 `git clone` 和 `git push` 了。 -Cloudflare 只需免费方案足以,不必花钱。 +当你使用 `git clone ssh://[user@]server/project.git` 或是 `git clone [user@]server:project.git` 的时候,你是在使用 SSH 协议。你需要配置 `~/.ssh/config` 来使用代理,比如我的本地有一个Sock5代理,端口是 1085,那么我可以这样配置: -### 6.2 V2Ray +```s +### github.com +Host github.com + Hostname github.com + ProxyCommand nc -x localhost:1085 %h %p + # git-for-windows 下可以用 connect 代替 nc + # ProxyCommand connect -S localhost:1085 %h %p +``` +### 10.4 Cloudflare Warp 原生 IP -VPS 上正常安装并配置好 V2Ray,注意两点: +很多我们需要访问的网站都需要使用“原生 IP”,比如:[Disney+](https://www.disneyplus.com/), [ChatGPT](https://chat.openai.com),[New Bing](https://www.bing.com/) 等。 -1. 传输协议必须要使用 ws -2. 要使用 80 或者 8080 端口 +所谓“原生 IP”就是指该网站的 IP 地址和其机房的 IP 地址是一致的,但是,很多 IDC 提供商的 IP 都是从其它国家调配来的,这导致我们就算是翻墙了,也是使用了美国的 VPS,但是还是访问不了相关的服务。所以,我们需要使用 Cloudflare Warp 来访问这些网站。 -如果端口有其他用途,那么用 Nginx/Caddy 之类软件,做一个 WebSocket proxy 到 V2Ray 即可。 +下面有几种安装方式: +- 全局模式。这种模式下,所有流量都会通过 Cloudflare 的网络,相当于VPN。 +- 代理模式。通过在服务器本机启动一个 SOCKS5 代理,然后把需要的流量转发到这个代理上。 -### 6.3 补充 +#### 10.4.1 WARP 模式 -客户端注意使用网址来连接。 +WARP 模式是 Cloudflare 提供的一种全局代理模式,就是一个客户端的 VPN,它会将你的所有流量都通过 Cloudflare 的网络,这样就能访问到原生 IP 了。 -目前支持 WebSocket 的免费 CDN 似乎只有 Cloudflare 一家,国内 CDN 服务商既不支持也不安全,不要考虑了。如果有更好的服务商欢迎补充。 +你可以使用这个一键安装的脚本来快速完成安装 https://github.com/P3TERX/warp.sh -网络延迟比直连增加不少,如果是频繁操作会很痛苦。网络带宽如果运气好可能比直连还优化了,用来看 Youtube 搞不好更流畅。 +下载脚本 +```shell +wget git.io/warp.sh +chmod +x warp.sh +``` +运行脚本 中文菜单 +```shell +./warp.sh menu +``` +先后执行如下安装: + - 1 - 安装 Cloudflare WARP 官方客户端 + - 4 - 安装 WireGuard 相关组件 + - 7 - 自动配置 WARP WireGuard 双栈全局网络 + +>**Note** +> 1. 如果没有 IPv6 网络,那么第 7 步可以换成第 5 步 自动配置 WARP WireGuard IPv4 网络,或是执行 `./warp.sh 4`。 +> +> 2. 你需要备份一下你的帐号和配置文件,在 `/etc/warp/` 目录下,主要是两个文件,一个是 `wgcf-account.toml`,一个是 `wgcf-profile.conf` +> +> 3. 这个脚本会启动两个 Systemd 服务,一个是 `warp-svc`,另一个是 `wg-quick@wgcf`。第一个是 Cloudflare Warp 的服务,第二个是 WireGuard 的服务。 +> +> 4. 你可以使用 `./warp.sh status` 来查看服务的状态,如果正常的话,会显示如下的信息。如果你的服务没有正常启动,那么会自动 `disable wg-quick@wgcf`,如果这样的话,你可以使用 `./warp.sh d`(IPv4 + IPv6 双栈网格)或是 `./warp.sh 4`(IPv4 网络) 来重头走一遍所有的安装过程。 +> ``` +> WireGuard : Running +> IPv4 Network : WARP +> IPv6 Network : WARP +> ``` +> -## 7. 其它 -### 7.1 其它方式 +使用 `curl ipinfo.io` 命令来检查你的 IP 地址,如果显示的是 Cloudflare 的 IP 地址,那么恭喜你,你已经成功了。如: + +```json +{ + "ip": "104.28.227.191", + "city": "Los Angeles", + "region": "California", + "country": "US", + "loc": "34.0522,-118.2437", + "org": "AS13335 Cloudflare, Inc.", + "postal": "90009", + "timezone": "America/Los_Angeles", + "readme": "https://ipinfo.io/missingauth" +} +``` + + +#### 10.4.2 代理模式 + +如果 WARP 模式安装不能成功,那么你可以使用如下的代理模式。代理模式也就是通过一个代理来访问 Cloudflare WARP 的服务,这样就可以访问到原生 IP 了。 + +> **Note** +> +> 下面的步骤主要使用 Cloudflare 的官方客户端,也许会随时间流逝导致过时,你可以参考 [Cloudflare WARP 的官方文档](https://developers.cloudflare.com/warp-client/get-started/linux/) + + +**1) 安装软件包** + +如果是 Ubuntu,那么可以使用以下命令在添加安装源: + +```shell +sudo apt install curl +curl https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg +echo "deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list +``` + +添加完源后,安装 Cloudflare WARP 客户端: + +```shell +sudo apt update +sudo apt install cloudflare-warp +``` +> **Note** +> +> 安装过程中,可能会出现如下错误: +> ``` +> The following packages have unmet dependencies: +> cloudflare-warp : Depends: nftables but it is not going to be installed +> Depends: gnupg2 but it is not going to be installed +> Depends: desktop-file-utils but it is not going to be installed +> Depends: libnss3-tools but it is not going to be installed +> linux-headers-aws : Depends: linux-headers-5.3.0-1028-aws but it is not going to be installed +> E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution). +> ``` +> 你先执行 `sudo apt --fix-broken install`,然后再执行 `sudo apt install cloudflare-warp` 即可。 + +**2) 配置 Cloudflare WARP** + +如果是第一次安装,你需要先注册一个帐号。其注册信息会在这里`/var/lib/cloudflare-warp/reg.json` + +```shell +warp-cli register +``` + +然后设置代理模式,这点非常重要,因为默认是 WARP 模式,这个会把你的整个 VPS 带到 Cloudflare 的 VPN 网络中,那么就会出现无法连接的情况。 + +```shell +warp-cli set-mode proxy +``` +然后,设置永久连接模式。 + +```shell +warp-cli enable-always-on +``` + +配置完后,你可以使用 `warp-cli settings` 来查看配置。你也可以通过查看配置文件来看是否配置成功,配置文件在 `/var/lib/cloudflare-warp/settings.json`。 + +**3) 连接 Cloudflare WARP** + +使用如下命令来连接 Cloudflare WARP: + +```shell +warp-cli connect +``` +你可以使用 `warp-cli status` 来查看连接状态。如: + +```shell +> warp-cli status +Status update: Connected +Success +``` + +连接成功后,你可以会在本地有一个 Socks5 代理, `127.0.0.1:40000`,你可以使用如下命令来查看: + +**4)验证 Cloudflare WARP** + +你可以使用如下命令来验证是否成功: + +```shell +curl -x "socks5://127.0.0.1:40000" ipinfo.io +``` + +如果输出现如下的信息,那么恭喜你,你已经成功了 + +```json + "ip": "104.28.247.70", + "org": "AS13335 Cloudflare, Inc." +``` + +**5)配置 Gost 路由转发** + +你可以使用如下命令来启动 gost 转发规则。下面的命行行意思是,把本地的 8080 端口转发到 Cloudflare WARP 的 Socks5 代理上。 + +```shell +gost -L "http://:8080" -F "socks5://127.0.0.1:40000" +``` +当然,上面的配置是不够好的,我们最好使用有证书的 HTTPS 代理。这里的内容参见于 前的面 [3.3 用 Gost 设置 HTTPS 服务](#33-用-gost-设置-https-服务)。 + +为了使用两种不同的代理,你可以启动两个 gost 服务: + +- 一个是通过 443 端口直接代理 +- 另一个是通过 8443 端口转发到 Cloudflare WARP 的 Socks5 代理上 + +```shell +# 下面的四个参数需要改成你的 +DOMAIN="YOU.DOMAIN.NAME" +USER="username" +PASS="password" +PORT=443 + +BIND_IP=0.0.0.0 +CERT_DIR=/etc/letsencrypt +CERT=${CERT_DIR}/live/${DOMAIN}/fullchain.pem +KEY=${CERT_DIR}/live/${DOMAIN}/privkey.pem +sudo docker run -d --name gost \ + -v ${CERT_DIR}:${CERT_DIR}:ro \ + --net=host ginuerzh/gost \ + -L "http2://${USER}:${PASS}@${BIND_IP}:${PORT}?cert=${CERT}&key=${KEY}&probe_resist=code:404&knock=www.google.com" + +sudo docker run -d --name gost-warp \ + -v ${CERT_DIR}:${CERT_DIR}:ro \ + --net=host ginuerzh/gost \ + -L "http2://${USER}:${PASS}@${BIND_IP}:8443?cert=${CERT}&key=${KEY}&probe_resist=code:404&knock=www.google.com" \ + -F "socks://localhost:40000" +``` + +> **Note** +> +> 1) 你也可以使用 gost 的 `bypass`参数来让相应的域名的流量转发到 Cloudflare WARP 的 Socks5 代理上。如:` +-F=socks5://localhost:40000?bypass=~*.openai.com,openai.com¬ls=true` +> +> 2) 你也可以使用 V2Ray 的路由模式,参见 [V2Ray 的路由功能](https://www.v2ray.com/chapter_02/03_routing.html)。V2Ray的路由模式就比 gost 要强很多。你还可以通过使用预定义域名列表 `geolocation-cn` 把其的路由转发到 Cloudflare WARP 的 Socks5 代理上,以避免你的 VPS 的 IP 被暴露。 + +**6)其它事宜** + +- **查看运行状态**。 `warp-cli` 是 `warp-svc` 的客户端,真正的程序是 `warp-svc`,你可以使用如下命令来查看: + + ```shell + systemctl status warp-svc + ``` + +- **内存泄漏问题**。 目前,`warp-svc` 这个程序有内存泄漏的问题(参看 [#124](https://github.com/haoel/haoel.github.io/issues/124)),所以,你需要定期重启服务。你可以使用cronjob来重启服务。运行 `crontab -e`,然后添加如下内容: + + ```cron + 0 * * * * /bin/systemctl resetart warp-svc + ``` + +- **文件描述符不足**。另外,如果你的程序出现文件描述不足的情况: + + ```shell + warp-cli connect + Status update: Unable to connect. Reason: Insufficient system resource: file descriptor + ``` + 你需要修改文件描述符的限制,这类的文章比较多,你自行 Google,这里就不再赘述了。如果你想配置 Cloudflare WARP 文件描述符的限制,你可以编辑 `/lib/systemd/system/warp-svc.service`,在 `[Service]` 下面添加如下内容: + + ```ini + LimitNOFILE=65535 + LimitNOFILESoft=65535 + ``` + 然后,重启服务: + + ```shell + sudo systemctl daemon-reload + sudo systemctl restart warp-svc.service + ``` + +#### 10.4.3 Docker 代理 + +用 Docker 可以更方便地部署起一个 Cloudflare WARP Proxy,只需要一行命令: + +```shell +docker run -v $HOME/.warp:/var/lib/cloudflare-warp:rw \ + --restart=always --name=cloudflare-warp e7h4n/cloudflare-warp +``` + +这条命令会在容器上的 40001 开启一个 socks5 代理,接下来查看这个容器的 ip: + +```shell +docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' cloudflare-warp +``` + +然后可以通过 curl 镜像来测试,例如,如果容器的 ip 是 `172.17.0.2`,则可以运行: + +```shell +docker run --rm curlimages/curl --connect-timeout 2 -x "socks5://172.17.0.2:40001" ipinfo.io +``` + +返回的结果中 `org` 字段应该能看到 Cloudflare 相关的信息。 + +接下来我们给 Gost 增加一个条件转发规则,转发我们希望的域名、地址到 cloudflare 的 warp 网络: + +``` +-F=socks5://172.17.0.2:40001?bypass=~*.openai.com,openai.com¬ls=true +``` + +> **Note** +> +> `bypass=~` 的含义是,只有命中后面规则时才转发请求到 `172.17.0.2:40001` 这个 socks5 代理。接下来,通过这个 Gost 代理访问 `openai.com` 时,就会走 warp 网络了。 + +## 11. 其它 + +### 11.1 其它方式 如下还有一些其它的方式(注:均由网友提供,我没有验证过) [Outline](https://getoutline.org/en/home) 是由 Google 旗下 [Jigsaw](https://jigsaw.google.com/) 团队开发的整套翻墙解决方案。Server 端使用 Shadowsocks,MacOS, Windows, iOS, Android 均有官方客户端。使用 Outline Manager 可以一键配置 DigitalOcean。其他平台例如 AWS, Google Cloud 也提供相应脚本。主要优点就是使用简单并且整个软件栈全部[开源](https://github.com/Jigsaw-Code/?q=outline),有专业团队长期维护。 -### 7.2 搭建脚本 +### 11.2 搭建脚本 上述的搭建和安装脚本可参看本库的 scripts 目录下的脚本(感谢网友 [@gongzili456](https://github.com/gongzili456) 开发) -- [Ubuntu 18.04 Installation Script](https://github.com/haoel/haoel.github.io/blob/master/scripts/install.ubuntu.18.04.sh) +- [Ubuntu 18.04 Installation Script](https://github.com/haoel/haoel.github.io/blob/master/scripts/install.ubuntu.18.04.sh) + +**注意:这个脚本可能年久失修,不一定能用,但是可以参考,如果有问题,可以提交 PR**。 欢迎补充和改善! (全文完) - diff --git a/images/cover.jpg b/images/cover.jpg deleted file mode 100644 index 069d18c1..00000000 Binary files a/images/cover.jpg and /dev/null differ diff --git a/images/cover.webp b/images/cover.webp new file mode 100644 index 00000000..29ae5ddd Binary files /dev/null and b/images/cover.webp differ diff --git a/scripts/install.ubuntu.18.04.sh b/scripts/install.ubuntu.18.04.sh index e7de3d92..d494a77d 100755 --- a/scripts/install.ubuntu.18.04.sh +++ b/scripts/install.ubuntu.18.04.sh @@ -43,7 +43,7 @@ start_bbr(){ install_bbr() { # 如果内核版本号满足最小要求 - if [ $VERSION_CURR > $VERSION_MIN ]; then + if [[ $VERSION_CURR > $VERSION_MIN ]]; then check_bbr else update_core @@ -53,9 +53,9 @@ install_bbr() { install_docker() { if ! [ -x "$(command -v docker)" ]; then echo "开始安装 Docker CE" - curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add - + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ - "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" sudo apt-get update -qq @@ -94,21 +94,21 @@ create_cert() { echo "开始生成 SSL 证书" echo -e "${COLOR_ERROR}注意:生成证书前,需要将域名指向一个有效的 IP,否则无法创建证书.${COLOR_NONE}" - read -p "是否已经将域名指向了 IP?[Y/n]" has_record + read -r -p "是否已经将域名指向了 IP?[Y/n]" has_record if ! [[ "$has_record" = "Y" ]] ;then echo "请操作完成后再继续." return fi - read -p "请输入你要使用的域名:" domain + read -r -p "请输入你要使用的域名:" domain - sudo certbot certonly --standalone -d $domain + sudo certbot certonly --standalone -d "${domain}" } install_gost() { if ! [ -x "$(command -v docker)" ]; then - echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" + echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" return fi @@ -118,25 +118,25 @@ install_gost() { fi echo "准备启动 Gost 代理程序,为了安全,需要使用用户名与密码进行认证." - read -p "请输入你要使用的域名:" DOMAIN - read -p "请输入你要使用的用户名:" USER - read -p "请输入你要使用的密码:" PASS - read -p "请输入HTTP/2需要侦听的端口号(443):" PORT + read -r -p "请输入你要使用的域名:" DOMAIN + read -r -p "请输入你要使用的用户名:" USER + read -r -p "请输入你要使用的密码:" PASS + read -r -p "请输入HTTP/2需要侦听的端口号(443):" PORT - if [[ -z "${PORT// }" ]] || ! [[ "${PORT}" =~ ^[0-9]+$ ]] || ! [ "$PORT" -ge 1 -a "$PORT" -le 655535 ]; then + if [[ -z "${PORT// }" ]] || ! [[ "${PORT}" =~ ^[0-9]+$ ]] || ! { [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; }; then echo -e "${COLOR_ERROR}非法端口,使用默认端口 443 !${COLOR_NONE}" PORT=443 fi BIND_IP=0.0.0.0 - CERT_DIR=/etc/letsencrypt/ + CERT_DIR=/etc/letsencrypt CERT=${CERT_DIR}/live/${DOMAIN}/fullchain.pem KEY=${CERT_DIR}/live/${DOMAIN}/privkey.pem sudo docker run -d --name gost \ -v ${CERT_DIR}:${CERT_DIR}:ro \ --net=host ginuerzh/gost \ - -L "http2://${USER}:${PASS}@${BIND_IP}:${PORT}?cert=${CERT}&key=${KEY}&probe_resist=code:400" + -L "http2://${USER}:${PASS}@${BIND_IP}:${PORT}?cert=${CERT}&key=${KEY}&probe_resist=code:400&knock=www.google.com" } crontab_exists() { @@ -145,14 +145,14 @@ crontab_exists() { create_cron_job(){ # 写入前先检查,避免重复任务。 - if ! crontab_exists "cerbot renew --force-renewal"; then + if ! crontab_exists "certbot renew --force-renewal"; then echo "0 0 1 * * /usr/bin/certbot renew --force-renewal" >> /var/spool/cron/crontabs/root echo "${COLOR_SUCC}成功安装证书renew定时作业!${COLOR_NONE}" else echo "${COLOR_SUCC}证书renew定时作业已经安装过!${COLOR_NONE}" fi - if ! crontab_exists "docker restart gost"; then + if ! crontab_exists "docker restart gost"; then echo "5 0 1 * * /usr/bin/docker restart gost" >> /var/spool/cron/crontabs/root echo "${COLOR_SUCC}成功安装gost更新证书定时作业!${COLOR_NONE}" else @@ -162,7 +162,7 @@ create_cron_job(){ install_shadowsocks(){ if ! [ -x "$(command -v docker)" ]; then - echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" + echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" return fi @@ -172,24 +172,24 @@ install_shadowsocks(){ fi echo "准备启动 ShadowSocks 代理程序,为了安全,需要使用用户名与密码进行认证." - read -p "请输入你要使用的密码:" PASS - read -p "请输入ShadowSocks需要侦听的端口号(1984):" PORT + read -r -p "请输入你要使用的密码:" PASS + read -r -p "请输入ShadowSocks需要侦听的端口号(1984):" PORT BIND_IP=0.0.0.0 - if [[ -z "${PORT// }" ]] || ! [[ "${PORT}" =~ ^[0-9]+$ ]] || ! [ "$PORT" -ge 1 -a "$PORT" -le 655535 ]; then + if [[ -z "${PORT// }" ]] || ! [[ "${PORT}" =~ ^[0-9]+$ ]] || ! { [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; }; then echo -e "${COLOR_ERROR}非法端口,使用默认端口 1984 !${COLOR_NONE}" PORT=1984 - fi + fi sudo docker run -dt --name ss \ - -p ${PORT}:${PORT} mritd/shadowsocks \ + -p "${PORT}:${PORT}" mritd/shadowsocks \ -s "-s ${BIND_IP} -p ${PORT} -m aes-256-cfb -k ${PASS} --fast-open" } install_vpn(){ if ! [ -x "$(command -v docker)" ]; then - echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" + echo -e "${COLOR_ERROR}未发现Docker,请求安装 Docker ! ${COLOR_NONE}" return fi @@ -199,13 +199,13 @@ install_vpn(){ fi echo "准备启动 VPN/L2TP 代理程序,为了安全,需要使用用户名与密码进行认证." - read -p "请输入你要使用的用户名:" USER - read -p "请输入你要使用的密码:" PASS - read -p "请输入你要使用的PSK Key:" PSK + read -r -p "请输入你要使用的用户名:" USER + read -r -p "请输入你要使用的密码:" PASS + read -r -p "请输入你要使用的PSK Key:" PSK sudo docker run -d --name vpn --privileged \ - -e PSK=${PSK} \ - -e USERNAME=${USER} -e PASSWORD=${PASS} \ + -e PSK="${PSK}" \ + -e USERNAME="${USER}" -e PASSWORD="${PASS}" \ -p 500:500/udp \ -p 4500:4500/udp \ -p 1701:1701/tcp \ @@ -232,7 +232,7 @@ init(){ COLUMNS=50 echo -e "\n菜单选项\n" - while [ 1 == 1 ] + while true do PS3="Please select a option:" re='^[0-9]+$' @@ -254,10 +254,10 @@ init(){ break; elif (( REPLY == 2 )) ; then install_docker - break + break elif (( REPLY == 3 )) ; then create_cert - loop=1 + #loop=1 break elif (( REPLY == 4 )) ; then install_gost @@ -282,7 +282,8 @@ init(){ done done - IFS=$OIFS # Restore the IFS + echo "${opt}" + IFS=$OIFS # Restore the IFS } init