参考:Install OpenZiti and Protect a Web Server Overview (youtube.com)
概述
物理架构
- openziti的控制器和路由器部署在云服务器中,可通过公网访问
- 下文将在本地局域网中测试,不使用云服务器,用本地的一台虚拟机部署openziti,
- web服务器和隧道器部署在本地虚拟机的两个docker容器中,这两个docker容器在同一个docker网络中
- 本地win系统作为客户端访问web服务器时,流量经过:客户端隧道器 - ziti网络 - 服务端隧道器-web服务器
逻辑架构
HTTP 客户端的网络请求将被 OpenZiti 隧道器拦截。一旦被拦截,数据包就会被传送到 OpenZiti 覆盖网络,该结构负责将被拦截的数据包传送到目标身份。一旦传送到目标身份,流量将卸载回底层网络,然后发送到最终目的地:HTTP 服务器
构建openziti网络
配置环境变量
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# export EXTERNAL_DNS="acme.example.com"
# export EXTERNAL_IP="$(curl -s eth0.me)"
# 本地测试的话设置为本机ip
export EXTERNAL_DNS="192.168.1.135"
export EXTERNAL_IP="192.168.1.135"
export ZITI_CTRL_EDGE_IP_OVERRIDE="${EXTERNAL_IP}"
export ZITI_ROUTER_IP_OVERRIDE="${EXTERNAL_IP}"
export ZITI_CTRL_EDGE_ADVERTISED_ADDRESS="${EXTERNAL_DNS:-${EXTERNAL_IP}}"
export ZITI_ROUTER_ADVERTISED_ADDRESS="${EXTERNAL_DNS:-${EXTERNAL_IP}}"
export ZITI_CTRL_ADVERTISED_PORT=8440
export ZITI_CTRL_EDGE_ADVERTISED_PORT=8441
export ZITI_ROUTER_PORT=8442
|
- 安装依赖
1
|
sudo apt-get install tar hostname jq curl
|
- 下载OpenZiti 二进制文件并解压缩到
~/.ziti/quickstart/$(hostname -s)
1
|
source /dev/stdin <<< "$(wget -qO- https://get.openziti.io/ziti-cli-functions.sh)"; expressInstall
|
如果之前运行过 expressInstall
,请先清理旧的安装:
1
2
3
4
5
6
7
|
rm -rI "${ZITI_HOME}" # probably a sub-directory of ~/.ziti/quickstart/
# 没有${ZITI_HOME}环境变量的话用绝对路径
rm -rI ~/.ziti/quickstart
unsetZitiEnv
# 记得重新执行上面的环境变量
lsof -i:8441
kill -9 [PID]
|
报错1:没有下载到ziti二进制文件
解决:
- 多试几次
- 科学上网
1
2
3
4
5
6
7
8
|
# 配置
export https_proxy=http://192.168.1.1:7890
export http_proxy=http://192.168.1.1:7890
export all_proxy=socks5://192.168.1.1:7890
# 删除
export -n all_proxy
export -n http_proxy
export -n https_proxy
|
报错2:等待控制器上线
Wait for Controller - Ziti Overlay - openziti
主机OpenZiti Anywhere无法注册-支持- openziti — Host OpenZiti Anywhere Unable to enroll - Support - openziti
https://openziti.discourse.group/t/quicksetup-waiting-to-enroll/1001/2
- 启动控制器
- 查看控制器的侦听地址和端口:此值默认为:
$(hostname -s):1280
1
|
echo ${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS}:${ZITI_CTRL_EDGE_ADVERTISED_PORT}
|
- 验证控制器是否可用
1
|
curl -sk "https://${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS}:${ZITI_CTRL_EDGE_ADVERTISED_PORT}"
|
- 启动edge路由器
- 查看路由器的侦听地址和端口:此值默认为:
$(hostname -s):3022
1
|
echo $ZITI_ROUTER_ADVERTISED_ADDRESS:$ZITI_ROUTER_PORT
|
- 使用
ziti
CLI 登录到网络
- 查看边缘路由器是否在线
1
|
ziti edge list edge-routers
|
- 查看边缘路由器的身份
1
|
ziti edge list identities
|
配置openziti服务
安装SSH:方便移动jwt
文件
1
|
sudo apt-get install openssh-server
|
- 在ziti为 HTTP 服务端创建
http-server
身份
1
|
ziti edge create identity user http-server -o http-server.jwt
|
执行下面的命令,设置环境变量,登录ziti Cli
1
2
|
. ~/.ziti/quickstart/wyatt/wyatt.env
zitilogin
|
- 在ziti中为 HTTP 客户端创建
http-client
身份
1
|
ziti edge create identity user http-client -o http-client.jwt
|
- 在ziti中注册服务端
host
配置:创建host.v1
配置,该配置用于指示服务端隧道器如何将流量从覆盖层卸载回底层
1
|
ziti edge create config sample-web-app-host.v1 host.v1 '{"protocol":"tcp", "address":"sample-web-app", "port":8000}'
|
- 在ziti中注册客户端流量拦截器配置:创建
intercept.v1
配置,该配置用于指示客户端隧道器如何正确拦截目标流量并将其放到叠加网络上
1
|
ziti edge create config sample-web-app-intercept.v1 intercept.v1 '{"protocols":["tcp"],"addresses":["sample-web-app.ziti"], "portRanges":[{"low":8000, "high":8000}]}'
|
- 在ziti中创建服务:创建一个服务,将创建的客户端和服务端隧道配置关联到一个服务中
1
|
ziti edge create service sample-web-app.svc --configs sample-web-app-intercept.v1,sample-web-app-host.v1
|
- 创建服务策略:授权“HTTP 客户端”“拨号”代表 HTTP 服务器的服务
1
|
ziti edge create service-policy sample.web.app.policy.dial Dial --service-roles "@sample-web-app.svc" --identity-roles '@http-client'
|
- 创建服务策略:授权“HTTP 服务器”“绑定”表示 HTTP 服务器的服务
1
|
ziti edge create service-policy sample.web.app.policy.bind Bind --service-roles '@sample-web-app.svc' --identity-roles "@http-server"
|
配置HTTP服务端
此处为了方便,我将web服务也放在openziti网络所在虚拟机中
- 在HTTP服务端创建一个docker网络
httpServerNetwork
:为了使Web服务器能够与隧道器通信,同时也为了网络隔离和安全通信
1
|
docker network create httpServerNetwork
|
- 在HTTP服务端启动web服务器
1
|
docker run --rm --network httpServerNetwork --network-alias sample-web-app crccheck/hello-world
|
docker run
: 启动一个 Docker 容器。
--rm
: 表示容器停止后会自动删除,保持环境干净。
--network httpServerNetwork
: 将容器连接到名为 httpServerNetwork
的网络中,使其能够与同一网络中的其他容器进行通信。
--network-alias sample-web-app
: 为容器指定了一个网络别名 sample-web-app
,可以在网络中使用这个别名来访问该容器。
crccheck/hello-world
: 这是要运行的 Docker 镜像,具体来说是 crccheck
用户名下的 hello-world
镜像,这是一个简单的示例镜像,通常用于测试 Docker 安装是否正常运行。
总结来说,这条命令的目的是在叫做 httpServerNetwork
的docker
网络中启动一个 crccheck/hello-world
镜像的容器,并允许使用别名 sample-web-app
在 httpServerNetwork
网络中访问这个容器
- 进入web服务器所在容器
heuristic_nobel
,从8000
端口下载内容并查看
1
2
3
4
|
docker ps -a
docker exec -it heuristic_nobel sh
wget http://localhost:8000
cat index.html
|
- 将
http_server.jwt
移动到HTTP服务器上的~/.ziti/ids
路径下
1
2
|
mkdir -p ~/.ziti/ids/
mv http-server.jwt ~/.ziti/ids/
|
- 在HTTP服务端启动隧道器
1
|
docker run --rm --network httpServerNetwork --network-alias zet --name ziti-edge-tunnel --volume ~/.ziti/ids:/ziti-edge-tunnel --env=NF_REG_NAME=http-server openziti/ziti-edge-tunnel:0.19.6 run-host
|
docker run
: 启动一个 Docker 容器。
--rm
: 表示容器停止后会自动删除,保持环境干净。
--network httpServerNetwork
: 将容器连接到名为 httpServerNetwork
的网络中,使其能够与同一网络中的其他容器进行通信。
--network-alias zet
: 为容器指定网络别名 zet
,可以在网络中使用这个别名来访问该容器。
--name ziti-edge-tunnel
: 给容器命名为 ziti-edge-tunnel
,这样可以方便地管理和操作这个容器。
--volume ~/.ziti/ids:/ziti-edge-tunnel
: 将本地系统中 ~/.ziti/ids
目录挂载到容器内的 /ziti-edge-tunnel
目录,实现在容器内外的数据共享。
--env=NF_REG_NAME=http-server
: 设置一个环境变量 NF_REG_NAME
的值为 http-server
,这样容器内的程序可以根据这个环境变量进行不同的配置或行为。
openziti/ziti-edge-tunnel:latest
: 指定要运行的 Docker 镜像是 openziti/ziti-edge-tunnel
,并且使用 latest
标签来确保使用最新版本。
run-host
: 这是传递给 openziti/ziti-edge-tunnel
镜像的参数,告诉它以主机模式运行,可能是指让容器以主机网络的方式运行。
这条命令的目的是在 Docker 中启动一个名为 ziti-edge-tunnel
的容器,将其连接到指定网络,并进行必要的配置和数据共享,然后以指定的主机模式运行 openziti/ziti-edge-tunnel
镜像。
Bug1
原因:连接不到控制器
解决:
- 通过查阅官方文档发现,原视频中使用的是
openziti/ziti-edge-tunnel
镜像,该镜像要配容器内部dns
,因此报错连接不到控制器;改为使用另一镜像openziti/ziti-host
,会报Bug2暂时未解决;
- 在最开始设置环境变量后,但会报Bug3、Bug4,此处Bug3可以解决,Bug4无法解决;
- 改用回
openziti/ziti-edge-tunnel
镜像,设置的环境变量会解决连接不到控制器的情况,但仍会报Bug4
Bug2
Bug3
原因:无权访问
解决:修改http-server.jwt
权限
Bug4
原因:缺少GLIBC_2.29
解决:修改镜像版本为0.19.6
配置HTTP客户端
- 为HTTP客户端下载隧道器:Windows | OpenZiti
- 在HTTP客户端使用一次性令牌
http-client.jwt
登记身份,将身份添加到HTTP客户端隧道器
- 创建服务策略后,客户端隧道器会显示有一个服务
测试结果
- 在客户端访问
http://sample-web-app.ziti:8000
- 查看web服务器上的响应
由此,openziti实现了web服务隐藏,客户端不知道web服务器的真实地址,只能通过ziti服务名来访问真实的web服务