到这里下载最新安装包:https://github.com/PowerShell/Win32-OpenSSH/releases
下载下来解压,而后用管理员打开服务器自带的PowerShell,运行下列命令:
cd C:\OpenSSH-Win64\OpenSSH-Win64
Set-ExecutionPolicy unrestricted
.\install-sshd.ps1
.\ssh-keygen.exe -Alinux
假定host1是本地主机,host2是远程主机。因为种种缘由,这两台主机之间没法连通。可是,另外还有一台host3,能够同时连通前面两台主机。所以,很天然的想法就是,经过host3,将host1连上host2。ios
咱们在host1执行下面的命令:git
"本地端口:目标主机:目标主机端口"github
$ ssh -L 2121:host2:21 host3
监听本地2121端口,当访问本地2121端口时,数据将经过host3 转发到host2 的21 端口。shell
$ ssh -N -L 0.0.0.0:80:localhost:80 pi@host3
监听本地80端口,当访问本地80 端口时会 转发到host3的80端口, 这里的localhost是指的是host3的“本地”服务器
另外一个例子是经过host3的端口转发,ssh登陆host2。网络
$ ssh -L 9001:host2:22 host3
这时,只要ssh登陆本机的9001端口,就至关于登陆host2了。-p参数表示指定登陆端。ssh
$ ssh -p 9001 localhost
仍是接着看上面那个例子,host1与host2之间没法连通,必须借助host3转发。可是,特殊状况出现了,host3是一台内网机器,它能够链接外网的host1,可是反过来就不行,外网的host1连不上内网的host3。这时,"本地端口转发"就不能用了,怎么办?this
解决办法是,既然host3能够连host1,那么就从host3上创建与host1的SSH链接,而后在host1上使用这条链接就能够了。spa
咱们在host3执行下面的命令:
$ ssh -R 2121:host2:21 host1
R参数也是接受三个值,分别是"远程主机端口:目标主机:目标主机端口"。这条命令的意思,就是让host1监听它本身的2121端口,而后将全部数据经由host3,转发到host2的21端口。因为对于host3来讲,host1是远程主机,因此这种状况就被称为"远程端口绑定"。
绑定以后,咱们在host1就能够链接host2了:
$ ftp localhost:2121
作代理
ssh -D 8081 xxx@host
在host上创建8081端口的代理。
设置SSH免密登录:
(这一步能够忽略) [服务段]:一般linux下会修改ssh_config文件来修改ssh配置,但在安装目录并无发现这个文件,查阅官方wiki后发现,原来是在C:\ProgramData\ssh目录下(此目录为隐藏目录)
端口号:Port 22
密钥访问:PubkeyAuthentication yes
密码访问:PasswordAuthentication no
空密码:PermitEmptyPasswords no
[客户段] 生成公私钥匙。 输入命令,不要使用保护密码,设置保护密码为空。
ssh-keygen -t rsa
生成的密钥,在C:\Users\[帐户名]\.ssh 下。将公钥 id_rsa.pub 发送到[服务端] 并放在C:\Users\[帐户名]\.ssh,并从新命名为authorized_keys(也可在ssh_config修改路径)
设置完成后重启sshd服务。
[客户端] 使用ssh链接,须要加上私钥id_ssh,举例子以下:
ssh -i id_rsa -N -L 0.0.0.0:3306:localhost:3306 administrator@10.168.1.154
这时候会遇到Permissions for 'id_rsa' are too open. 的问题。
须要把其余人的权限所有去掉,只保留本身可以访问,不用父级目录继承权限。这样就能够自动登录了,可是第一次须要输入yes。之后就能够无人值守了。若是发现仍然要输入密码,那么进入[服务端]运行 FixHostFilePermissions.ps1 和 FixUserFilePermissions.ps1 的powershell脚本就可真正的免密登陆了。
网上不断线的教程不少,包括用了autossh,可是仍然很差使。最终找到下面的方法:
在使用本地链接L方式时候,能够设置循环,保证永不掉线。
@echo off echo *** :LOOP echo [%HOST%] [%date% %time%] ssh running... ssh -i id_rsa -N -L 0.0.0.0:3306:localhost:3306 administrator@10.168.1.154 timeout 60 > NUL goto LOOP echo [%HOST%] [%date% %time%] exited
可是在使用远程链接R的时候,上述方法不必定好使, 由于网络断了链接不会自动终端,也就没法触发循环。能够尝试使用TCPkeepAlive=yes 还有配置ServerAliveInterval向服务器发送请求判断是否掉线。实测发现,即便网络断线后,一旦网络恢复稳定后,会自动从新链接。
ssh.exe -i id_rsa -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveInterval=30 -N -R 7999:10.8.69.4:7999 administrator@10.168.1.154
踩过的坑:
命令行不识别空格时:C:\Program Files\用C:\Progra~1\替代
Windows Service2012R2即便配置了.ssh/authorized_keys公钥,链接时依然显示没有注册公钥。。。
查阅了官方wiki判断多是权限问题:Fix SSH file permissions
进入C:\Program Files\OpenSSH(安装目录),右键 FixHostFilePermissions.ps1【使用PowerShell运行】,命令行提示全选是,重启sshd服务后密钥链接正常
附: 常见错误以下:
Error message: channel 3: open failed: connect failed: Connection refused
Change localhost to 127.0.0.1 in the ssh -L
parameter.
Cannot listen on port X on local machine because of network policies.
Try to use another port locally. Ports such as 3306 (MySQL) may have been left open. These are good to use for SSH tunneling if you aren’t already running MySQL.
Error message: Privileged ports can only be forwarded by root.
Use a port above 1024, or try to set up the SSH tunnel as root.
Error message: bind: Address already in use, channel_setup_fwd_listener: cannot listen to port: xxxx, Could not request local forwarding.
Some local server process is already listening on the local port you’re trying to forward to. Pick a different local port and configure your program to connect to th at port instead. If your program cannot be configured to listen to a different port, try to find what server process is occupying that port (netstat -a
on Linux or lsof -i -P
on Mac OS X) and stop it. Retry setting up the tunnel.
I want other hosts on my network to be able to use the tunnel I established.
By default, only local clients can connect to SSH tunnels established this way.
Use the -g
option when setting up the tunnel. Realize that this is insecure, but it may make sense in certain scenarios.
I don’t know what local port is available for me to use.
Linux: netstat -a | grep LISTEN
Mac OS X: lsof -i -P | grep LISTEN
will show you the ports that are in use. Generally, you can pick any that’s not already taken. To make sure you’re not breaking some other unknown protocol, check the IANA Well-known Port Numbers list and pick one that’s not taken.
If you’ve not been able to debug this so far, try passing the -v
parameter to ssh to see verbose output. Add another -v
for more verbose output.