惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
D
DataBreaches.Net
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
B
Blog
U
Unit 42
有赞技术团队
有赞技术团队
博客园 - 聂微东
GbyAI
GbyAI
宝玉的分享
宝玉的分享
F
Full Disclosure
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
Jina AI
Jina AI
Martin Fowler
Martin Fowler
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
P
Proofpoint News Feed
A
About on SuperTechFans
I
InfoQ
博客园 - 【当耐特】
C
Check Point Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
Y
Y Combinator Blog
Project Zero
Project Zero
WordPress大学
WordPress大学
小众软件
小众软件
AWS News Blog
AWS News Blog
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
I
Intezer
Engineering at Meta
Engineering at Meta
C
CXSECURITY Database RSS Feed - CXSecurity.com
J
Java Code Geeks
T
Tenable Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes

邢平cn's blog

甲骨文密钥 ssh 连不上且忘记登录密码解决方法 让 traefik 代替你的 waf(使用 CrowdSec)+ nginx + acme.sh + mtls-auth 使用 rclone 和 alist 加密和备份你的数据到公有云 邓晓芒《黑格尔辩证法讲演录》读书笔记 如何白嫖和使用 GitHub models 的 LLM(gpt4o 和 Llama-3.1-405b) 提升部署在 cloudflare、vercel 或 netlify 的网站在中国国内的访问速度和稳定性 免费通过 NS1 利用监控宝平台实现实时基于不同运营商的故障转移 记录某一测速网站的 js 逆向的过程 列举几个免费域名和权威 dns 服务器 Hexo 博客折腾 尝试在闲置的 surface pro 4 上运行安卓应用 国内各个 as 自治系统[转] 『现学现忘』Git基础 — 19、在Git中进行忽略文件操作 让在 vpc 中的 aws lambda 函数不通过 nat 获得访问互联网的能力 cron 笔记 curl 遇到的坑 你的常用域名被其他 vercel 账号使用的解决方法 解决升级 umamiv2.11 时出现的 P3009 错误 v2ray+ws+tls 太慢解决方法 在 python 中运行 bash 实时输出结果(windows) 在存在父子文件结构情况下使用 python import
docker 学习笔记
xingpingcn · 2023-04-21 · via 邢平cn's blog

通过学习 docker-compose 将 hysteria2 通过 bridge 模式提供服务

这是一篇通过配置 hysteria2 学习 docker-compose 的笔记

前言

用官方的 docker 和配置 3 分钟就搭好了,但是想试试通过 bridge 和通过 nginx 反代来实现(最后没有实验),于是就开始了折腾,,,

docker 的 network 模式

docker 会隔离文件、网络、进程,而网络的隔离程度分为 4 种:

  • host 这个相当于和主机共用一个网络
  • none 容器不需要内部和外部网络
  • container 似乎是容器内的网络,和主机分离。
  • bridge 命令 docker network create 的默认模式,连接到该网络的容器可以互相连通,而且可以暴露端口给主机和主机通讯。客户端通过 主机ip:port 访问。
Tip (NOTE)

docker 默认创建除 container 的三个网络。可以通过 docker network ls 查看。

root@:/bin/hy2# docker network ls

NETWORK ID NAME DRIVER SCOPE

c069db7ead85 bridge bridge local

cf668a8174a8 host host local

162c8b1b3229 nginx-proxy bridge local # `nginx-proxy`是我自己创建的。

4f9ce671d49a none null local

Tip (NOTE)

值得注意的是,docker 默认创建一个名为 docker0 的网口用于连接主机和容器。通过 ip link 查看 进入 hy2 容器执行 ip link 命令可以看到,hy2 的网卡(eth0)是和主机上的 veth6f76815 虚拟网卡连接(240:241)

root@445:/bin/hy2# ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

link/ether [隐私删除] brd ff:ff:ff:ff:ff:ff

altname enp0s3

altname ens3

3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default

link/ether 02:42:4e:38:4d:51 brd ff:ff:ff:ff:ff:ff

12: br-162c8b1b3229: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default

link/ether 02:42:93:b0:6a:4a brd ff:ff:ff:ff:ff:ff

223: veth3452fbb@if222: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-162c8b1b3229 state UP mode DEFAULT group default

