跳转至

🌐 网络工程 / 软考网工

OpenVPN Docker 容器故障排查与修复

  • 手机通过 OpenVPN 连接后能访问 GitHub,但 Google/YouTube 无法访问
  • 根本原因:
  • DNS 配置错误: OpenVPN AS 推送的 DNS 是 127.0.0.11(Docker 内部 DNS),手机上不存在该地址
  • NAT 缺失: VPN 子网 172.27.0.0/16 没有做 MASQUERADE,包出去了但回不来
  • 解决方法:
  • 修改容器 /etc/resolv.conf 为公共 DNS(8.8.8.8 + 1.1.1.1
  • sacli 设置 vpn.client.routing.dns.0/1 为公共 DNS
  • 容器内添加 iptables NAT: iptables -t nat -A POSTROUTING -s 172.27.0.0/16 -o eth0 -j MASQUERADE
  • 修改 entrypoint 脚本使修复持久化
  • 关键知识点:
  • Docker 容器的 127.0.0.11 是内部 DNS 解析器,只在容器内有效
  • OpenVPN AS 配置要用 sacli 工具写入数据库,直接改 config-local.json 不生效
  • sacli ConfigPut → 写入配置,sacli Start/Stop → 重启服务
  • VPN 子网需要 NAT 才能访问外网,容器重启后 iptables 规则会丢失

反向代理(Reverse Proxy)技术

正向代理 vs 反向代理

  • 正向代理:代理客户端,帮客户端访问服务器(如 VPN、Fiddler)
  • 反向代理:代理服务器,帮服务器接收客户端请求(如 Nginx、HAProxy)

核心作用

  1. 安全隐藏:客户端不知道真实服务器,反向代理是"面具",集中配置 WAF/防火墙
  2. 负载均衡:多台后端服务器,按策略分发请求(轮询、加权轮询、IP Hash、最少连接)
  3. SSL 终结(SSL Termination):客户端 HTTPS → Nginx 卸载 SSL → 后端明文 HTTP,减少加密开销
  4. 缓存加速:静态资源由 Nginx 直接响应,动态请求转发后端,减轻服务器压力
  5. 统一入口:多服务只暴露 80/443,按域名/路径分发(server_name + location + proxy_pass)
  6. 压缩与限流:Gzip 压缩响应、限制请求速率防 DDoS

常用 Nginx 指令

  • proxy_pass:转发请求到后端地址
  • upstream:定义后端服务器组(负载均衡)
  • location:匹配请求路径
  • server_name:匹配域名

实际例子

客户端 → Nginx :443 (HTTPS) → :8000 (MkDocs)
好处:加 HTTPS、绑域名、隐藏端口、统一管理

考试/面试要点

  • 正向代理代表客户端,反向代理代表服务器
  • 负载均衡四种算法:轮询、加权轮询、IP Hash、最少连接
  • SSL 终结在代理层卸载加密

Mac 生成 SSH 密钥

基本命令

ssh-keygen -t ed25519 -C "邮箱@example.com"
默认保存到 ~/.ssh/id_ed25519,一路回车即可。

指定文件名

ssh-keygen -t ed25519 -f ~/.ssh/mykey -C "邮箱"

传公钥到服务器

ssh-copy-id -i ~/.ssh/id_ed25519.pub 用户名@服务器IP

Mac 无 ssh-copy-id 的替代方案

cat ~/.ssh/id_ed25519.pub | ssh 用户名@服务器 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

注意

  • ed25519 优于 RSA(更安全更快),除非老设备不支持
  • 兼容老设备用 ssh-keygen -t rsa -b 4096
  • 私钥别泄露,公钥可公开

ed25519 是什么

定义

ed25519 是一种非对称加密算法,具体是椭圆曲线数字签名算法(EdDSA)。

名称拆解

  • Ed = Edwards 曲线(椭圆曲线变体)
  • 25519 = Curve25519(曲线参数名,Daniel Bernstein 设计)

在 SSH 中的作用

生成公钥/私钥对。公钥放服务器验证身份,私钥自己留着证明身份。

与其他算法对比

  • ed25519:密钥短、速度快、安全性高,首选
  • RSA:老牌兼容性好,但需 4096 位才够安全
  • ecdsa:比 RSA 好,有潜在随机数漏洞

优势

  1. 密钥短(公钥仅 68 字符 vs RSA 几百字符)
  2. 生成和验证速度快
  3. 抗侧信道攻击,不依赖随机数质量
  4. 256 位密钥 ≈ RSA 3072 位安全强度

SSH 公钥存放位置

服务器端路径

~/.ssh/authorized_keys

设置步骤

mkdir -p ~/.ssh && chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
cat 公钥.pub >> ~/.ssh/authorized_keys

Mac 一行命令传公钥

cat ~/.ssh/id_ed25519.pub | ssh 用户名@IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

权限要求

  • ~/.ssh/ → 700(rwx------)
  • authorized_keys → 600(rw-------)
  • 权限不对 SSH 会忽略公钥文件

authorized_keys 放多个公钥

直接放(推荐)

~/.ssh/authorized_keys 里一行放一把公钥,SSH 依次匹配:

ssh-ed25519 AAAA...公钥1 用户1@电脑1
ssh-ed25519 AAAA...公钥2 用户2@电脑2
吊销某把公钥直接删对应行即可。

分文件放(进阶)

/etc/ssh/sshd_config 中配置:

AuthorizedKeysFile .ssh/authorized_keys .ssh/keys/%u/%t/%k
然后按用户/用途分目录存放公钥。一般没必要,直接塞 authorized_keys 最简单。


Tailscale 组网与局域网访问

纯命令行登录

  1. 安装:curl -fsSL https://tailscale.com/install.sh | sh
  2. 执行 sudo tailscale up,终端会输出一个授权 URL
  3. 用任意能上网的设备(手机/电脑浏览器)打开该 URL,用 Tailscale 账号登录并授权
  4. 服务器终端会自动完成认证
  5. 其他方式:--auth-key=tskey-auth-xxx(预共享密钥,适合自动化部署)
  6. 本质:CLI 发起请求,浏览器完成授权,两步分离

Tailscale IP 与子网掩码

问题:Tailscale 分配的 IP 为什么只有第一段 100 相同,第二三段都不同?

解答:Tailscale 使用 100.64.0.0/10 网段,/10 表示前 10 位是网络位:

100 = 01100100(二进制)
/10 要求前 10 位固定:01100100 01xxxxxx ...
第二字节只有前 2 位固定(必须是 01),后 6 位可变
所以第二字节范围 64-127,第三四字节完全自由,22 位主机位可分配约 419 万台

子网掩码对照: - /24(255.255.255.0):前 24 位固定,254 台主机 - /16(255.255.0.0):前 16 位固定,65534 台主机 - /10(255.192.0.0):前 10 位固定,约 419 万台主机

关键理解:不是前几位数字相同才算同一子网,而是按位数算。/10 只要求前 10 位一样,第一个字节相同 + 第二个字节前两位相同就够了

CIFS 挂载(客户端访问 Samba 共享)

命令sudo mount -t cifs //100.x.x.x/共享名 /mnt/samba -o username=用户,password=***

逐项拆解: - sudo:挂载是系统级操作,需要 root 权限 - mount -t cifs:把远程 SMB/CIFS 共享映射到本地目录 - //IP/共享名:远程地址 + 共享名(// 固定格式) - /mnt/samba:本地挂载点

安全写法(密码写文件避免明文泄露):

echo "username=用户" | sudo tee /root/.smbpasswd
echo "password=密码" | sudo tee -a /root/.smbpasswd
chmod 600 /root/.smbpasswd
sudo mount -t cifs //IP/共享 /mnt/samba -o credentials=/root/.smbpasswd

常用挂载选项:uid=1000(所有者), gid=1000(组), iocharset=utf8(中文乱码), vers=3.0(SMB协议版本), ro(只读)

卸载sudo umount /mnt/samba,有进程在用时报 target is busy

服务器端安装客户端工具

# smbclient 是命令行工具,cifs-utils 提供 mount -t cifs 支持
# 都是客户端工具,不监听端口,不需要管理服务
sudo apt install smbclient cifs-utils

是否需要一直挂载? - 挂载点本身几乎不占资源,但网络断了会卡死(进程等待、命令卡住) - 偶尔用:手动 mount / umount - 经常用:用 autofs 自动挂载(访问时挂载,闲置 5 分钟自动卸载) - autofs 配置:echo "/mnt/samba -fstype=cifs,credentials=/root/.smbpasswd ://IP/共享" >> /etc/auto.smb