ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GoLand远程开发实战:SSH与frp构建固定公网地址的稳定通道

GoLand远程开发实战:SSH与frp构建固定公网地址的稳定通道 作为一个常年跟 Go 项目打交道的人我太熟悉这种场景了代码和运行环境都放在一台服务器上但出门在外想改个 bug手头只有一台笔记本。把代码拉到本地改环境变量、系统依赖、CGO 相关的库版本全都对不上跑起来各种崩。后来我把 GoLand有人习惯写成 Goland的远程开发方式彻底摸了一遍配合 SSH 和固定公网地址把“本地服务器”变成一个随时能连的远程开发环境这个痛点才算真正解决。这套方案的核心其实就是三样东西GoLand、SSH、固定公网地址。GoLand 负责写代码和调试SSH 负责加密传输和远程执行命令固定公网地址负责让你不管在哪都能稳定找到那台服务器。写这篇文章的主要对象是用过 Linux、会一点命令行的 Go 开发者或者是想给自己家里/办公室服务器开远程开发入口的运维。我会从安装配置讲到公网打通再把 GoLand 远端连接的具体步骤和排查思路都过一遍全部基于我实际配置过的流程不是照搬官方文档那种干巴巴的说明。1. 先把整条链路拆开看GoLand、SSH 和固定公网地址各管什么事很多人在配置远程开发的时候容易蒙是因为没想清楚这条链路上每个组件到底承担什么角色。我先分别拆开讲后面实操就顺了。1.1 GoLand 远程开发到底解决什么问题GoLand 是 JetBrains 家的 Go 专用 IDE补全、重构、调试、测试覆盖率这些功能都做得很全。但它的能力不止于“本地写代码”还支持两种典型的远程开发形态一种是经典的“编辑器本地跑编译和运行在远程”通过 SSH 解释器 Deployment 文件同步实现另一种是 JetBrains 新推的 Remote Development 模式实际 IDE 后端装在服务器上本地只跑一个瘦客户端Gateway操作起来和本地 IDE 几乎一样。选择这两种模式的关键看你的网络质量和服务器资源。经典方式对带宽要求低因为同步过去的是源码但调试体验会受到一定影响Remote Development 模式下补全、索引都在远端对服务器内存和 CPU 要求更高如果服务器配置只有 1 核 2G还是老老实实走经典方式。我自己的主力机器是 4 核 8G用 Remote Development 很舒服但在老服务器上出现过索引卡死后来就切回 Deployment 方式了。所以第一步不是急着装而是想清楚你的远程开发要什么纯改代码跑起来验证Deployment 够用重度调试、依赖大、想完全复用服务器环境Remote Development 更合适。1.2 SSH 不只是命令行入口还是远程开发通道SSH 在这条链路里承担的不只是“登录服务器敲命令”它还加密了所有通信包括文件传输、端口转发、IDE 后端的通信。换句话说你在 GoLand 里点一下运行背后走的都是 SSH 通道里的数据流。很多人对 SSH 的理解停在“密码登录”实际生产环境里更推荐密钥登录。原理很简单你本地生成一对公私钥把公钥放到服务器的~/.ssh/authorized_keys里登录时服务器用公钥验证你持有的私钥匹配就放行。这种方式比 22 个字符的强密码更抗暴力破解因为私钥从来不走网络传输。尤其当你把端口暴露到公网后密码登录几乎是每天被扫描的靶子密钥登录是底线安全要求。另外 SSH 本身还有一种“端口转发”能力可以把远程服务器上的某个端口映射到你本地也可以把你本地服务器的某个端口反带到远程跳板机。后面要讲的固定公网地址方案里SSH 反向隧道就是靠这个能力实现的这也是我不建议一上来就上复杂商业软件的原因。1.3 固定公网地址的三种常见实现方式“固定公网地址”听着玄乎其实本质就一句话给那台没有公网 IP 的本地服务器找一个稳定不变化的公网入口。宽带运营商的公网 IP 经常变所以我们才需要“固定”这个词。我实际用过三种方式。第一种是给云服务器装 frp 这类内网穿透工具本地服务器主动连出去把本地 SSH 端口映射到云服务器的某个公网端口。这种方式最通用云服务器的公网 IP 是固定的GoLand 直接连云服务器IP:映射端口就行。第二种是 SSH 反向隧道不需要额外装客户端但保活要靠 autossh。第三种是动态 DNS前提是你的宽带能要到公网 IP然后用 DDNS 把变化的 IP 绑定到一个固定域名NAT 里再做端口映射。缺点是需要路由器支持而且不少宽带没有真正公网 IPv4。一句话总结不折腾且稳的方案是 frp临时应急用 SSH 反向隧道能接受家里光猫桥接DDNS 的第三种也行。我文章后面主要按 frp 方案讲因为它在 Windows/Linux/macOS 上表现都很稳定配合 systemd 还能开机自启。2. 前置准备安装 GoLand 与配置服务器 SSH链路想明白了就可以动手装环境。这一部分我把 GoLand 安装、Linux 服务器 SSH 开启、密钥登录配置都讲清楚。2.1 GoLand 官方安装包的下载与解压步骤这里先提醒一句GoLand 没有社区版官方有 30 天评估期之后需要 license。千万别去网上随便下“破解版”既是版权风险也可能被塞木马。我见过有人在服务器上装破解版 GoLand结果 SSH 密钥被盗的事。老老实实用官方安装包或者公司买了授权就用授权省心得多。下载时可以根据操作系统选择安装包Windows下载.exe安装包双击一路 Next 就行。要注意勾选“添加到 PATH”和.go文件关联。macOS下载.dmg打开后把 GoLand 图标拖进 Applications。Linux下载.tar.gz我一般这样装sudo tar -xzf goland-*.tar.gz -C /opt/ sudo ln -s /opt/GoLand-*/bin/goland.sh /usr/local/bin/goland如果你已经装了 JetBrains Toolbox那更简单Toolbox 里直接安装并管理版本还能随时切换开发版的 GoLand。装完后第一次启动会进入初始化配置界面主题、快捷键方案、插件都可以按喜好选。日常做 Go 开发至少把 Go 插件其实内置了、.gitignore、Markdown 这类装上就行。别忘了在Settings - Go里配置 GOROOT如果本机还没装 Go SDK可以点下载按钮直接装。2.2 服务器端 SSH 服务配置与防火墙放行本地服务器我默认是 LinuxUbuntu、Debian、CentOS 都适用命令略有差别而已。第一步检查有没有装 OpenSSH Serversudo apt update sudo apt install -y openssh-server # Debian/Ubuntu # 或者 CentOS/RHEL sudo yum install -y openssh-server然后看服务状态sudo systemctl enable --now sshd # 使用 ssh 服务名也可以 sudo systemctl status sshd能听到active (running)说明服务正常。接下来要确认 SSH 端口真的在监听用这个命令sudo ss -tlnp | grep ssh看到类似0.0.0.0:22的结果就正常。如果监听地址只有127.0.0.1:22说明 SSH 只对本地回环开放外部根本连不进来需要去/etc/ssh/sshd_config检查ListenAddress配置。防火墙也要放行 22 端口不然服务再正常也白搭。Ubuntu 上常用 ufwsudo ufw allow 22/tcp sudo ufw enable sudo ufw statusCentOS 7 用 firewalld 的话改成sudo firewall-cmd --permanent --add-servicessh sudo firewall-cmd --reload这里有一个最容易踩的坑如果你已经通过 SSH 连接着机器先放行再 enable 防火墙不然把自己关在外面。我第一次配腾讯云服务器时就是先重启的网络再开防火墙结果 IP 直接被拉进黑洞只能去云控制台用 VNC 救回来。2.3 用密钥登录替代密码登录为了后续公网安全千万别拿密码裸奔。操作分三步本地生成密钥、上传公钥、调整文件权限。本地就是你装 GoLand 的电脑执行ssh-keygen -t ed25519 -C my-remote-dev -f ~/.ssh/id_ed25519一路回车不设密码保护也可以但为了安全我建议设一个 passphrase这样即使私钥文件泄露别人也还要破译口令。生成后把公钥传到服务器ssh-copy-id -i ~/.ssh/id_ed25519.pub dev192.168.1.100如果你的系统没有ssh-copy-id就手动追加mkdir -p ~/.ssh echo ssh-ed25519 AAAA... my-remote-dev ~/.ssh/authorized_keys chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys权限这一步特别重要。authorized_keys 如果权限太宽松SSH 服务会直接忽略这个文件导致你一直认证失败。服务器上最好再建一个专用用户不要用 root 登录。比如sudo useradd -m -s /bin/bash dev sudo usermod -aG sudo dev然后回到本地验证ssh -i ~/.ssh/id_ed25519 dev192.168.1.100能免密进去就算成功。最后再改服务器配置/etc/ssh/sshd_configPasswordAuthentication no PermitRootLogin no改完重启 sshd。这样密码登录就被禁掉了只剩密钥可以进暴力破解基本对你无效。3. 核心实操固定公网地址的打通与 GoLand 连接前置准备好了现在进入重头戏怎么让外网的 GoLand 能连上内网服务器。我以一台有固定公网 IP 的云服务器作为跳板来演示。假设公网 IP 是203.0.113.10本地服务器 IP 是192.168.1.100最终目标是让 GoLand 用dev203.0.113.10:2222连到本地服务器。3.1 方案一frp 端口映射把本地 22 端口送上公网frp 是目前最成熟的内网映射工具之一分成服务端 frps 和客户端 frpc 两部分。服务端装在有公网 IP 的云服务器上客户端装在你需要被访问的本地服务器上。原理特别朴素客户端主动连上服务端告诉它“帮我监听公网 2222 端口收到的数据转给我本机的 22 端口”。先下载 frp。到 GitHub releases 页面找对应架构的压缩包云服务器和本地服务器通常都是 amd64。解压后有两个核心二进制frps、frpc按需使用。云服务器上建个服务端配置/etc/frp/frps.ini[common] bindPort 7000 auth.token 这里填一串足够随机的Token dashboardPort 7500 dashboardUser admin dashboardPwd 换一个复杂的密码bindPort 是 frps 自己监听的控制端口客户端通过它建立连接。token 是客户端和服务端之间的认证信息一定别用默认。dashboard 可选用来在浏览器里看连接状态。启动服务端./frps -c /etc/frp/frps.ini生产环境建议写成 systemd 服务。系统服务文件/etc/systemd/system/frps.service内容大致如下[Unit] Descriptionfrp server Afternetwork.target [Service] ExecStart/usr/local/frp/frps -c /etc/frp/frps.ini Restartalways RestartSec5 [Install] WantedBymulti-user.target然后sudo systemctl enable --now frps本地服务器上写客户端配置/etc/frp/frpc.ini[common] serverAddr 203.0.113.10 serverPort 7000 auth.token 与服务端一致的Token [ssh_local] type tcp localIP 127.0.0.1 localPort 22 remotePort 2222remotePort 就是映射到公网的端口建议选一个不常见的端口别用 22 和 2222 太规律的我习惯用 6xxxx 这种高位端口。启动 frpc 并设置开机自启方式和 frps 类似。完成后在云服务器上测试一下ss -tlnp | grep 2222能看到0.0.0.0:2222就说明映射生效了。再用本地电脑连一次ssh -p 2222 dev203.0.113.10如果通了说明从公网入口到本地服务器的链路已经打通。3.2 方案二SSH 反向隧道 autossh 保活不想装 frp 的可以用纯 SSH 反向隧道临时顶一顶。在本地服务器执行一条命令ssh -fN -R 2222:127.0.0.1:22 relay_user203.0.113.10这行的意思是让云服务器监听 2222 端口把收到的连接通过这条已经建立的 SSH 隧道反向转回本地服务器的 22 端口。但有个坑云服务器默认的 sshd 配置只允许隧道监听在 127.0.0.1外部连不上。需要改云服务器的/etc/ssh/sshd_configGatewayPorts clientspecified然后重启 sshd。这样隧道才能绑定到公网网卡上外部访问203.0.113.10:2222才会真正进来。但 SSH 隧道断掉就完了所以要用 autossh 保活sudo apt install -y autossh autossh -M 0 -fN -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -R 2222:127.0.0.1:22 relay_user203.0.113.10ServerAliveInterval每 30 秒发一个探测包ServerAliveCountMax连续 3 次没回应就重连。这里的 relay_user 是云服务器上的一个普通用户给密钥认证是必要的。优点是零额外组件缺点是没有 frp 那样的可视化监控网络稍微差一点就容易重连体验不够稳。所以我后来还是切回了 frp。3.3 GoLand 里连接远程服务器并创建远程开发环境链路通了之后GoLand 这边有两种接法。先说新派的 Remote Development。打开 JetBrains Gateway可以从 Toolbox 安装也可以从 GoLand 首页选择 Remote Development 跳转选择 SSH填写Host203.0.113.10Port2222UsernamedevAuth选择密钥文件~/.ssh/id_ed25519远程项目目录/home/dev/project点 ConnectGateway 会先通过 SSH 连接然后在服务器上部署 JetBrains 的后端组件。这一步需要服务器的网络能正常访问 JetBrains 下载地址如果下载很慢或失败可以检查网络策略或者把后端包手动拷到服务器上再指定路径。第一次部署耗时比较长后面再连接就快多了。连接成功后GoLand 会在服务端启动完整的 IDE 后端本地界面依然是熟悉的 GoLand。你需要确认远程 GOROOT 是否正确Settings - Go - GOROOT选择远程服务器上的 Go SDK。如果服务器还没装 Go可以用sudo apt install -y golang-go # 或者官方 tar 包解压到 /usr/local/go再就是 Run 配置。GoLand 支持通过 SSH 运行和调试它会自动把项目同步到远端目录然后在远端执行go build、go run、go test。断点调试需要远程机器上有 delve通常 GoLand 会自动处理失败的话手动装go install github.com/go-delve/delve/cmd/dlvlatest再说经典方式。GoLand 菜单Tools - Deployment - Configuration添加一个 SFTP 类型填 Host、Port 2022对应公网映射端口、用户名、私钥Root Path 填/home/dev/project。然后在Settings - Go - GOROOT里添加远程 SDK同样通过 SSH 选择服务器上的/usr/local/go。Run/Debug 配置里把 Deployment 选成自动上传运行前它会先把改动文件同步上去再远程执行。两种方式我都在用Remote Development 胜在“本地零代码、一切都在远端”经典方式胜在对弱网更友好、文件完全在自己手里。你也可以都试试再决定长期用哪个。3.4 链路自检从内网到公网逐段验证很多新手配置失败不知道到底哪一段出问题。我的习惯是严格按从近到远排查千万别一上来就怪 GoLand。第一段本地服务器自己连自己ssh dev127.0.0.1能通说明 sshd 正常。第二段从局域网电脑连ssh dev192.168.1.100能通说明内网防火墙和 SSH 服务正常。第三段从云服务器连本地映射端口ssh -p 2222 dev127.0.0.1如果在云服务器本机执行这个能通说明 frp 隧道已经建立了。第四段从外部电脑比如你笔记本连固定公网地址ssh -p 2222 dev203.0.113.10能通说明公网入口正常。哪一段失败就处理哪一段这比盲改配置高效太多了。我在排查时还会借助telnet或nc看端口通不通nc -vz 203.0.113.10 2222如果端口通但 SSH 登录不上问题大概率在认证如果端口都不通先去云控制台看安全组放行规则再检查 frps 状态。4. 常见问题与排查技巧实录再顺利的部署也会遇到各种问题。我把实际踩过的高频坑整理成速查方便你对照处理。4.1 SSH 连接失败的典型原因速查表现象可能原因排查/处理连接超时云服务器安全组未放行端口去云控制台安全组添加 TCP 2222 入站规则连接被拒绝sshd 未启动或 frp 隧道没起来systemctl status sshd、systemctl status frpc端口映射没生效frpc 配置里 remotePort 被占用ss -tlnp认证失败authorized_keys 权限不对、密钥不匹配chmod 600 authorized_keys确认公钥内容密码错误服务器开启了密码认证且密码输错临时用PasswordAuthentication yes登录后检查密钥无法通过公网 IP 访问GatewayPorts 没配置sshd_config 设置GatewayPorts clientspecified有一次我配完全没问题但本地怎么都连不上最后发现云服务商控制台的安全组规则没有放行高位端口 2222。云服务器上的 firewalld 和 iptables 都开着但安全组是云平台第一道关卡这个别忘了。一般的做法是云控制台入站规则放行你选择的高位端口同时源地址做限制比如只允许你的固定办公 IP能大幅降低被扫描风险。4.2 GoLand 远程开发的高频坑与处理办法先说 Remote Development 最开始遇到的“远程后端一直下载失败”。原因是后端组件要从 JetBrains 服务器下载而远端网络没有放行或速度很慢。处理办法先在服务器上用浏览器或 curl 访问下载地址能通再继续如果访问受限可以手动下载后端包传到服务器然后在 Gateway 里指定安装目录。注意不同 JetBrains 产品的后端包不一样别下混了。第二个坑是“索引慢”。远程开发里代码索引在服务器端跑如果项目里有巨大的 node_modules、vendor 目录或者塞了一堆二进制索引会非常慢。解决办法是在项目的.gitignore里临时加排除或者在 GoLand 的 Project Structure 里把不需要的目录标记为 Excluded。还有就是在 Settings - Build, Execution, Deployment - Remote Development 里调整索引范围别一次全扫。第三个坑是断点不生效。Go 的调试器是 delve远程模式下 GoLand 需要能在服务器上启动 dlv。报错时先检查服务器上有没有 dlvwhich dlv如果没有执行go install github.com/go-delve/delve/cmd/dlvlatest。还要确认 Run Configuration 选的不是run而是debug并且 GOROOT 和 GOPATH 在远端都已配置正确。如果代码同步不完整断点可能会落到“找不到源文件”的境地这时强制重新上传所有文件再试。第四个坑是文件不同步。经典方式下Deployment 的“自动上传”有时不会把删除的文件同步掉导致服务器上残留旧文件编译时出现奇怪结果。最好定期手动执行Tools - Deployment - Sync with Deployed To...或者把 Run 配置里的Upload changed files改成Before run时执行。强迫症的话甚至可以在部署配置里开启“删除远端多余文件”但风险是你手动在服务器上建的文件会被删用之前一定三思。4.3 远程端口暴露后的安全加固清单公网映射最忌讳的就是裸奔。如果你内部测试都完成了服务器端口已经暴露在公网上下面这些措施务必做掉。第一SSH 密码登录已经关掉了这里再确认一次。/etc/ssh/sshd_config里PasswordAuthentication no必须为 no禁用 root 登录。密钥文件权限保持600.ssh目录700。很多人把私钥拷到多台机器上私钥一旦泄露所有机器都得换所以注意保管。第二映射端口别用常见端口。frp 的 remotePort 尽量选 10000 以上的随机端口配合云安全组的来源 IP 白名单可以把攻击面压到很小。比如你家宽带的出口 IP 相对固定就在安全组里只放行那个 IP 访问 2222 端口。第三给云服务器装 fail2ban防止暴力破解 sshd 本身。虽然你已经禁了密码登录但日志里会看到无数扫描尝试fail2ban 能自动把可疑 IP 拉黑。第四本地服务器的 SSH 端口也别裸着。如果本地服务器本身防火墙开放了 22面对内网可以放行但没必要对全体内网开放frp 映射走的是 127.0.0.1 的 localIP所以本地 sshd 只需监听回环或受限网段都能减少风险。第五定期检查认证日志sudo tail -n 100 /var/log/auth.log无论 frp 还是反向隧道只要端口吊在公网上日志就是你的第一道眼睛。发现不认识的 IP 反复尝试登录立即加强限制。配置这套远程开发环境我个人的习惯是先把内网全链路验证好再开公网映射公网映射开通后先用命令行 SSH 测几次确认稳定后再交给 GoLandGoLand 连不上时不要反复重试界面而是回到终端用ssh -vvv看详细日志九成的“GoLand 问题”其实是 SSH 配置或网络问题。这套顺序帮我省下了大量折腾时间你照着试试应该也能少走不少弯路。
返回列表