在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 -A

假定host1是本地主機,host2是遠程主機。由於種種原因,這兩台主機之間無法連通。但是,另外還有一台host3,可以同時連通前面兩台主機。因此,很自然的想法就是,通過host3,將host1連上host2。

我們在host1執行下面的命令:

"本地端口:目標主機:目標主機端口"

$ ssh -L 2121:host2:21 host3
監聽本地2121端口,當訪問本地2121端口時,數據將通過host3 轉發到host2 的21 端口。

 $ 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 -p 9001 localhost

 

還是接着看上面那個例子,host1與host2之間無法連通,必須借助host3轉發。但是,特殊情況出現了,host3是一台內網機器,它可以連接外網的host1,但是反過來就不行,外網的host1連不上內網的host3。這時,"本地端口轉發"就不能用了,怎么辦?

解決辦法是,既然host3可以連host1,那么就從host3上建立與host1的SSH連接,然后在host1上使用這條連接就可以了。

我們在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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM