智能网关de_GWD的一次排障经历

前言

原创文章,转载引用请务必注明链接,水平有限,如有疏漏,欢迎指正。

1、光猫配置

这里主要是想将光猫由路由模式改为桥接模式,理由如下。

光猫路由模式的Cons:

  • 光猫性能差,多个设备连接就不行了
  • 仅支持2.4GHz的无线网频段,内外网传输速度很慢,成为网络瓶颈

光猫桥接模式的Pros:

  • 桥接模式后,使用路由器拨号,可以实现单线多拨,提升网速
  • 可以灵活添加旁路由,实现加速上网,智能去广告/保护隐私的功能

要改光猫模式,需要使用超级密码登陆,进入后台管理,这也是主要的难点。

1.1 获取超级密码

光猫型号是友华PT924G,看了很多帖子,最后发现早先的方法都失效,已验证失效的方法包括telnet、ftp、replay、ctromfile.cfg等,最后用USB2TTL模块,因为散热片挡住了串口,没焊接,直接用串口登陆,/tmp只有一个rombackup.conf,打开没有密码,然后全盘搜conf,找到/var文件夹里,有passwd,boa什么的,md5加密过的。最后参考别的文章,lastgood.xml | grep "password",找到,耗时两天,根据自己了解和B站UP宽带小哥孙阳光的介绍,默认的超级管理员密码在光猫注册后会生成一个新的,根据算号器算出,但是也明文保存在本地,所以通过TTL法可以获取,参数root:123,115200。

1.2 更换光猫尝试

之前也有一个光猫,烽火的,比这个好,主要支持物理按键关闭灯光,而且启动速度要快,做工好些,虽然改桥接之后,光猫就只有光信号转电信号的作用,不需要啥性能。这里尝试了自己注册之前的光猫,最后暂时没成功,主要是旧路由器按RESET键仍然显示已注册。Keyword:LOID、GPON/EPON。

光猫更换指南+无线路由器选择参考

2、智能网关

想要使局域网内的机器使用透明代理,了解到的有sower、de_GWD、smartdns等。代理方案有*、v2ra--y。

2.1 Base Environment

硬件环境:DQ77KB+i5 3470T+8G DDR3+64G SATA SSD+500G HDD+双千兆网卡,水星D191G做无线AP

软件环境:PVE 6+DietPi VM,软路由使用高恪系统。

关于安装DietPi,参考此链接,主要参数如下:

  • Create a VM with mostly default settings. I did change the CPU type to "host" and set the "ssd" flag on the disk.
  • Unzip the IMG file and SCP it over to my server. Had to use the command line for this b/c the GUI doesn't know what an "IMG" file is.
  • Overwrite the virtual disk with the IMG. I'm using lvm-thin storage and the VMID was 107 so that command looked like:
    • dd if=DietPi_v6.25_NativePC-BIOS-x86_64-Buster.img of=/dev/mapper/vg1-vm--107--disk--0 bs=4M
  • Booted that sucker up. And it worked.

2.2 de_GWD

更新比较频繁(太频繁了!),建议多留意电报群通知。一些使用教程可以参考博客(基本不更新)和youtube频道(随缘更新)。然而目前新版服务端使用了docker+nginx_with_tls1.3 images,安装过程中提示证书获取时timeout,安装完毕后无法正常使用, docker ps显示容器启动失败,一直提示restarting(132)。另外安装的时候需要提前安装apt install software-properties-common ,于是有了本文排障的过程和思路,走弯路的同时也学习了不少知识。

一些Tips:

  • 测试端口有无正确开启可用curl -v http://localhost:80命令。
  • 最后一版非docker server可以下载,但是需要手动更改安装脚本的链接。

2.2.1 docker 排障

好久没用docker了,找到本书,再先搜搜docker cheatsheet,了解到以下命令:

Docker -- 从入门到实践 · GitBook (Legacy)

