[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"content:\u002Fposts\u002Fpowershell-ssh-config-guide":3,"surround:\u002Fposts\u002Fpowershell-ssh-config-guide":792},{"id":4,"title":5,"body":6,"categories":762,"date":764,"description":765,"draft":766,"extension":767,"image":768,"meta":769,"navigation":771,"path":772,"permalink":768,"pinned":766,"published":768,"readingTime":773,"recommend":768,"references":768,"seo":778,"sitemap":779,"stem":780,"tags":781,"type":790,"updated":764,"__hash__":791},"content\u002Fposts\u002Fposts\u002Fpowershell-ssh-config-guide.md","PowerShell SSH 效率手册：免密、别名与端口转发",{"type":7,"value":8,"toc":740},"minimark",[9,19,22,27,30,41,48,76,80,87,92,98,105,109,116,122,129,133,136,144,198,202,205,279,283,298,304,311,314,332,336,343,349,356,377,381,384,390,401,405,412,416,422,427,458,476,480,489,493,522,526,593,599,603,722,725,731,734],[10,11,15],"alert",{"title":12,"type":13,"icon":14},"AI 迁移提示","info","tabler:robot",[16,17,18],"p",{},"本文由 AI 协助从旧站迁移，尚未完成逐篇人工审校；内容如有疏漏，将在复核后修订。",[16,20,21],{},"Windows 10+ 自带的 OpenSSH 客户端已经很完善，配合 PowerShell Profile 和 SSH Config，运维里最常用的连服务器、免密、端口转发都能用一套干净的方式管理。本文记录我自己用得最顺手的一套配置。",[23,24,26],"h2",{"id":25},"_1-本地生成密钥只需执行一次","1. 本地生成密钥（只需执行一次）",[16,28,29],{},"在本地 PowerShell 运行：",[31,32,38],"pre",{"className":33,"code":35,"language":36,"meta":37},[34],"language-powershell","# 确保 .ssh 目录存在（全新账户第一次使用 SSH 时必要）\nif (!(Test-Path $HOME\\.ssh)) { New-Item -ItemType Directory $HOME\\.ssh | Out-Null }\n\n# 生成 ed25519 密钥，-N '' 表示不设密码\nssh-keygen -t ed25519 -N '' -f \"$HOME\\.ssh\\id_ed25519\"\n\n# 查看公钥内容\nGet-Content $HOME\\.ssh\\id_ed25519.pub\n","powershell","",[39,40,35],"code",{"__ignoreMap":37},[10,42,45],{"title":43,"type":44},"为什么选 ed25519","tip",[16,46,47],{},"ed25519 是目前推荐的密钥算法：公钥一行搞定、生成速度快、安全性更高。RSA 只在需要兼容十多年前的老系统时才需要考虑。",[10,49,51,70],{"title":50,"type":44},"要不要给密钥加 passphrase？",[16,52,53,54,57,58,62,63,65,66,69],{},"上面用 ",[39,55,56],{"code":56},"-N ''"," 生成的是",[59,60,61],"strong",{},"无密码私钥","，方便但一旦文件泄露就直接失守。对安全要求更高可以去掉 ",[39,64,56],{"code":56},"、交互式输入一个 passphrase。然后用 ",[39,67,68],{"code":68},"ssh-agent"," 托管密钥，每次登录不用反复输 passphrase：",[31,71,74],{"className":72,"code":73,"language":36,"meta":37},[34],"# 启用 ssh-agent 服务并设为开机自启（PowerShell 以管理员身份运行一次）\nStart-Service ssh-agent\nSet-Service ssh-agent -StartupType Automatic\n\n# 把密钥加入 agent（只需执行一次，之后重启电脑也会自动加载）\nssh-add $HOME\\.ssh\\id_ed25519\n",[39,75,73],{"__ignoreMap":37},[23,77,79],{"id":78},"_2-服务器端免密配置","2. 服务器端免密配置",[16,81,82,83,86],{},"把公钥送上服务器有三种方式，",[59,84,85],{},"推荐方式 A","（一行命令，不依赖额外工具）。",[88,89,91],"h3",{"id":90},"_21-方式-apipe-到-ssh-自动写入推荐","2.1 方式 A：pipe 到 ssh 自动写入（推荐）",[31,93,96],{"className":94,"code":95,"language":36,"meta":37},[34],"Get-Content $HOME\\.ssh\\id_ed25519.pub | ssh user@1.2.3.4 \"mkdir -p ~\u002F.ssh && chmod 700 ~\u002F.ssh && cat >> ~\u002F.ssh\u002Fauthorized_keys && chmod 600 ~\u002F.ssh\u002Fauthorized_keys\"\n",[39,97,95],{"__ignoreMap":37},[16,99,100,101,104],{},"命令会：读取本地公钥 → SSH 送到服务器 → 自动追加到 ",[39,102,103],{"code":103},"authorized_keys"," → 顺手把目录和文件权限都设对。执行时输一次密码，完成后下次起就免密。",[88,106,108],{"id":107},"_22-方式-bssh-copy-idopenssh-新版本自带","2.2 方式 B：ssh-copy-id（OpenSSH 新版本自带）",[16,110,111,112,115],{},"较新的 OpenSSH 客户端内置了 ",[39,113,114],{"code":114},"ssh-copy-id","，效果和方式 A 一致但命令更短：",[31,117,120],{"className":118,"code":119,"language":36,"meta":37},[34],"ssh-copy-id user@1.2.3.4\n",[39,121,119],{"__ignoreMap":37},[16,123,124,125,128],{},"Windows 自带的 OpenSSH 不一定带这个命令（看版本），如果提示 ",[39,126,127],{"code":127},"The term 'ssh-copy-id' is not recognized","，直接用方式 A。",[88,130,132],{"id":131},"_23-方式-c手动粘贴兜底","2.3 方式 C：手动粘贴（兜底）",[16,134,135],{},"登录服务器后手动执行（需要先把公钥内容复制到剪贴板）：",[31,137,142],{"className":138,"code":140,"language":141,"meta":37},[139],"language-bash","mkdir -p ~\u002F.ssh && chmod 700 ~\u002F.ssh && \\\necho \"这里粘贴公钥内容\" >> ~\u002F.ssh\u002Fauthorized_keys && \\\nchmod 600 ~\u002F.ssh\u002Fauthorized_keys\n","bash",[39,143,140],{"__ignoreMap":37},[10,145,148,155,163,178,184],{"title":146,"type":147},"免密配好后建议禁用密码登录","warning",[16,149,150,151,154],{},"公钥登录正常工作后，推荐在服务器 ",[39,152,153],{"code":153},"\u002Fetc\u002Fssh\u002Fsshd_config"," 里改成：",[31,156,161],{"className":157,"code":159,"language":160},[158],"language-text","PubkeyAuthentication yes\nPasswordAuthentication no\n","text",[39,162,159],{"__ignoreMap":37},[16,164,165,166,169,170,173,174,177],{},"然后 ",[39,167,168],{"code":168},"sudo systemctl reload ssh","（Debian\u002FUbuntu 是 ",[39,171,172],{"code":172},"ssh","，CentOS\u002FRHEL 是 ",[39,175,176],{"code":176},"sshd","）。这样服务器只接受密钥登录，彻底消除密码被爆破的风险。",[16,179,180,183],{},[59,181,182],{},"两条关键保险","：",[185,186,187,191],"ol",{},[188,189,190],"li",{},"修改前务必先用密钥登录一次，确认公钥配置无误。",[188,192,193,194,197],{},"修改和 reload 期间",[59,195,196],{},"保留一个已登录的 SSH 窗口别关","——万一配置语法错、reload 失败或被防火墙误杀，可以从这个窗口里回滚，而不是被锁在门外。",[23,199,201],{"id":200},"_3-ssh-端口转发的三种模式","3. SSH 端口转发的三种模式",[16,203,204],{},"SSH 内置 3 种端口转发模式，分别应对不同场景：",[206,207,208,227],"table",{},[209,210,211],"thead",{},[212,213,214,218,221,224],"tr",{},[215,216,217],"th",{},"模式",[215,219,220],{},"参数",[215,222,223],{},"方向",[215,225,226],{},"典型场景",[228,229,230,247,263],"tbody",{},[212,231,232,236,241,244],{},[233,234,235],"td",{},"本地转发",[233,237,238],{},[39,239,240],{"code":240},"-L",[233,242,243],{},"本地 → 远程",[233,245,246],{},"访问远程内网 Web \u002F DB",[212,248,249,252,257,260],{},[233,250,251],{},"远程转发",[233,253,254],{},[39,255,256],{"code":256},"-R",[233,258,259],{},"远程 → 本地",[233,261,262],{},"把本地服务暴露给远端（内网穿透）",[212,264,265,268,273,276],{},[233,266,267],{},"动态转发",[233,269,270],{},[39,271,272],{"code":272},"-D",[233,274,275],{},"SOCKS 代理",[233,277,278],{},"浏览器流量整条走 SSH",[88,280,282],{"id":281},"_31-本地转发-l最常用","3.1 本地转发（-L）——最常用",[16,284,285,286,289,290,293,294,297],{},"把",[59,287,288],{},"远端能访问的资源","映射到",[59,291,292],{},"本地端口","。比如服务器上跑着只监听 ",[39,295,296],{"code":296},"127.0.0.1:8080"," 的内部 Web 面板：",[31,299,302],{"className":300,"code":301,"language":36,"meta":37},[34],"# 格式：ssh -L [本地端口]:[远端可访问地址]:[远端端口] 用户@服务器IP\n# 示例：把服务器的 127.0.0.1:8080 映射到本地 8080\nssh -L 8080:127.0.0.1:8080 user@1.2.3.4\n",[39,303,301],{"__ignoreMap":37},[16,305,306,307,310],{},"连上后，本地浏览器访问 ",[39,308,309],{"code":309},"http:\u002F\u002Flocalhost:8080"," 就是在访问服务器上的服务。",[16,312,313],{},"常用参数：",[315,316,317,323],"ul",{},[188,318,319,322],{},[39,320,321],{"code":321},"-N","：只建隧道，不打开远程 shell",[188,324,325,328,329,331],{},[39,326,327],{"code":327},"-f","：执行命令前 fork 到后台（通常和 ",[39,330,321],{"code":321}," 一起用，让 SSH 进程进入后台运行）",[88,333,335],{"id":334},"_32-远程转发-r内网穿透","3.2 远程转发（-R）——内网穿透",[16,337,338,339,342],{},"方向相反：把",[59,340,341],{},"本地能访问的服务","暴露给远端。比如想让服务器访问你本地 3000 端口的服务：",[31,344,347],{"className":345,"code":346,"language":36,"meta":37},[34],"# 把本地 localhost:3000 映射到服务器的 8000 端口\nssh -R 8000:localhost:3000 user@1.2.3.4\n",[39,348,346],{"__ignoreMap":37},[16,350,351,352,355],{},"服务器上访问 ",[39,353,354],{"code":354},"http:\u002F\u002F127.0.0.1:8000"," 就是访问你本地的 3000，常用于给服务器演示本地 demo、接收 webhook 调试等。",[10,357,359],{"title":358,"type":147},"-R 默认只监听 127.0.0.1",[16,360,361,362,364,365,368,369,372,373,376],{},"服务器上 ",[39,363,256],{"code":256}," 暴露出来的端口默认只绑定 ",[39,366,367],{"code":367},"127.0.0.1","，外部机器访问不到。如果要让公网或局域网也能访问，需要在服务器 ",[39,370,371],{"code":371},"sshd_config"," 里开启 ",[39,374,375],{"code":375},"GatewayPorts yes","——安全敏感，谨慎使用。",[88,378,380],{"id":379},"_33-动态转发-dsocks-代理","3.3 动态转发（-D）——SOCKS 代理",[16,382,383],{},"把 SSH 当成本地 SOCKS5 代理：",[31,385,388],{"className":386,"code":387,"language":36,"meta":37},[34],"# 在本地 1080 端口起 SOCKS5 代理，所有流量走服务器\nssh -D 1080 -N user@1.2.3.4\n",[39,389,387],{"__ignoreMap":37},[16,391,392,393,396,397,400],{},"浏览器把代理设成 SOCKS5 ",[39,394,395],{"code":395},"127.0.0.1:1080"," 后，所有网页请求都会经服务器出口。相当于",[59,398,399],{},"一条 SSH 连接就能当整套代理","，临时用不需要单独装 Clash \u002F v2ray 这类工具。",[23,402,404],{"id":403},"_4-短别名与自动端口转发两种方案","4. 短别名与自动端口转发：两种方案",[16,406,407,408,411],{},"每次敲 ",[39,409,410],{"code":410},"ssh -L ... user@ip"," 又长又容易出错。下面两种方案都能做到\"一个词解决\"，按需选一种或两种搭配用。",[88,413,415],{"id":414},"_41-方案一ssh-config-文件推荐","4.1 方案一：SSH Config 文件（推荐）",[16,417,418,421],{},[59,419,420],{},"优点","：声明式配置；命令行、Git、SCP 等各种 SSH 工具都认；一次配置终身受益。",[16,423,424,183],{},[59,425,426],{},"步骤",[185,428,429,438,449],{},[188,430,431,432],{},"打开配置文件：",[31,433,436],{"className":434,"code":435,"language":36,"meta":37},[34],"notepad $HOME\\.ssh\\config\n",[39,437,435],{"__ignoreMap":37},[188,439,440,441],{},"写入内容：",[31,442,447],{"className":443,"code":445,"language":446,"meta":37},[444],"language-ssh-config","# --- 基础服务器：只做登录 ---\nHost s1\n    HostName 1.2.3.4\n    User user\n    Port 22                # 非默认端口（如 22222）就改这里\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n\n# --- 带自动端口转发的同一台服务器 ---\nHost s1-tunnel\n    HostName 1.2.3.4\n    User user\n    Port 22\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n    # LocalForward [本地端口] [目标地址]:[目标端口]\n    LocalForward 18789 127.0.0.1:18789\n    LocalForward 3306 127.0.0.1:3306\n","ssh-config",[39,448,445],{"__ignoreMap":37},[188,450,451,452],{},"使用：",[31,453,456],{"className":454,"code":455,"language":36,"meta":37},[34],"ssh s1              # 纯登录\nssh s1-tunnel       # 登录 + 自动把 18789 \u002F 3306 映射到本地\n",[39,457,455],{"__ignoreMap":37},[10,459,461],{"title":460,"type":44},"用 IdentityFile 管理多密钥",[16,462,463,464,467,468,471,472,475],{},"如果不同服务器需要不同密钥（比如公司机和 HomeLab 分开），在每个 ",[39,465,466],{"code":466},"Host"," 块下单独写 ",[39,469,470],{"code":470},"IdentityFile","，SSH 会按主机挑对应密钥，不会把所有私钥依次试一遍（那样很快就会撞到服务器端 ",[39,473,474],{"code":474},"MaxAuthTries"," 限制被拒绝）。",[88,477,479],{"id":478},"_42-方案二powershell-profile-函数","4.2 方案二：PowerShell Profile 函数",[16,481,482,484,485,488],{},[59,483,420],{},"：启动时可以打印友好提示、函数里能塞任意 PowerShell 逻辑（例如连前先 ",[39,486,487],{"code":487},"Test-NetConnection"," 探活）。",[16,490,491,183],{},[59,492,426],{},[185,494,495,504,513],{},[188,496,497,498],{},"打开 Profile：",[31,499,502],{"className":500,"code":501,"language":36,"meta":37},[34],"notepad $PROFILE\n",[39,503,501],{"__ignoreMap":37},[188,505,506,507],{},"写入函数：",[31,508,511],{"className":509,"code":510,"language":36,"meta":37},[34],"# 1. 纯连接\nfunction s1 { ssh user@1.2.3.4 }\n\n# 2. 一键开启端口转发并显示提示\nfunction s1-tunnel {\n    Write-Host \"------------------------------------------------\" -ForegroundColor Cyan\n    Write-Host \"SSH 隧道已建立！\" -ForegroundColor Green\n    Write-Host \"Web 应用: http:\u002F\u002Flocalhost:18789\" -ForegroundColor Yellow\n    Write-Host \"数据库端口: 3306 -> 3306\" -ForegroundColor Yellow\n    Write-Host \"提示: 保持此窗口开启，按 Ctrl+C 关闭隧道\" -ForegroundColor DarkGray\n    Write-Host \"------------------------------------------------\" -ForegroundColor Cyan\n    # -N 表示不执行远程命令，仅做转发\n    ssh -N -L 18789:127.0.0.1:18789 -L 3306:127.0.0.1:3306 user@1.2.3.4\n}\n",[39,512,510],{"__ignoreMap":37},[188,514,515,516],{},"让配置生效并使用：",[31,517,520],{"className":518,"code":519,"language":36,"meta":37},[34],". $PROFILE       # 立即加载本次会话\ns1-tunnel        # 直接输入函数名\n",[39,521,519],{"__ignoreMap":37},[88,523,525],{"id":524},"_43-两种方案对比","4.3 两种方案对比",[206,527,528,541],{},[209,529,530],{},[212,531,532,535,538],{},[215,533,534],{},"维度",[215,536,537],{},"Config 方式",[215,539,540],{},"Profile 方式",[228,542,543,560,571,582],{},[212,544,545,548,554],{},[233,546,547],{},"打字量",[233,549,550,553],{},[39,551,552],{"code":552},"ssh s1-tunnel","（中等）",[233,555,556,559],{},[39,557,558],{"code":558},"s1-tunnel","（最少）",[212,561,562,565,568],{},[233,563,564],{},"可维护性",[233,566,567],{},"高（标准格式、跨工具通用）",[233,569,570],{},"一般（仅 PowerShell 生效）",[212,572,573,576,579],{},[233,574,575],{},"自动化能力",[233,577,578],{},"声明式配端口，无逻辑",[233,580,581],{},"可写任意 PowerShell 脚本逻辑",[212,583,584,587,590],{},[233,585,586],{},"推荐度",[233,588,589],{},"⭐⭐⭐⭐⭐",[233,591,592],{},"⭐⭐⭐（补充）",[16,594,595,598],{},[59,596,597],{},"建议方案一为主、方案二为辅","：能用 Config 解决的就用 Config，需要彩色提示 \u002F 脚本逻辑时再走 Profile 函数。",[23,600,602],{"id":601},"_5-常见故障排查","5. 常见故障排查",[206,604,605,618],{},[209,606,607],{},[212,608,609,612,615],{},[215,610,611],{},"报错",[215,613,614],{},"原因",[215,616,617],{},"对策",[228,619,620,637,660,678,700],{},[212,621,622,627,630],{},[233,623,624],{},[39,625,626],{"code":626},"Permissions 0644 for 'id_ed25519' are too open",[233,628,629],{},"本地私钥权限过松",[233,631,632,633,636],{},"PowerShell 运行 ",[39,634,635],{"code":635},"icacls $HOME\\.ssh\\id_ed25519 \u002Finheritance:r \u002Fgrant:r \"$($env:USERNAME):F\"","，或手动在文件属性里只保留当前用户可读",[212,638,639,645,654],{},[233,640,641,642],{},"服务器侧 ",[39,643,644],{"code":644},"Permission denied (publickey)",[233,646,647,650,651,653],{},[39,648,649],{"code":649},"~\u002F.ssh"," 或 ",[39,652,103],{"code":103}," 权限不对",[233,655,656,657],{},"服务器上执行 ",[39,658,659],{"code":659},"chmod 700 ~\u002F.ssh && chmod 600 ~\u002F.ssh\u002Fauthorized_keys",[212,661,662,668,671],{},[233,663,664,665],{},"端口转发报 ",[39,666,667],{"code":667},"bind: Address already in use",[233,669,670],{},"本地端口被其他进程占用",[233,672,673,674,677],{},"PowerShell 里 ",[39,675,676],{"code":676},"Get-NetTCPConnection -LocalPort 8080"," 定位占用进程",[212,679,680,683,690],{},[233,681,682],{},"能连上但卡很久才出提示符",[233,684,685,686,689],{},"服务器开了 ",[39,687,688],{"code":688},"UseDNS"," 但反向解析失败",[233,691,692,693,695,696,699],{},"服务器 ",[39,694,371],{"code":371}," 里设 ",[39,697,698],{"code":698},"UseDNS no"," 后重启 sshd",[212,701,702,705,708],{},[233,703,704],{},"没明显报错但连不上 \u002F 认证反复失败",[233,706,707],{},"需要更详细调试信息",[233,709,710,711,714,715,714,718,721],{},"加 ",[39,712,713],{"code":713},"-v"," \u002F ",[39,716,717],{"code":717},"-vv",[39,719,720],{"code":720},"-vvv"," 打印握手日志（见下方）",[16,723,724],{},"遇到复杂问题时的万能调试命令：",[31,726,729],{"className":727,"code":728,"language":36,"meta":37},[34],"ssh -vvv s1-tunnel\n",[39,730,728],{"__ignoreMap":37},[16,732,733],{},"输出会逐步打印 SSH 协议握手的每个阶段，对密钥不匹配、配置未生效、算法协商失败等问题定位非常有用。",[10,735,737],{"title":736,"type":13},"作者注",[16,738,739],{},"本教程在 Windows 11 + OpenSSH 9.x 客户端上验证过。对端服务器可以是 Linux \u002F macOS，SSH 协议两端一致，命令互通。",{"title":37,"searchDepth":741,"depth":741,"links":742},4,[743,745,751,756,761],{"id":25,"depth":744,"text":26},2,{"id":78,"depth":744,"text":79,"children":746},[747,749,750],{"id":90,"depth":748,"text":91},3,{"id":107,"depth":748,"text":108},{"id":131,"depth":748,"text":132},{"id":200,"depth":744,"text":201,"children":752},[753,754,755],{"id":281,"depth":748,"text":282},{"id":334,"depth":748,"text":335},{"id":379,"depth":748,"text":380},{"id":403,"depth":744,"text":404,"children":757},[758,759,760],{"id":414,"depth":748,"text":415},{"id":478,"depth":748,"text":479},{"id":524,"depth":748,"text":525},{"id":601,"depth":744,"text":602},[763],"系统","2026-03-07","在 Windows PowerShell 下用 OpenSSH 实现 ed25519 免密登录、SSH Config 短别名、本地\u002F远程\u002F动态三种端口转发以及多密钥管理。",false,"md",null,{"slots":770},{},true,"\u002Fposts\u002Fpowershell-ssh-config-guide",{"text":774,"minutes":775,"time":776,"words":777},"11 min read",10.09,605400,2018,{"title":5,"description":765},{"loc":772},"posts\u002Fposts\u002Fpowershell-ssh-config-guide",[782,783,784,785,786,787,788,789],"SSH","OpenSSH","PowerShell","Windows","端口转发","免密登录","ed25519","Linux","tech","iXTxCBcBRx9ySJmRs3-Kj52k07K2tzKg7xpW0WAHh8o",[793,797],{"title":794,"path":795,"stem":796,"date":764,"type":790,"children":-1},"OpenClaw (小龙虾) 部署指南：打造企业级 AI 自动化助手","\u002Fposts\u002Fopenclaw-installation-and-setup","posts\u002Fposts\u002Fopenclaw-installation-and-setup",{"title":5,"path":798,"stem":799,"date":764,"type":790,"children":-1},"\u002Fposts\u002Fpowershell-ssh-config","posts\u002Fposts\u002Fpowershell-ssh-config",1788712223479]