link/ether d2:85:53:63:a1:76 brd ff:ff:ff:ff:ff:ff link-netnsid 0

241: veth6f76815@if240: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-162c8b1b3229 state UP mode DEFAULT group default

link/ether aa:e0:71:cf:9e:50 brd ff:ff:ff:ff:ff:ff link-netnsid 1

root@445:/bin/hy2# docker exec -it hy2 /bin/bash

1cb800f27bd1:/# ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

240: eth0@if241: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP

link/ether 02:42:ac:14:00:03 brd ff:ff:ff:ff:ff:ff

1cb800f27bd1:/#

配置 hy2 的 yaml

官方的 yaml 是使用的 host 模式,我现在要创建一个名为 nginx-proxy 的网络并且在配置文件中更改。

version: '3.9'

services:

hysteria:

image: tobyxdd/hysteria

container_name: hy2

restart: always

volumes:

- acme:/acme

- ./hysteria.yaml:/etc/hysteria.yaml

command: ['server', '-c', '/etc/hysteria.yaml']

networks:

- nginx-proxy

ports:

- '10808:443'

# expose:

# - "443"

networks:

nginx-proxy:

external: true

volumes:

acme:

这样我以为就可以通过访问 10808 端口科学上网了。但是 ping 不通,,,

经过努力的排查,找到了 docker inspect 命令,发现容器被分配的 IP 是空的,,,

原来还需要手动通过输入 docker network connect 来连接,,,我看 nginx 是自动连接的,不知道对应的 yaml 怎么写。

结果还是是 ping 不通,,,

iptables -t nat -nvL --line-number 查看发现,Chain DOCKER 里也有容器 IP 的 DNAT 了,为什么还是不行。

不细心眼力不好还发现不了,是暴露端口的时候默认暴露 tcp,,,。结合 hy2 文档也知道 hy2 是基于 udp 的,然后更改配置

services:

hysteria:

ports:

- "10808:443/udp"

...

成功!

但是关闭连接的时候就会出错再也连不上,通过日志发现,原来关闭的时候通过 tcp 沟通的。

最终的配置文档应该像这样的

services:

hysteria:

ports:

- "10808:443/udp"

- "10808:443/tcp"

...

最后删除多余的 NAT,和设置新的 NAT,并备份 iptables

Warning (warning)

iptables-save -f /etc/iptables/rules.v4 适用于 Debian,其他系统可能会恢复不了 iptables

iptables -t nat -D PREROUTING 1

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 20000:50000 -j DNAT --to-destination :10808

iptables-save -f /etc/iptables/rules.v4

systemctl restart iptables

Warning (warning)

如果使用 ufw,则修改以下文件。重启 ufw 的时候不会删除 iptables 已经有的规则,也就是说重复重启 ufw 会添加多条相同的规则,需要手动删除。

Warning (warning)

注意!必须在前一个 filter block 最后,即 COMMIT 之后添加!

最后只放行那个要转发的端口!

例如 ufw allow 12345,而不是 ufw allow 20000-50000

# 注意!必须在前一个filter block最后,即COMMIT之后添加!

# don't delete the 'COMMIT' line or these rules won't be processed

COMMIT

# Custom

*nat

:PREROUTING ACCEPT [0:0]

-A PREROUTING -i eth0 -p udp --dport 10000:30000 -j DNAT --to-destination :3456

COMMIT

最后放上配置

listen: :10808

#acme:

#domains:

# - xxx #把xxx.com改成你的域名,需要先解析到服务器ip

#email: @gmail.com #可以改成自己邮箱,也可以把test这里随便加几个字符

tls:

cert: /etc/cert/domain.com.cert.pem

key: /etc/cert/domain.com.key.pem

auth:

type: password

password: #设置密码

masquerade:

type: proxy

proxy:

url: https://bing.com #伪装网址

rewriteHost: true

quic:

initStreamReceiveWindow: 26843545

maxStreamReceiveWindow: 26843545

initConnReceiveWindow: 67108864

maxConnReceiveWindow: 67108864

nginx 初次使用

由于 nginx 运行在 docker 内,而每个 docker 都会被 network 的虚拟网关分配一个 ip,如果 nginx 要反代同一 network 内的 docker container 是不是就要预先知道它的 ip 呢?这样做其实也可以,但是如果机器重启就会出问题,因为重启后每个容器的 ip 会被重新分配,分配的规则我猜测是根据启动顺序来决定的。更优雅的方式是直接使用 container 的别名作为 ip