docker exec -it [container-id] bash         # Enter a running container
docker ps                                   # See a list of all running containers
docker images -a                            # Show all images on this machine
docker rmi <imagename>                      # Remove the specified image from this machine
docker rm <hash>                            # Remove the specified container from this machine
docker logs <hash>

然后ps发现它一直在重启,并且看不到日志。今晨想到安装时获取证书的时候报错,而之前非docker使用nginx时也出现过无法启动的问题,所以也有可能nginx压根没起来导致没有错误日志。

怀疑是容器参数问题,导致nginx没有正常暴露端口,我们来看看dockerfile和sever脚本中启动容器的参数,注意expose,net:host,使用nginx官方镜像,同样参数正常暴露端口。搜了132,和本文情况不同,卡住。

Find out Why Your Docker Container Keeps Crashing

2.2.2 acme.sh 排障

这里再推测获取ssl证书的问题导致。同样查看相关server安装脚本,第437行makeSsl()函数。可见使用acme.sh获取let's encryt,参考《ACME 客户端》相关介绍,官方推荐使用Certbot,不过国人制作的acme.sh也很不错,参考官方使用教程。重现GWD的请求参数:

~/.acme.sh/acme.sh --issue -d $vpsdomain -w /var/www/html --keylength ec-256
# 报错
[Mon Jan  6 10:37:33 CST 2020] *MYDOMAIN*:Verify error:Fetching http://*MYDOMAIN*/.well-known/acme-challenge/zyZ8cQzbtSydBwaf7-EFkIN2phzp1j8zvcvxYMu3Tuo: Connection refused
[Mon Jan  6 10:37:33 CST 2020] Please add '--debug' or '--log' to check more details.
[Mon Jan  6 10:37:33 CST 2020] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
# 添加 --debug重新运行
[Mon Jan  6 10:37:46 CST 2020] url='https://acme-v02.api.letsencrypt.org/acme/chall-v3/2131125561/B7akww'
[Mon Jan  6 10:37:46 CST 2020] payload
[Mon Jan  6 10:37:46 CST 2020] POST
[Mon Jan  6 10:37:46 CST 2020] _post_url='https://acme-v02.api.letsencrypt.org/acme/chall-v3/2131125561/B7akww'
[Mon Jan  6 10:37:46 CST 2020] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
[Mon Jan  6 10:37:46 CST 2020] _ret='0'
[Mon Jan  6 10:37:46 CST 2020] code='200'
[Mon Jan  6 10:37:46 CST 2020] *MYDOMAIN*:Verify error:Fetching http://*MYDOMAIN*/.well-known/acme-challenge/Y2uPDaXaJtzrbY8u0Cf38OOaJDaJVoXPp_museFxlH4: Connection refused
[Mon Jan  6 10:37:46 CST 2020] Debug: get token url.
[Mon Jan  6 10:37:46 CST 2020] GET
[Mon Jan  6 10:37:46 CST 2020] url='http://*MYDOMAIN*/.well-known/acme-challenge/Y2uPDaXaJtzrbY8u0Cf38OOaJDaJVoXPp_museFxlH4'
[Mon Jan  6 10:37:46 CST 2020] timeout=1
[Mon Jan  6 10:37:46 CST 2020] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g  --connect-timeout 1'
[Mon Jan  6 10:37:47 CST 2020] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 7
[Mon Jan  6 10:37:47 CST 2020] ret='7'
# 错误代码7
# CURLE_COULDNT_CONNECT (7) —— Failed to connect() to host or proxy.

参考官方debug指南,最后使用dns手动认证的方法解决了证书的问题,我用的dnspod,注意使用自己的Token,截止目前猜测timeout是因为ipv6的原因。FYI

