原创

目前找到了两个解决方案

  1. socat 端口转发

  2. docker-ipv6nat

很早就和QNAP官方反馈请求支持IPV6,但一直没反应

socat 端口转发

环境

  • 系统:QTS 4.3.6

  • 网络:IPV4 & IPV6

  • Docker: 由Container Station提供

问题

通过ipv6地址可以打开NAS的管理页面,但是无法访问Docker对应端口的服务。

排查

QTS中Docker使用的虚拟交换机网络没有启动IPV6,且无法在虚拟交换机设置中手动启动。
这样一来,Docker只监听了tcp4的端口,对于主机上tcp6的端口的访问无法映射到docker容器上。

解决方案

在主机上开一个tcp6的端口,将其转发到主机上与docker关联的tcp4端口。
即:
docker(tcp4)–>host(tcp4)–>host(tcp6)

docker-ipv6nat

  • IPv4 & IPv6 可以平等使用(端口可以在主机系统上共享)
  • 容器并不完全在线,因为 Docker 容器并不总是以安全着称

步骤1:

为 ip6tables NAT 安装内核模块。不幸的是,QNAP 没有自带这些模块,所以你必须自己构建它们。
谢天谢地,有人已经这样做并在 github 上发布了它。qnap-ip6tables_nat-module。在 Release 下,您已经可以在此处下载当前构建的模块。我将它们放在 Docker 容器的应用程序目录中:

/share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/

然后,您必须确保在启动时加载这些模块。为此,必须在您的 autorun.sh 中输入以下行。

# ipv6-tables
/sbin/modprobe ip6_tables
/sbin/modprobe nf_nat
/sbin/modprobe xt_MASQUERADE
insmod /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/ip6t_NPT.ko
insmod /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/nf_reject_ipv6.ko
insmod /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/ip6t_REJECT.ko
insmod /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/ip6table_nat.ko

您可以在 QNAP Wiki 中了解如何在您的 QNAP 模型上编辑此文件:Running_Your_Own_Application_at_Startup

添加模块后,您需要重新启动 NAS。

第2步:

为了设置 docker-ipv6nat 容器,我准备了一个 docker-compose 文件。您可以通过 Create 简单地将其插入 ContainerStation:

version: '3'

services:
  ipv6nat:
    container_name: ipv6nat
    restart: always
    image: robbertkl/ipv6nat
    privileged: true
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /lib/modules:/lib/modules:ro

容器应该在终端上没有任何输出的情况下启动。不起眼……现在呢?创建也应该可以通过 IPv& 访问的容器时是否需要一些手动工作。至少我还没有通过 QNAP 界面找到更简单的方法。

如果需要,您必须为每个容器创建至少一个支持 IPv6 的网络。

为此,请通过 SSH 登录 QNAP 并创建一个新的 Docker 网络:

docker network create --ipv6 --subnet fd00:dead:beef::/48 ipv6net-1

当然,您也可以使用任何其他 ULA 范围 (fc00::/7)。

现在只需使用 ipv6net-1 作为容器的外部网络。这是一个小例子:

version: "3"
  services:
    alp1:
      image: yeasy/simple-web:latest
      ports:
      - 80:80
      networks:
      - ipv6net-1

networks:
  ipv6net-1:
    external: true

现在您的容器端口来自 IPv4:

nmap <ipv4 ip> -p 80

PORT   STATE  SERVICE
80/tcp open http

也可以通过 IPv6 访问:

nmap <ipv6 ip> -6 -p 80

PORT   STATE  SERVICE
80/tcp open http

享受通过 IPv4 和 IPv6 托管您的服务的乐趣!

实操

遇到问题: robbertkl/ipv6nat 启动日志报错

开启防火墙使用到了geoip会遇到如下错误

iptables   exit status 1: Can't find library for match `geoip'

可能的解决方案

  1. 编译支持 geoip
  1. 不使用 geoip

    把防火墙中的规则设计到geoip 的都修改为任何地区,防火墙规则设计的好,针对一个地区开发某些端口和针对所有地区开发端口基本一样的风险。

使用第二种方案,实际测试使用发现丢包率还不低!

# 在开启了ipv6的docker中运行如下命令
# ping6  2409:804c:2000:2::1
PING 2409:804c:2000:2::1 (2409:804c:2000:2::1): 56 data bytes
ping: getnameinfo: Temporary failure in name resolution
64 bytes from unknown: icmp_seq=1 ttl=57 time=4.073 ms

...

^Cping: getnameinfo: Temporary failure in name resolution
64 bytes from unknown: icmp_seq=24 ttl=57 time=3.654 ms
--- 2409:804c:2000:2::1 ping statistics ---
25 packets transmitted, 22 packets received, 12% packet loss
round-trip min/avg/max/stddev = 3.606/4.100/5.562/0.608 ms

Temporary failure in name resolution 似乎是DNS配置问题

测试IPV6

Windows

