最近想要配置自家的电脑用作服务器,方便自己远程访问。
由于没有静态IP,最开始想使用DDNS,从花生壳注册了一个域名,然后在路由配置端口转发,配置完成后,发现家里网络是光猫拨号的,路由器自动获取ip,转发的依然是内网ip,局域网可以访问,但是外网仍然访问不了,后面改成路由器拨号,依然没有公网ip。后面就想着通过一个公网上的服务器做跳板,网上找了一圈,决定使用ssh技术进行转发连接,本路记录ssh实现过程中的一些问题。
window下有自动OpenSSH工具可以实现ssh连接管理。
安装方法参考:安装 OpenSSH | Microsoft Learn
OpenSSH 是安全 Shell (SSH) 工具的开放源代码版本,Linux 及其他非 Windows 系统的管理员使用此类工具跨平台管理远程系统。 OpenSSH 在 2018 年秋季已添加至 Windows,并包含在 Windows 10 和 Windows Server 2019 中。
SSH 基于客户端-服务器体系结构,用户在其中工作的系统是客户端,所管理的远程系统是服务器。 OpenSSH 包含一系列组件和工具,用于提供一种安全且简单的远程系统管理方法,其中包括:
sshd.exe,它是远程所管理的系统上必须运行的 SSH 服务器组件
ssh.exe,它是在用户的本地系统上运行的 SSH 客户端组件
ssh-keygen.exe,为 SSH 生成、管理和转换身份验证密钥
ssh-agent.exe,存储用于公钥身份验证的私钥
ssh-add.exe,将私钥添加到服务器允许的列表中
ssh-keyscan.exe,帮助从许多主机收集公用 SSH 主机密钥
sftp.exe,这是提供安全文件传输协议的服务,通过 SSH 运行
scp.exe 是在 SSH 上运行的文件复制实用工具
本部分中的文档重点介绍了如何在 Windows 上使用 OpenSSH,包括安装以及特定于 Windows 的配置和用例。
有关常见 OpenSSH 功能的其他详细文档,请参阅 OpenSSH.com。
使用ssh访问前需要确认远程主机上安装了OpenSSH服务器,本地主基上安装了OpenSSH客户端。
基本信息:
本地主机的IP(局域网内的):Local_IP
服务器的IP(公网IP):Server_IP
服务器可登录的用户名:UserName
服务器用户的密码:123456
ssh密钥对(后续创建)
通过win+r调出运行界面,然后输入services.msc打开服务管理器。
找到OpenSSH SSH Server服务启动,一般建议设置为自动启动
以管理员运行PowerShell或者命令行,然后运行如下命令:
# 启动服务
Start-Service sshd
# 设置为自启动:
Set-Service -Name sshd -StartupType 'Automatic'
注:sshd是OpenSSH的服务名
直接在powershell中用ssh访问
ssh username@server_IP
# 连接成功后会收到如下提示
The authenticity of host 'servername (10.00.00.001)' can't be established.
ECDSA key fingerprint is SHA256:().
Are you sure you want to continue connecting (yes/no)?
#输入 yes
#然后输入密码,注意输入密码时不会显示密码。
密钥对指的是由特定的身份验证协议使用的公钥和私钥文件。
SSH 公钥身份验证使用不对称加密算法来生成两个密钥文件 – 一个为“私钥”文件,一个为“公钥”文件。 私钥文件等效于密码,在所有情况下都应当保护它们。 如果有人获取了你的私钥,则他们可以像你一样登录到你有权登录的任何 SSH 服务器。 公钥放置在 SSH 服务器上,并且可以共享,不会危害私钥的安全。
ssh-keygen -t ed25519
如上,-t是用于指定算法,包括DSA、RSA、ECDSA、Ed25519等,未指定时默认为RSA算法。
# 以下设置以ed25519算法生成密钥对
PS C:\WINDOWS\system32> ssh-keygen -t ed25519
# 提示生成密钥的信息
Generating public/private ed25519 key pair.
# 此处用于设置密钥文件的存储位置,默认为前面括号中的文件名称
# 若要设置名称,后方需要写入文件所在路径以及文件名称才可,不能只写一个名称
Enter file in which to save the key (C:\Users\xxx/.ssh/id_ed25519):
# 由于我原来生成过,所以要确认是否覆盖
C:\Users\xxx/.ssh/id_ed25519 already exists.
Overwrite (y/n)? y # 回复y确认覆盖
# 以下时设置创建密码时是否加密私钥的密码,直接按Enter是不加密
Enter passphrase (empty for no passphrase):
# 确认密码
Enter same passphrase again:
# 密码确认通过后会生成密钥对
Your identification has been saved in C:\Users\xxx/.ssh/id_ed25519.
Your public key has been saved in C:\Users\xxx/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:gSHnvI7PnKlI/QgZUzvbbFoY+o+l0pIhgSlHkytgkbI xxx@PC-xxx
The key's randomart image is:
+--[ED25519 256]--+
| .o.. o |
|oo+ = o |
|=+ o. + . |
|E o. . . . |
|.+o + . S |
|. .* X |
| .=+= B |
| .++.& o |
| .oBoO |
+----[SHA256]-----+
创建成功后可以在文件夹下看到密钥对,无扩展名的是私钥,带“.pub”的是公钥。
私钥的管理一般使用ssh-agent来管理,通过ssh-add添加私钥。
# 获取服务
Get-Service ssh-agent | Set-Service -StartupType Manual
# 启动服务器
Start-Service ssh-agent
# 运行服务
Get-Service ssh-agent
# 将私钥添加到ssh-agent,注意需要添加对应私钥的路径
ssh-add ~\.ssh\id_ed25519
注:要想免密登录,启动Agent服务,建议设置成自动启动。
连接到ssh服务器之后可以通过scp将公钥文件复制到服务器,然后执行命令加载公钥
# 连接服务器后创建公钥存储目录,注意mkdir一般只能创建一级目录
ssh UserName@Server_IP mkdir C:\ProgramData\ssh\
# 使用scp拷贝公钥到服务器上
scp C:\Users\username\.ssh\id_ed25519.pub UserName@Server_IP:C:\ProgramData\ssh\administrators_authorized_keys
# 访问公钥文件,生效公钥
ssh --% UserName@Server_IP icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
一般可能服务器会有多个公钥,先通过cd命令切换到公钥所在路径,然后可通过cat指令将公钥添加到公钥文件中,添加完之后重启ssh服务器(也可不重启,具体看情况,我是重启才有效)。
cat zero.pub >> administrators_authorized_keys
若公钥无法正常识别时,需要修改ssh_config文件配置,修改配置信息PubkeyAuthentication yes和
AuthorizedKeysFile.ssh/authorized_keys:
若是管理员账户访问时需要配试匹配管理员账户信息:
当公钥和私钥均部署完毕后,再在本地主机上通过ssh访问服务器时即可不用输入密码,当然首次登录一般还是需要进行密码确认。
Agent服务需要设置成自动启动,否则重启电脑后仍然需要密码登录,或者启动Agent服务后才能这正常免密访问。
ssh文件传输可使用sftp或者scp进行操作,
sftp [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
[-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit]
[-o ssh_option] [-P port] [-R num_requests] [-S program]
[-s subsystem | sftp_server] destination
scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program] source ... target
最简单的操作就是指定文件两个文件路径直接拷贝。
若需要大量操作,还可以使用WinSCP软件来操作,网址如下:
WinSCP :: Official Site :: Free SFTP and FTP client for Windows
ssh的精华功能是用作端口转发,可以通过端口转发将不安全连接转换成加密的数据连接,大大提高数据安全性。
ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
[-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
[-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
[-i identity_file] [-J [user@]host[:port]] [-L address]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-Q query_option] [-R address] [-S ctl_path] [-W host:port]
[-w local_tun[:remote_tun]] destination [command]
常用参数如下:
-f:后台执行ssh指令
-C:允许压缩数据
-N:不执行远程指令
-R:远程端口转发
-L:本地端口转发
-D:动态转发
-g:允许远端主机连接本地转发的端口
-v:调试模式运行,可以打印一些日志信息
通过-L参数进行本地端口转发,可实现对本地端口的访问转发到远程服务器上。
ssh -L [本地IP]本地端口:目标主机IP(或主机名):目标端口 Username@Server_IP
通过本地端口转发,可以实现对本地主机的某个端口进行访问时,通过远程服务器中转,变成访问远程的服务器。
当远程端口省略时默认绑定到127.0.0.1。
ssh -R [远程IP:]远程端口:目标IP:目标端口 UserName@Server_IP
进行远程端口转发时,发起放必须在目标主机中发起,将对远程服务器主机指定端口的访问转发到本地主机上。
进行远程端口转发时,需要保证,服务器的安全组规则开放了端口:
window可以通过“netstat ”查看端口配置情况,ip为0.0.0.0:3389匹配设置的远程ip时就标识配置成功。
PS C:\Windows\system32> netstat -ano|findstr "3389"
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 1516
TCP [::]:3389 [::]:0 LISTENING 1516
UDP 0.0.0.0:3389 *:* 1516
UDP [::]:3389 *:* 1516
配置成功后可以在服务器的资源监视器查看对应端口的使用情况,若端口防火墙状态不是允许,需要在防火墙添加对应端口的入站规则,否则远程端口配置成功了,也无法正常转发,因为服务器该端口无法正常访问。
ssh运行依赖于客户端,一旦客户端关闭,ssh就会断开连接,可通过autossh等工具进行配置,自动连接ssh。
我打算使用python编辑一个小工具调用powershell自动连接ssh,然后添加成服务程序,设置自动启动(这个后面再整)。