[Mon Jan  6 10:54:24 CST 2020] Your cert is in  /root/.acme.sh/*MYDOMAIN*/*MYDOMAIN*.cer 
[Mon Jan  6 10:54:24 CST 2020] Your cert key is in  /root/.acme.sh/*MYDOMAIN*/*MYDOMAIN*.key 
[Mon Jan  6 10:54:24 CST 2020] The intermediate CA cert is in  /root/.acme.sh/*MYDOMAIN*/ca.cer 
[Mon Jan  6 10:54:24 CST 2020] And the full chain certs is there:  /root/.acme.sh/*MYDOMAIN*/fullchain.cer
## 
cd /root/.acme.sh/*MYDOMAIN*/
export vpsdomain="*MYDOMAIN*" 
~/.acme.sh/acme.sh --installcert -d $vpsdomain --ecc \
               --key-file       /var/www/ssl/$vpsdomain.key  \
               --fullchain-file /var/www/ssl/fullchain.cer \
               --reloadcmd     "docker restart nginx > /dev/null 2>&1"
openssl dhparam -out /var/www/ssl/dhparam.pem 2048

2.2.3 nginx 排障

我们解决了证书的问题,结果容器还是无法启动,回头看docker_nginx的脚本:

docker run -d --name=nginx --net=host --restart=always \
-v /etc/localtime:/etc/localtime \
-v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
-v /var/www/ssl/:/var/www/ssl/ \
-v /var/www/html/:/var/www/html/ \
jacyl4/nginx_tls1.3:latest

我们attach进这个容器里看看,docker exec -it [container-id] /bin/bash 。nginx -V输出如下:

root@cc:/# nginx -V
nginx version: nginx/1.17.7
built by gcc 8.3.0 (Debian 8.3.0-6)
built with OpenSSL 1.1.1b  26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --user=www-data --group=www-data --with-compat --with-file-aio --with-threads --with-libatomic --with-mail --with-mail_ssl_module --with-http_realip_module --with-http_ssl_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_stub_status_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_slice_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_spdy_module --with-http_v2_module --with-http_v2_hpack_enc --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-zlib=/usr/src/zlib --with-pcre=/usr/src/pcre-8.43 --with-pcre-jit --with-openssl=/usr/src/openssl-1.1.1b --with-openssl-opt='zlib enable-weak-ssl-ciphers enable-ec_nistp_64_gcc_128 -march=native -Wl,-flto' --with-cc-opt='-DTCP_FASTOPEN=23 -m64 -g -O3 -flto -ffast-math -march=native -fstack-protector-strong -fuse-ld=gold --param=ssp-buffer-size=4 -Wformat -Werror=format-security -fno-strict-aliasing -fPIC -Wdate-time -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-lrt -Wl,-z,relro -Wl,-z,now -fPIC -flto' --add-module=/usr/src/ngx_brotli

然后执行以下命令测试nginx配置参数:nginx -t -c /etc/nginx/nginx.conf,报错:Illegal instruction (core dumped) ,由此怀疑是编译问题,不是cpu架构问题,因为nginx -V可以输出。重新通过dockerfile在本地编译,重新编译后使用新镜像的容器终于ok了,由此怀疑是指令集问题。由于使用的make进行编译nginx,我们看看gcc的编译选项, 怀疑CloudCone的服务器CPU较老,缺乏支持AVX指令集,可能在第三方x86平台编译时添加-mno-avx -mno-avx2参数。

How to Resolve The Error "Illegal instruction (core dumped)" when Running "import tensorflow" in a Python Program

Preventing GCC from automatically using AVX and FMA instructions when compiled with -mavx and -mfma

Building GCC without AVX 2

至此,问题终于解决,原来是由于cpu不支持avx指令集导致通用的nginx无法运行,从而导致ssl证书验证时(需要本地web server)失败。表象在ssl证书获取,实质在nginx。后期还是准备换回sower。

3、拓展

  1. 使用网络服务自动构建docker images
  2. gcc-编译时使用的指令集
上一篇:A1070 Mooncake (25 分)


下一篇:【2019年8月】OCP 071认证考试最新版本的考试原题-第28题