例如在同一网络内有两个 container,别名分别为 nginx_testapi,则 nginx_test 的反代配置应该是类似于这样的。

server {

listen 80;

server_name localhost;

location /api {

proxy_pass http://api:3000;

}

}

以上情况只是适用于 nginx 通过 docker 部署的情况。而我用的是直接安装在主机的方式,反代的容器需要暴露端口到 localhost

services:

hysteria:

ports:

- "127.0.0.1:3000:443/udp"

- "127.0.0.1:3000:443/tcp"

...

这样子,使用 ip:10808 就不能访问了,必须在 nginx 那里反代 proxy_pass http://127.0.0.1:3000; 通过 ip:443 访问

Warning (WARNING)

hy2 并不支持和 nginx 共享 443 端口,所以需要自己用 acme 申请证书,然后在 hy2 的配置中填写 tls

nginx 安装和证书自动申请

意外地发现需要结合多个教程才能搞定,记录一下备忘

有两种方法,一种是 acme.sh,一种是 Certbot,后者更加方便,但是过程中做了什么我不知道,前者需要手动的地方更多,但是你会知道证书放在了哪里。

可以先设置软连接。注意路径,第一个为默认的 nginx 配置路径,第二个为你要软连接的路径。

ln -s /etc/nginx/nginx.conf /home/nginx/nginx.conf

acme.sh

先在 conf 中写好域名,acme.sh 会根据配置帮你申请域名

server {

server_name domain.com;

listen 80;

}

安装 acme.sh 后,重新 打开一个终端,输入以下命令;需要域名先指向你的 vps

acme.sh --issue -d domain.com --nginx /home/nginx/nginx.conf

这里有个可以不用 nginx 的方法,如果使用的是华为云,可以运行以下命令。原理就是利用 api 自动添加 txt 记录。如果需要更多支持的 dns 请点击这里,基本上包含了主流 dns 服务器了。

export HUAWEICLOUD_Username=""

export HUAWEICLOUD_Password=""

export HUAWEICLOUD_DomainName="" # 注意的是这个的中文名为账户名而不是域名,需要你去设置里面查看

acme.sh --issue --dns dns_huaweicloud -d example.com -d *.example.com #填写你的域名

最后运行以下命令。快到期会自动续。注意路径。

acme.sh --install-cert -d domain.com \

--key-file /home/nginx/cert/domain.com.key.pem \

--fullchain-file /home/nginx/cert/domain.com.cert.pem \

--reloadcmd "nginx -s reload"

第一个命令是申请证书,证书会放在 acme.sh 自己脚本所在的目录,所以后面要使用 --install-cert 安装。这个并不会修改 conf,所以要手动配置。

再打开 conf,填写 443 端口,之后就会在过期前 30 天自动更新

server{

listen 443 ssl;

server_name domain.com;

location /{

client_max_body_size 64m;

proxy_http_version 1.1;

proxy_pass http://localhost:8080; # 请根据实际情况修改你的端口

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $remote_addr;

proxy_cache_bypass $http_upgrade;

proxy_set_header Accept-Encoding gzip;

proxy_read_timeout 360s; # GPT-4 需要较长的超时时间,请自行调整

}

ssl_certificate /home/nginx/cert/domain.com.cert.pem;

ssl_certificate_key /home/nginx/cert/domain.com.key.pem;

# ssl_session_cache shared:SSL:1m;

# ssl_session_timeout 5m;

# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;

access_log /home/nginx/log/domain.com.access.log;

error_log /home/nginx/log/domain.com.error.log;

}

Certbot

sudo snap install --classic certbot

sudo ln -s /snap/bin/certbot /usr/bin/certbott

之后 conf 中填写好 443 端口

使用 certbot 获取 SSL 证书:sudo certbot --nginx

sudo vim ./push 查看更改。重启 nginx

重启 nginx

有两个,前者确定不会重启 nginx,后者应该会。

nginx -s reload

service nginx restart

容器更新

docker-compose pull

docker-compose up -d --remove-orphans # 重启

docker image prune # 删除旧的