在windows中安裝OpenSSH,無密碼登陸,永遠不斷線

到這裏下載最新安裝包: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.

相關文章
相關標籤/搜索