[{"data":1,"prerenderedAt":782},["ShallowReactive",2],{"content:\u002Fposts\u002Flinux-openvpn-installation-guide":3,"surround:\u002Fposts\u002Flinux-openvpn-installation-guide":772},{"id":4,"title":5,"body":6,"categories":740,"date":742,"description":743,"draft":744,"extension":745,"image":746,"meta":747,"navigation":749,"path":750,"permalink":746,"pinned":744,"published":746,"readingTime":751,"recommend":746,"references":746,"seo":756,"sitemap":757,"stem":758,"tags":759,"type":770,"updated":742,"__hash__":771},"content\u002Fposts\u002Fposts\u002Flinux-openvpn-installation-guide.md","Linux 下 OpenVPN 快速部署与配置全攻略",{"type":7,"value":8,"toc":713},"minimark",[9,19,24,27,43,51,58,61,72,76,80,105,108,120,124,128,151,211,215,222,227,235,243,249,255,262,266,273,279,310,314,317,323,330,336,339,345,352,356,360,369,375,393,427,431,434,440,458,487,491,494,500,503,507,692,707],[10,11,15],"alert",{"title":12,"type":13,"icon":14},"AI 迁移提示","info","tabler:robot",[16,17,18],"p",{},"本文由 AI 协助从旧站迁移，尚未完成逐篇人工审校；内容如有疏漏，将在复核后修订。",[20,21,23],"h2",{"id":22},"为什么自建-openvpn","为什么自建 OpenVPN",[16,25,26],{},"自建 OpenVPN 常见场景：",[28,29,30,34,37,40],"ul",{},[31,32,33],"li",{},"出差 \u002F 异地时接回家庭或公司内网",[31,35,36],{},"多个 HomeLab 机房跨地域组网",[31,38,39],{},"访问云上 VPC 的私有子网",[31,41,42],{},"需要一个能穿越绝大多数防火墙的稳定 VPN 协议",[16,44,45,46,50],{},"相比 WireGuard、ZeroTier、Tailscale 这些更现代的方案，OpenVPN 的优势是",[47,48,49],"strong",{},"历史悠久、客户端全平台覆盖、路由器 \u002F OpenWRT \u002F PVE 固件几乎都原生支持","；缺点是性能不如 WireGuard、握手速度一般、配置相对复杂。",[16,52,53,54,57],{},"如果没有既定技术选型，刚起步做 VPN 推荐先看 WireGuard；本文针对",[47,55,56],{},"已经决定用 OpenVPN"," 的读者。",[20,59,60],{"id":60},"本文结构",[62,63,68],"pre",{"className":64,"code":66,"language":67},[65],"language-text","服务端（你有一台公网 VPS \u002F 家里有公网 IP）\n    ├── 一键脚本（推荐，90% 场景够用）\n    └── 手动 easy-rsa（想理解 PKI 原理）\n               ↓\n     生成 .ovpn 客户端配置文件\n               ↓\n客户端（手机 \u002F 电脑 \u002F 其他 Linux 服务器）\n    ├── 安装 OpenVPN（按发行版）\n    ├── 放 .ovpn 或 client.conf\n    └── 用 systemd（主流）或 OpenRC（Alpine）跑\n","text",[69,70,66],"code",{"__ignoreMap":71},"",[20,73,75],{"id":74},"_1-前置条件","1. 前置条件",[77,78,79],"h3",{"id":79},"服务端",[28,81,82,88,91,94],{},[31,83,84,87],{},[47,85,86],{},"一台有公网 IP 的服务器","（国外 VPS \u002F 国内有公网 IP 的 VPS \u002F 家里有公网的路由器后台机器都行）",[31,89,90],{},"系统为 Debian \u002F Ubuntu \u002F RHEL 系（CentOS \u002F Rocky \u002F AlmaLinux） \u002F Alpine \u002F Arch 任一",[31,92,93],{},"root 或 sudo 权限",[31,95,96,97,100,101,104],{},"云厂商",[47,98,99],{},"安全组","和主机",[47,102,103],{},"防火墙","放行 OpenVPN 端口（默认 UDP 1194）",[77,106,107],{"id":107},"客户端",[28,109,110,113],{},[31,111,112],{},"任意 Linux \u002F Windows \u002F macOS \u002F Android \u002F iOS 设备",[31,114,115,116,119],{},"能从服务端获取 ",[69,117,118],{"code":118},".ovpn"," 配置文件（U 盘 \u002F SCP \u002F 安全聊天工具等）",[20,121,123],{"id":122},"第二部分客户端接入","第二部分：客户端接入",[20,125,127],{"id":126},"_4-安装-openvpn-客户端","4. 安装 OpenVPN 客户端",[10,129,132],{"title":130,"type":131},"客户端和服务端是同一个软件","tip",[16,133,134,135,138,139,142,143,146,147,150],{},"OpenVPN 的服务端和客户端是同一个 ",[69,136,137],{"code":137},"openvpn"," 二进制，靠配置文件里是 ",[69,140,141],{"code":141},"mode server"," \u002F ",[69,144,145],{"code":145},"client"," 区分。所以",[47,148,149],{},"下面的安装命令和前面服务端完全一样","。如果这台机器只做客户端，不装 easy-rsa 也行。",[152,153,154,167],"table",{},[155,156,157],"thead",{},[158,159,160,164],"tr",{},[161,162,163],"th",{},"发行版",[161,165,166],{},"命令",[168,169,170,181,191,201],"tbody",{},[158,171,172,176],{},[173,174,175],"td",{},"Debian \u002F Ubuntu",[173,177,178],{},[69,179,180],{"code":180},"sudo apt install -y openvpn",[158,182,183,186],{},[173,184,185],{},"RHEL \u002F CentOS \u002F Rocky \u002F Alma",[173,187,188],{},[69,189,190],{"code":190},"sudo dnf install -y epel-release && sudo dnf install -y openvpn",[158,192,193,196],{},[173,194,195],{},"Alpine",[173,197,198],{},[69,199,200],{"code":200},"sudo apk add openvpn",[158,202,203,206],{},[173,204,205],{},"Arch",[173,207,208],{},[69,209,210],{"code":210},"sudo pacman -S --noconfirm openvpn",[20,212,214],{"id":213},"_5-客户端配置文件","5. 客户端配置文件",[77,216,218,219,221],{"id":217},"_51-方式-a直接用服务端给的-ovpn-文件推荐","5.1 方式 A：直接用服务端给的 ",[69,220,118],{"code":118}," 文件（推荐）",[16,223,224,226],{},[69,225,118],{"code":118}," 已经把 CA、证书、密钥都内嵌进去了，就一个文件。把它放到：",[62,228,233],{"className":229,"code":231,"language":232,"meta":71},[230],"language-bash","sudo mkdir -p \u002Fetc\u002Fopenvpn\u002Fclient\nsudo cp alice-laptop.ovpn \u002Fetc\u002Fopenvpn\u002Fclient\u002Fmyvpn.conf\n# 注意：systemd 模板单元读 \u002Fetc\u002Fopenvpn\u002Fclient\u002F 下的 .conf 文件（不是 .ovpn）\n# 所以这里重命名为 .conf\n","bash",[69,234,231],{"__ignoreMap":71},[77,236,238,239,242],{"id":237},"_52-方式-b手写最小-clientconf-模板","5.2 方式 B：手写最小 ",[69,240,241],{"code":241},"client.conf"," 模板",[16,244,245,246,248],{},"如果服务端没直接给 ",[69,247,118],{"code":118},"、只给了零散的证书文件，手写一个：",[62,250,253],{"className":251,"code":252,"language":67},[65],"client\ndev tun\nproto udp\nremote your-vpn-server.example.com 1194\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\nremote-cert-tls server\n\n# 证书 & 密钥（路径用绝对路径或相对 \u002Fetc\u002Fopenvpn\u002Fclient\u002F）\nca ca.crt\ncert client.crt\nkey client.key\ntls-auth ta.key 1\n\n# 如果服务端启用了\"用户名+密码\"额外认证，取消下一行的注释\n# auth-user-pass auth.txt\n\ncipher AES-256-GCM\nauth SHA256\nverb 3\n",[69,254,252],{"__ignoreMap":71},[16,256,257,258,261],{},"保存为 ",[69,259,260],{"code":260},"\u002Fetc\u002Fopenvpn\u002Fclient\u002Fmyvpn.conf","，对应的证书文件放同一目录。",[77,263,265],{"id":264},"_53-如果服务端启用了用户名密码认证","5.3 如果服务端启用了用户名密码认证",[16,267,268,269,272],{},"某些服务端会在证书之外再要求用户名密码（双重认证）。先在配置里启用 ",[69,270,271],{"code":271},"auth-user-pass auth.txt","，然后创建凭据文件：",[62,274,277],{"className":275,"code":276,"language":232,"meta":71},[230],"sudo tee \u002Fetc\u002Fopenvpn\u002Fclient\u002Fauth.txt > \u002Fdev\u002Fnull \u003C\u003CEOF\nyour_username\nyour_password\nEOF\nsudo chmod 600 \u002Fetc\u002Fopenvpn\u002Fclient\u002Fauth.txt\n",[69,278,276],{"__ignoreMap":71},[10,280,283],{"title":281,"type":282},"auth.txt 的权限 + 内容","warning",[28,284,285,296,299],{},[31,286,287,288,291,292,295],{},"文件",[47,289,290],{},"必须"," ",[69,293,294],{"code":294},"chmod 600","，否则 OpenVPN 会拒绝读取",[31,297,298],{},"严禁把真实密码写进博客 \u002F 教程 \u002F 提交到 Git",[31,300,301,302,305,306,309],{},"密码文件尽量放在 root 可读的目录（",[69,303,304],{"code":304},"\u002Fetc\u002Fopenvpn\u002Fclient\u002F","），不要放 ",[69,307,308],{"code":308},"\u002Ftmp"," 之类",[20,311,313],{"id":312},"_6-先手动前台运行验证一次","6. 先手动前台运行验证一次",[16,315,316],{},"正式做服务之前，先前台跑一次，确认配置有效、能连上：",[62,318,321],{"className":319,"code":320,"language":232,"meta":71},[230],"sudo openvpn --config \u002Fetc\u002Fopenvpn\u002Fclient\u002Fmyvpn.conf\n",[69,322,320],{"__ignoreMap":71},[16,324,325,326,329],{},"期望日志里",[47,327,328],{},"最后一行","出现：",[62,331,334],{"className":332,"code":333,"language":67},[65],"Initialization Sequence Completed\n",[69,335,333],{"__ignoreMap":71},[16,337,338],{},"看到这条就说明连接成功。另开一个终端验证：",[62,340,343],{"className":341,"code":342,"language":232,"meta":71},[230],"# 1. 是否出现 tun0 接口\nip a show tun0\n\n# 2. 是否有 VPN 内网 IP（如 10.8.0.x）\n# 3. 路由表是否把默认网关指到 tun0（如果服务端 push redirect-gateway）\nip route\n\n# 4. 出口 IP 是不是 VPN 服务端的 IP\ncurl -s https:\u002F\u002Fipinfo.io\u002Fip\n",[69,344,342],{"__ignoreMap":71},[16,346,347,348,351],{},"确认无误后在第一个终端 ",[69,349,350],{"code":350},"Ctrl+C"," 退出，进下一步做服务化。",[20,353,355],{"id":354},"_7-客户端服务化","7. 客户端服务化",[77,357,359],{"id":358},"_71-systemd-系debian-ubuntu-rhel-arch","7.1 systemd 系（Debian \u002F Ubuntu \u002F RHEL \u002F Arch）",[16,361,362,368],{},[47,363,364,365],{},"强烈推荐用官方模板单元 ",[69,366,367],{"code":367},"openvpn-client@.service","，不要自己造轮子。它已经自带了各种路径约定、权限处理、重连逻辑。",[62,370,373],{"className":371,"code":372,"language":232,"meta":71},[230],"# 配置文件放 \u002Fetc\u002Fopenvpn\u002Fclient\u002F\u003C名字>.conf\nls \u002Fetc\u002Fopenvpn\u002Fclient\u002Fmyvpn.conf\n\n# 启用并立即启动（开机自启 + 现在就跑）\nsudo systemctl enable --now openvpn-client@myvpn\n\n# 查看状态\nsudo systemctl status openvpn-client@myvpn\n\n# 实时日志\nsudo journalctl -u openvpn-client@myvpn -f\n\n# 停止 \u002F 禁用\nsudo systemctl disable --now openvpn-client@myvpn\n",[69,374,372],{"__ignoreMap":71},[16,376,377,378,381,382,384,385,388,389,392],{},"单元名后面的 ",[69,379,380],{"code":380},"@myvpn"," 和 ",[69,383,260],{"code":260}," 的文件名对应——想跑多个 VPN 配置各自独立，再放一份 ",[69,386,387],{"code":387},"\u002Fetc\u002Fopenvpn\u002Fclient\u002Foffice.conf"," 然后 ",[69,390,391],{"code":391},"enable --now openvpn-client@office"," 即可。",[10,394,396,402,420],{"title":395,"type":131},"为什么不自己写 .service 文件",[16,397,398,399,401],{},"OpenVPN 官方包自带 ",[69,400,367],{"code":367}," 模板已经处理了：",[28,403,404,411,414,417],{},[31,405,406,407,410],{},"自动找 ",[69,408,409],{"code":409},"\u002Fetc\u002Fopenvpn\u002Fclient\u002F%i.conf"," 作为配置",[31,412,413],{},"正确的 working directory、权限降级",[31,415,416],{},"网络就绪后再启动",[31,418,419],{},"进程异常退出自动重启",[16,421,422,423,426],{},"自己 ",[69,424,425],{"code":425},"cat > \u002Fetc\u002Fsystemd\u002Fsystem\u002Fopenvpn-client.service"," 写个简版，很容易漏掉其中一项导致\"前台能跑、服务跑不起来\"。",[77,428,430],{"id":429},"_72-openrcalpine","7.2 OpenRC（Alpine）",[16,432,433],{},"Alpine 用 OpenRC，没有 systemctl。",[62,435,438],{"className":436,"code":437,"language":232,"meta":71},[230],"# Alpine 默认 init 脚本读 \u002Fetc\u002Fopenvpn\u002Fopenvpn.conf\n# 如果你只跑一个 VPN，把配置文件改名放到那里\nsudo mv \u002Fetc\u002Fopenvpn\u002Fclient\u002Fmyvpn.conf \u002Fetc\u002Fopenvpn\u002Fopenvpn.conf\n\n# 启动 + 开机自启\nsudo rc-service openvpn start\nsudo rc-update add openvpn default\n\n# 状态\nsudo rc-service openvpn status\n\n# 日志（OpenRC 下日志通常在 \u002Fvar\u002Flog\u002Fmessages 或 \u002Fvar\u002Flog\u002Fopenvpn\u002F）\ntail -f \u002Fvar\u002Flog\u002Fmessages\n",[69,439,437],{"__ignoreMap":71},[16,441,442,445,446,449,450,453,454,457],{},[47,443,444],{},"多配置场景","：Alpine 的 init script 支持给每个配置文件起一个独立的 service。参考 ",[69,447,448],{"code":448},"\u002Fetc\u002Finit.d\u002Fopenvpn"," 的注释，常见做法是 ",[69,451,452],{"code":452},"ln -s \u002Fetc\u002Finit.d\u002Fopenvpn \u002Fetc\u002Finit.d\u002Fopenvpn.myvpn"," 再 ",[69,455,456],{"code":456},"rc-service openvpn.myvpn start","——但兼容性视 Alpine 版本而异，建议 Alpine 场景保持单配置即可。",[10,459,461,468,474,480],{"title":460,"type":13},"`\u002Fdev\u002Fnet\u002Ftun` 缺失时才需要 mknod",[16,462,463,464,467],{},"现代 Linux 内核 + udev 下 ",[69,465,466],{"code":466},"\u002Fdev\u002Fnet\u002Ftun"," 会自动创建。",[16,469,470,473],{},[47,471,472],{},"只有在容器（Docker \u002F LXC）或精简的嵌入式系统里","才需要手动创建：",[62,475,478],{"className":476,"code":477,"language":232,"meta":71},[230],"sudo mkdir -p \u002Fdev\u002Fnet\nsudo mknod \u002Fdev\u002Fnet\u002Ftun c 10 200\nsudo chmod 600 \u002Fdev\u002Fnet\u002Ftun\n",[69,479,477],{"__ignoreMap":71},[16,481,482,483,486],{},"同时容器要加 ",[69,484,485],{"code":485},"--cap-add=NET_ADMIN --device \u002Fdev\u002Fnet\u002Ftun"," 才能跑 OpenVPN。",[20,488,490],{"id":489},"_8-连接验证","8. 连接验证",[16,492,493],{},"不管用服务化跑还是前台跑，连上后都要验证：",[62,495,498],{"className":496,"code":497,"language":232,"meta":71},[230],"# 1. VPN 接口和 IP\nip a show tun0\n# 应该能看到 inet 10.8.0.x（或你服务端配的网段）\n\n# 2. 路由\nip route\n# 若服务端 push 了 redirect-gateway，看到类似：\n# 0.0.0.0\u002F1 via 10.8.0.1 dev tun0\n\n# 3. 出口 IP 对比\ncurl -s https:\u002F\u002Fipinfo.io\u002Fip\n# 应该显示 VPN 服务端的公网 IP，不是本机原本的出口\n\n# 4. 能否访问 VPN 内网资源\nping 10.8.0.1              # ping 服务端的 VPN 内网 IP\n",[69,499,497],{"__ignoreMap":71},[16,501,502],{},"四项都正常就说明 VPN 在稳定工作。",[20,504,506],{"id":505},"_9-常见故障排查","9. 常见故障排查",[152,508,509,522],{},[155,510,511],{},[158,512,513,516,519],{},[161,514,515],{},"报错 \u002F 现象",[161,517,518],{},"可能原因",[161,520,521],{},"对策",[168,523,524,541,561,583,597,614,636,650,673],{},[158,525,526,531,534],{},[173,527,528],{},[69,529,530],{"code":530},"Connection refused",[173,532,533],{},"服务端没起 \u002F 端口不对 \u002F 协议 UDP vs TCP 不匹配",[173,535,536,537,540],{},"服务端 ",[69,538,539],{"code":539},"systemctl status openvpn-server@server","；确认防火墙 \u002F 安全组放行 1194 UDP",[158,542,543,548,551],{},[173,544,545],{},[69,546,547],{"code":547},"TLS handshake failed",[173,549,550],{},"客户端时间差太大 \u002F 防火墙拦截 \u002F MTU 问题",[173,552,553,554,557,558],{},"客户端 ",[69,555,556],{"code":556},"timedatectl"," 校时；换 TCP 测试；配置里加 ",[69,559,560],{"code":560},"tun-mtu 1400",[158,562,563,568,575],{},[173,564,565],{},[69,566,567],{"code":567},"AUTH_FAILED",[173,569,570,571,574],{},"用户名密码不对 \u002F ",[69,572,573],{"code":573},"auth.txt"," 格式错",[173,576,577,578,580,581],{},"确认 ",[69,579,573],{"code":573}," 第 1 行用户名、第 2 行密码，无多余空行；",[69,582,294],{"code":294},[158,584,585,588,591],{},[173,586,587],{},"连上后无法上网",[173,589,590],{},"服务端 IP forward 没开 \u002F NAT 规则缺失",[173,592,593,596],{},[69,594,595],{"code":595},"sudo sysctl net.ipv4.ip_forward"," 应为 1；检查 POSTROUTING MASQUERADE 规则",[158,598,599,602,608],{},[173,600,601],{},"连上后仅内网通、公网不通",[173,603,604,605],{},"服务端没 push ",[69,606,607],{"code":607},"redirect-gateway",[173,609,610,611],{},"server.conf 加 ",[69,612,613],{"code":613},"push \"redirect-gateway def1 bypass-dhcp\"",[158,615,616,619,622],{},[173,617,618],{},"DNS 不生效（能 ping IP 不能 ping 域名）",[173,620,621],{},"客户端没应用 push 的 DNS",[173,623,624,625,628,629,632,633],{},"systemd-resolved 系统需 ",[69,626,627],{"code":627},"update-resolv-conf"," 脚本；或客户端配 ",[69,630,631],{"code":631},"script-security 2"," + ",[69,634,635],{"code":635},"up \u002Fetc\u002Fopenvpn\u002Fupdate-resolv-conf",[158,637,638,641,644],{},[173,639,640],{},"前台能跑、服务跑不起来",[173,642,643],{},"自己写的 .service 文件有问题",[173,645,646,647],{},"改用官方模板单元 ",[69,648,649],{"code":649},"openvpn-client@myvpn",[158,651,652,658,663],{},[173,653,654,655],{},"容器里起不来 ",[69,656,657],{"code":657},"ERROR: Cannot open TUN\u002FTAP dev \u002Fdev\u002Fnet\u002Ftun",[173,659,660,662],{},[69,661,466],{"code":466}," 不存在或没权限",[173,664,665,666,668,669,672],{},"容器加 ",[69,667,485],{"code":485},"；必要时 ",[69,670,671],{"code":671},"mknod"," 手建",[158,674,675,682,685],{},[173,676,677,678,681],{},"Alpine 上执行 ",[69,679,680],{"code":680},"systemctl"," 报 command not found",[173,683,684],{},"Alpine 用 OpenRC 不用 systemd",[173,686,687,688,691],{},"用 ",[69,689,690],{"code":690},"rc-service openvpn"," 系列命令",[16,693,694,695,698,699,702,703,706],{},"实在排查不出来的时候，加大日志 verbosity：配置文件 ",[69,696,697],{"code":697},"verb 3"," 改成 ",[69,700,701],{"code":701},"verb 5"," 甚至 ",[69,704,705],{"code":705},"verb 9","，重启服务后看详细日志通常能定位到问题。",[10,708,710],{"title":709,"type":13},"作者注",[16,711,712],{},"本教程在 Ubuntu 22.04 \u002F 24.04 和 Debian 12 上以 OpenVPN 2.6.x 验证过主干流程。RHEL 系 \u002F Alpine \u002F Arch 的命令以各自官方包文档为准，主流程和 PKI 部分完全通用。",{"title":71,"searchDepth":714,"depth":714,"links":715},4,[716,718,719,724,725,726,733,734,738,739],{"id":22,"depth":717,"text":23},2,{"id":60,"depth":717,"text":60},{"id":74,"depth":717,"text":75,"children":720},[721,723],{"id":79,"depth":722,"text":79},3,{"id":107,"depth":722,"text":107},{"id":122,"depth":717,"text":123},{"id":126,"depth":717,"text":127},{"id":213,"depth":717,"text":214,"children":727},[728,730,732],{"id":217,"depth":722,"text":729},"5.1 方式 A：直接用服务端给的 .ovpn 文件（推荐）",{"id":237,"depth":722,"text":731},"5.2 方式 B：手写最小 client.conf 模板",{"id":264,"depth":722,"text":265},{"id":312,"depth":717,"text":313},{"id":354,"depth":717,"text":355,"children":735},[736,737],{"id":358,"depth":722,"text":359},{"id":429,"depth":722,"text":430},{"id":489,"depth":717,"text":490},{"id":505,"depth":717,"text":506},[741],"网络","2026-01-18","从零在 Linux 上搭 OpenVPN 服务端（一键脚本与手动 easy-rsa 两种方式）并让客户端接入。覆盖 Debian \u002F Ubuntu \u002F RHEL 系 \u002F Alpine \u002F Arch 五大发行版的安装与服务管理、.ovpn 和 client.conf 配置、systemd 与 OpenRC 启动、IP 转发与 NAT 规则、连接故障排查。",false,"md",null,{"slots":748},{},true,"\u002Fposts\u002Flinux-openvpn-installation-guide",{"text":752,"minutes":753,"time":754,"words":755},"10 min read",9.415,564900,1883,{"title":5,"description":743},{"loc":750},"posts\u002Fposts\u002Flinux-openvpn-installation-guide",[760,761,762,741,763,764,765,766,767,768,769],"OpenVPN","Linux","VPN","PKI","easy-rsa","systemd","OpenRC","iptables","NAT","运维","tech","QkVAFXOr9OAc0Q0SxNBp5AM3QCrRUhbcdLVAFJ9AFyk",[773,777],{"title":774,"path":775,"stem":776,"date":742,"type":770,"children":-1},"使用EdgeOne CDN加速你的任意网站","\u002Fposts\u002Feo-cdn-use","posts\u002Fposts\u002Feo-cdn-use",{"title":778,"path":779,"stem":780,"date":781,"type":770,"children":-1},"MinIO 对象存储部署与安全策略指南","\u002Fposts\u002Fminio-install","posts\u002Fposts\u002Fminio-install","2026-01-20",1788712225270]