以下Windows版本的ping命令支持ping IPv6地址:

  • Windows XP with SP1 及以上
  • Windows Vista 及以上
  • Windows Server 2003 及以上

ping ipv6主机名

ping -6 ipv6.google.com
ping -6 ipv6.test-ipv6.com  
ping -6 ipv6.baidu.com

**/!\注意:**当ping ipv6主机名时,必须加上参数-6;直接ping IPv6地址时可以省略。

ping ipv6地址

ping IPv6Address[%ZoneID]

例如:

ping 2001:4860:0:2001::68

如果要ping link-local地址,则需要指定网络接口索引,如:

ping fe80::260:97ff:fe02:6ea5%4

其中**%4**表示“用索引为4的网络接口”ping目标计算机。

Linux

在Linux发行版中,使用ping6命令ping IPv6主机或者地址。

ping ipv6主机名

ping6 ipv6.google.com

ping ipv6地址

ping6 IPv6Address[%InterfaceName]

如果要ping link-local地址,则需要指定网络接口名称,如:

ping fe80::260:97ff:fe02:6ea5%eth0

其中**%eth0**表示“用网络接口eth0 ping目标计算机”。

ping dns

ping6  2409:804c:2000:2::1

ssh

ssh root@fe80::c09a:4363:5763:32%enpxxx(网卡名称)

chrome IPV6

Chrome 地址栏输入

about:net-internals/#dns

访问 https://www.test-ipv6.com/

nginx支持ipv6

nginx 1.14 开始就默认支持ipv6了,不再需要添加编译参数 --with-ipv6,可以直接配置监听 ipv6

检查nginx是否监听了ipv6

netstat -tuln

同时监听IPV4和IPV6

server  {
....
listen  [::]:80;
listen  [::]:443;
...
}

只监听IPV6

server  {
....
listen  [::]:80  default  ipv6only=on;
listen  [::]:443  default  ipv6only=on;
...
}

监听指定IPV6地址

{
....
listen  [3608:f0f0:3002:31::1]:80;
listen  [3608:f0f0:3002:31::1]:443;
...
}

重启nginx

nginx -s reload

安全设置

暴露Nas到公网是会有很大安全隐患的,请注意你已经做好了安全防范!

  1. 开启动态安全码
  2. 开启防火墙,最好最高安全级别,自己控制端口开启
  3. 开启IP访问保护 失败登录尝试阻止时间调整
  4. 暴露出去的服务全部采用高强密码,最好所有服务全部采用高强度密码
  5. 尽量使用Docker,而不是套件版软件服务
  6. 重要数据定期离线备份

由于所有的link-local地址都有相同的前缀FE80::/64,并且每个网络接口都必须分配一个link-local地址,因而导致当发送数据包到一个link-local地址时,如果路由器使用普通的路由方法就无法决定选用哪个网络接口。因此,引入了一种被叫做zone index的标识符,它提供额外的路由信息,这个标识符通常指网络接口,并且通过一个百分号(%)被附加在IPv6地址后面。但是准确的表示方法还取决于操作系统:

Windows: 使用网络接口索引表示

如:

fe80::3%1
fe80::260:97ff:fe02:6ea5%4

要查看网络接口索引,请执行该命令:

netsh interface ipv6 show address

Linux: 使用网络接口名称表示

如:

fe80::3%eth0
fe80::260:97ff:fe02:6ea5%tun0

Linux只需要ifconnfig命令就可列出所有网络接口名称。

参考

系列教程

全部文章RSS订阅

Docker系列

Docker 分类 RSS 订阅

附赠

alpine linux 使用国内镜像源进行加速

Alpine 的源文件为:

/etc/apk/repositories

这里面的默认配置例如:

http://dl-cdn.alpinelinux.org/alpine/v3.11/main
http://dl-cdn.alpinelinux.org/alpine/v3.11/community

可以使用以下命令来进行源的切换(阿里云源):

sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

中国科技大学的源:

sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

清华源:

sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories

目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。

Alpine 使用 apk 来进行包管理。

可以在 Docker file 中添加以下语句,来加速 apk 的包管理。

...
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN apk add --no-cache gcc musl-dev linux-headers
...

注: sed 可依照脚本的指令来处理、编辑文本文件。 Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。


作者: 夜法之书
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 夜法之书 !
评论
数据加载中 ...
 上一篇

阅读全文

如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers Containers 的反向代理
如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers Containers 的反向代理 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers Containers 的反向代理
traefik 与 nginx 一样是反向代理工具,或者叫 Edge Router。具有无须重启即可更新配置,自动的服务发现与负载均衡,与 docker 完美集成 等优点。
2021-10-14
下一篇 

阅读全文

CMake快速入门教程
CMake快速入门教程 CMake快速入门教程
cmake是跨平台的makefile文件生成工具,是为了解决各个平台下面make工具不同造成的makefile文件格式不同的问题.也就是cmake是用来解决跨平台编译问题的.
2021-10-12