1. 背景
为了给梯子加速,尝试开启 BBR,所以尝鲜的用上了 Debian 9.
新的 TCP 拥塞控制算法 BBR (Bottleneck Bandwidth and RTT) 可以让服务器的带宽尽量跑慢,并且尽量不要有排队的情况,让网络服务更佳稳定和高效。
Linux Kernel 内核升级到 4.9 及以上版本实现 BBR 加速的,由于 Debian9 默认的内核就是 4.9 的内核而且编译了 TCP BBR 的内容,所以可以直接通过参数开启。
CentOS 6.x 因为内核的原因,所以装 Docker 比较麻烦;CentOS 7 新的防火墙 FirewallD 虽然已经会初步的使用了;但是还要习惯从 server xxxx start[restart|stop] 转到 systemctl ;还有一个 journalctl -xe 查看错误日志的东西。
看到网上好多的 Docker 镜像都是基于 Debian/Ubuntu 的,很少基于 CentOS,所以也为了学习一下 Debian
综合一下,所以 VPS 装了 Debian 9 的系统。
2. 安装梯子 2.1. 脚本安装(支持 Open-VZ) 然后用一键脚本装了 v2ray,放上作者的一键式安装命令
1 bash <(curl -s -L https://git.io/v2ray.sh)
确实相当好用,nice。具体链接请点击这里
2.2. Docker 一键安装 我使用的配置方式是 Docker + Caddy + v2ray,走的是 WS + TLS。
传送门:https://github.com/yuanmomo/docker-caddy-v2ray
3. 需求 安装 v2ray 后,需要防火墙禁用一些端口,像用 WS + TLS 时,v2ray 的监听端口只需要 Caddy 能访问就 OK 了,外面是不需要访问的。
如果使用一键脚本安装,又安装了 ss 服务,如果需要手动关闭和打开 ss 的端口,那就要用到防火墙。
在之前的 CentOS 6.x 之前,用 iptables,那是相当的没有问题,但是就是命令太长,所以 Debian(Ubuntu)基于 iptables 封装了一个 ufw,来简化 iptables 的操作。
4. ufw 使用 官方操作文档:https://help.ubuntu.com/lts/serverguide/firewall.html
大概使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # sudo ufw enable sudo ufw default deny # sudo ufw allow smtp # sudo ufw allow ssh # sudo ufw allow 22/tcp # sudo ufw allow 53 # sudo ufw allow from 192.168.1.100 # sudo ufw deny http # sudo ufw delete allow smtp # sudo ufw delete 1 # sudo ufw insert 1 allow 80 # ufw status numbered
5. 事实? 当我一顿猛如虎的操作了过后,然后看了一下当前 ufw 的状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # root@sz:/etc/ufw# ufw enable root@sz:/etc/ufw# ufw default deny # root@sz:/etc/ufw# ufw allow ssh # root@sz:/etc/ufw# ufw allow http # root@sz:~# netstat -anp | grep -i listen | grep tcp tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 21723/sshd tcp6 0 0 :::80 :::* LISTEN 1755/v2ray tcp6 0 0 :::443 :::* LISTEN 1755/v2ray # root@sz:/etc/ufw# ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere 80/tcp ALLOW IN Anywhere 22/tcp (v6) ALLOW IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6)
默认 deny,只允许访问两个端口: 80 和 22。443 是 ss 端口,不想开放出来,也没有配置在规则里面,简直毫无破绽。
然后美滋滋的在本地执行了一下 nmap 和 telnet( 真实 ip 被我替换掉了):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 » telnet 1.1.1.1 443 Trying 1.1.1.1... Connected to 1.1.1.1. Escape character is '^]'. Connection closed by foreign host. » telnet 1.1.1.1 22 Trying 1.1.1.1... Connected to 1.1.1.1. Escape character is '^]'. » nmap 1.1.1.1 Starting Nmap 7.60 ( https://nmap.org ) at 2019-08-14 01:11 CST Nmap scan report for 1.1.1.1 Host is up (0.0082s latency). Not shown: 997 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https Nmap done: 1 IP address (1 host up) scanned in 5.07 seconds
什么鬼???443 怎么可能访问到???我不是没有配置 443 端口吗?默认应该是 deny 的啊???
6. 排查 然后我重新试了好几次,还重装了一次 debian,网上各种谷歌 ufw not blocking port 的关键字,看了官方文档。确认,我的 ufw 操作肯定没有问题。
发工单给 VPS HOST,然后陆陆续续的交流,没有什么进展。
自己也在不停的找问题,最后用 iptables-save 命令检查一下当前iptables 的规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 root@sz:~# iptables-save # Generated by iptables-save v1.6.0 on Mon Aug 12 10:50:51 2019 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] ............. # -A INPUT -p udp -m state --state NEW -m udp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p udp -m state --state NEW -m udp --dport 443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT ............. # -A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT -A ufw-user-input -p udp -m udp --dport 80 -j ACCEPT -A ufw-user-input -p tcp -m tcp --dport 22 -j DROP -A ufw-user-input -p udp -m udp --dport 22 -j DROP ............. COMMIT # Completed on Mon Aug 12 10:50:51 2019
中间的不重要信息已经省略了。发现有两个地方定义了 80 端口,而且格式还不一样。果断怀疑是一键安装脚本直接使用 iptables 命令操作了防火墙,而不是 ufw,而且,插入的顺序还在 ufw 控制的前面,所以就不受 ufw 控制了。
一看脚本的内容:
真的是就是这个原因。
7. 解决 7.1. 脚本直接用 iptables 修改 防火墙配置 这种情况,注释掉脚本使用 iptables 操作防火墙的部分即可。
7.2. Docker 修 iptables 的配置 这个是我搜出来的,之前也遇到过,只是没有仔细深入去思考,为什么 ufw 不能 deny docker 容器中的端口。
参考:https://askubuntu.com/questions/652556/uncomplicated-firewall-ufw-is-not-blocking-anything-when-using-docker
解决办法有三个:
docker run 不使用 -p 参数. 使用 docker linking or docker networks 替代.
监听容器的端口在回环网卡 lo 上,也就是 127.0.0.1: docker run -p 127.0.0.1:8080:8080 …
配置 Docker 不要修改防火墙。修改 /etc/docker/daemon.json 文件: { “iptables” : false },然后重启。
建议使用第 1,2 两种方法。第 3 种方法回使容器不能访问外网。