⑴ SSH 之遠程登錄
從客戶端來看,SSH提供兩種級別的安全驗證。
對於第二種級別,你必須知道自己密匙的口令。但是,與第一種級別相比,第二種級別不需要在網路上傳送口令。第二種級別不僅加密所有傳送的數據,而且「中間人」這鉛乎種攻擊方式也是不可能的(因為他沒有用戶的私人密匙)。但是整個登錄的過程可能需要10秒。
將本地用戶生成的公鑰推送至遠程伺服器後,遠程主機將用戶的公鑰,保存在登錄後的用戶主目錄的$HOME/.ssh/authorized_keys文件中。公鑰就是一段字元串,只要把它追加在authorized_keys文件的末尾就行了。
這里不使用ssh--id命令,改用下面的命令,來解釋公鑰的保存過程:
輸入命令 ssh user@host ,然後根據提示輸入遠程伺服器的登錄密碼
也可在配置文件/etc/ssh/ssh_config 中設置user和host(ip), 來簡化命令, 配置如下:
配置後, 登錄請求時只需輸入如洞悉下命令:
使用密碼登錄,每次都必須輸入密碼,非常麻煩。好在SSH還提供了公鑰登錄,可以省去輸入密碼的步驟。
公鑰登錄原理 :就是用戶將自己的公鑰儲存在遠程主機上。登錄的時候,遠程主機會向用戶發送一段隨機字元串,用戶用自己的私鑰加密後,再發回來。遠程主機用事先儲存的公鑰進行解密,如果解密驗證成功,就證明用戶是可信的,直接允許登錄shell,不再要求密碼。
執行上述命令首先會讓你輸入生成密鑰的文件名: myPemKey (自定義),之後一路回車。
配置後,登錄遠槐顫悉程伺服器時只需輸入一下命令,便可直接登錄成功:
修改後重啟ssh服務
則遠程連接時指定埠
(1) 通過iptables設置ssh埠的白名單,如下設置只允許192.168.1.0/24網段的客戶機可以遠程連接本機
(2) 通過/etc/hosts.allow裡面進行限制(如下),/etc/hosts.deny文件不要任何內容編輯,保持默認!
例如:
修改遠程伺服器ssh服務配置文件/etc/ssh/sshd_config
修改遠程伺服器配置文件/etc/ssh/sshd_config, 如下:
如果本機系統有些賬號沒有設置密碼,而ssh配置文件里又沒做限制,那麼遠程通過這個空密碼賬號就可以登陸了,這是及其不安全的,所以一定要禁止空密碼登陸。
修改遠程伺服器配置文件/etc/ssh/sshd_config,如下:
參考:
⑵ 本地shell腳本中ssh到遠程伺服器並執行命令
在實際運用中在當前伺服器執行命令後,需要在另一台伺服器繼續執行某些命令,分開去到另一台伺服器執行也是比較麻煩的,因此整理下集中執行的方式
1、首先配置ssh免密操作
linux 下實現SSH互信: https://www.jianshu.com/p/2456d98aa607
2、簡單命令
ssh [email protected] "cd /var/lib; ls; cd "
2.1 使用時注意,雙引號必須有。若沒加雙引號,第二條及之後的命令會在本地執行
2.2 分號是將兩條語句間隔開
2.3 單雙引的區別:單引號不會解析值,是什麼就傳什麼;雙引號會解析值,將解析結果傳過去
3、多條命令
ssh [email protected]<< reallssh
cd /var/lib/test
tar -zxvf api.com.tar.gz
......
exit
reallssh
3.1 命令寫在 << reallssh(開始) 至 reallssh(結束) 之間
3.2 reallssh可自己定義為其他形式
3.3 在結束前加上exit退出遠程
4、可能遇到的問題
問題:遠程登錄主機時出現Pseudo-terminal will not be allocated because stdin is not a terminal. 錯誤
解決方案:字面意思是偽終端將無法分配,因為標准輸入不是終端。
所以需要增加-t -t參數來強制偽終端分配,即使標准輸入不是終端。
to force pseudo-tty allocation even if stdin isn』t a terminal.
參考樣例如下:
ssh -t -t [email protected] -p 22
--------------------------------------------------------------------------------
參考:https://blog.csdn.net/jinking01/article/details/84386769
⑶ ssh遠程連接伺服器執行命令
首先說一下使用ssh遠程連接伺服器執行命令的方法:
為了方便描述,這里把測試伺服器稱之為A1,目標伺服器稱之為A2
如果可以直接登錄到A2,則配置成功!
下面來說問題:
ssh在遠程連接伺服器執行命令的時候,經常會遇到環境變數的問題,如下:
如果出現上面的提示,則說明環境變數配置有問題。
先來說解決辦法
問題解決!
這里就要說明bash有兩種方式interactive + login shell模式和non-interactive + non-login shell模式
在伺服器上執行命令,走的是interactive + login shell模式,而通過遠程登錄執行命令,走的是non-interactive + non-login shell模式。
這兩種模式對於環境變數的讀取是有區別的。
Shell首先會載入/etc/profile文件,然後再嘗試依次去載入下列三個配置文件之一,一旦找到其中一個便不再接著尋找:
~/.bash_profile
~/.bash_login
~/.profile
所以當遠程執行命令時,我們只需要讓~/.bashrc文件中的環境變數與/etc/profile中的環境變數一致即可!
參考:
如何解決SSH遠程執行命令找不到環境變數的問題
⑷ ssh連接centos遠程伺服器運行指令的問題
總結下使用ssh遠程執行命令需要注意點:
一般我們會使用ssh ip "執行命令"這種格式來執行遠程是shell命令,但是如果是簡單的一些操作還好,比如cd,rm,ls,mv等命令一般不會出問題
,但是如果你的腳本任務是,殺死多台機器上的hadoop或者elasticsearch進程,你會怎麼做?
倫理片http://www.dotdy.com/
直接使用:
ssh h1 "kill -9 `jps | grep Elastic* | gawk '{print $1}' ` " 殺死es進程,你會發現,它竟然沒有生效? 明明在本地執行
kill -9 `jps | grep Elastic* | gawk '{print $1}' `
這個命令是可以生效的,為啥,放到遠程執行命令中就失效了呢?
其實原因很簡單,就是因為沒有轉義造成的,包括awk變數名引用都需要轉義,否則,你會發現,雖然能執行,但結果依舊是不準確的,注意linux中
單引號(所有命令均被當成普通字元處理)
雙引號(可引用變數名)
反引號(可以執行linux腳本命令)的區別
看最終的正確的寫法:
Java代碼
ssh$host"es_pid=`jps|grepElasticsearch|gawk'{print$1}'`&&kill$es_pid"
⑸ Linux-兩種ssh遠程執行命令方式載入環境變數區別
最近在編寫腳本的時候發現一個問題,在執行 kubectl -n kube-system get pods 這個命令的時候,通過 ssh root@ip command 和 ssh root@ip command 登錄後執行得到了不同的結果,
從上面可以看到哪賀SSH遠程執行獲取pods失敗了,但是shell窗口執行卻成功了,所以我們可以猜到兩者之間一定有什麼區別導致結果的不同。那麼區別在哪裡呢?通過研究發現兩者的環境變數存在區別,通過執行printenv可以查看所有設置的環境變數:
通過上面可以看到SSH遠程執行的時候是沒有KUBECONFIG這個環境變數,而Shell窗口是有的,為什麼有這個區別呢?這就要從Linux的bash的四種模式說起。
bash的四種模式:
從上面可以看出不同方式下載入的配置文件不同,那麼怎麼知道我們是載入了那些配置文襪凱件呢? 這里有一個驗證的方法,就是在上面的每個配置告緩喚文件中添加一句 echo $/etc/profile 這樣的命令,把每個文件的路徑列印出來。當配置文件被載入時,會輸出相應的文件名,本例中在兩個文件中加了該命令:/etc/pfoile, ~/.bashrc,然後使用不同SSH方式執行命令的結果如下。
只載入了.bashrc文件,未載入/etc/profile。
從輸出可以看到兩個配置都載入了,而KUBECONFIG只定義在/etc/profile中,沒有定義在.bashrc文件中,所以通過 ssh root@ip command 執行時沒有拿到KUBECONFIG這個環境變數從而導致報錯。知道原因後我們就可以將KUBECONFIG環境變數添加到.bashrc文件即可。
⑹ SSH遠程操作與埠轉發的原理
SSH不僅可以用於遠程主機登錄,還可以直接在遠程主機上執行操作。
上一節的操作,就是一個例子:
單引號中間的部分,表示在遠程主機上執行的操作;後面的輸入重定向,表示數據通過SSH傳向遠程主機。
這就是說,SSH可以在用戶和遠程主機之間,建立命令和數據的傳輸通道,因此很多事情都可以通過SSH來完成。
下面看幾個例子。
【例1】
將 HOME/src/目錄。
【例2】
將遠程主機$HOME/src/目錄下面的所有文件,復制到用戶的當前目錄。
【例3】
查看遠程主機是否運行進程httpd。
既然SSH可以傳送數據,那麼我們可以讓那些不加密的網路連接,全部改走SSH連接,從而提高安全性。
假定我們要讓8080埠的數據,都通過SSH傳向遠程主機,命令就這樣寫:
SSH會建立一個socket,去監聽本地的8080埠。一旦有數據傳向那個埠,就自動把它轉移到SSH連接上面,發往遠程主機。可以想像,如果8080埠原來是一個不加密埠,現在將變成一個加密埠。
有時,綁定本地埠還不夠,還必須指定數據傳送的目標主機,從而形成點對點的"埠轉發"。為了區別後文的"遠程埠轉發",我們把這種情況稱為"本地埠轉發"(Local forwarding)。
假定host1是本地主機,host2是遠程主機。由於種種原因,這兩台主機之間無法連通。但是,另外還有一台host3,可以同時連通前面兩台主機。因此,很自然的想法就是,通過host3,將host1連上host2。
我們在host1執行下面的命令:
命令中的L參數一共接受三個值,分別是"本地埠:目標主機:目標主機埠",它們之間用冒號分隔。這條命令的意思,就是指定SSH綁定本地埠2121,然後指定host3將所有的數據,轉發到目標主機host2的21埠(假定host2運行FTP,默認埠為21)。
這樣一來,我們只要連接host1的2121埠,就等於連上了host2的21埠。
"本地埠轉發"使得host1和host3之間彷彿形成一個數據傳輸的秘密隧道,因此又被稱為"SSH隧道"。
下面是一個比較有趣的例子。
它表示將本機的5900埠綁定host3的5900埠(這里的localhost指的是host3,因為目標主機是相對host3而言的)。
另一個例子是通過host3的埠轉發,ssh登錄host2。
這時,只要ssh登錄本機的9001埠,就相當於登錄host2了。
上面的-p參數表示指定登錄埠。
既然"本地埠轉發"是指綁定本地埠的轉發,那麼"遠程埠轉發"(remote forwarding)當然是指綁定遠程埠的轉發。還是接著看上面那個例子,host1與host2之間無法連通,必須藉助host3轉發。但是,特殊情況出現了,host3是一台內網機器,它可以連接外網的host1,但是反過來就不行,外網的host1連不上內網的host3。這時,"本地埠轉發"就不能用了,怎麼辦?
解決辦法是,既然host3可以連host1,那麼就從host3上建立與host1的SSH連接,然後在host1上使用這條連接就可以了。
我們在host3執行下面的命令:
R參數也是接受三個值,分別是"遠程主機埠:目標主機:目標主機埠"。這條命令的意思,就是讓host1監聽它自己的2121埠,然後將所有數據經由host3,轉發到host2的21埠。由於對於host3來說,host1是遠程主機,所以這種情況就被稱為"遠程埠綁定"。
綁定之後,我們在host1就可以連接host2了:
這里必須指出,"遠程埠轉發"的前提條件是,host1和host3兩台主機都有sshD和ssh客戶端。
SSH還有一些別的參數,也值得介紹。
N參數,表示只連接遠程主機,不打開遠程shell;T參數,表示不為這個連接分配TTY。這個兩個參數可以放在一起用,代表這個SSH連接只用來傳數據,不執行遠程操作。
f參數,表示SSH連接成功後,轉入後台運行。這樣一來,你就可以在不中斷SSH連接的情況下,在本地shell中執行其他操作。
要關閉這個後台連接,就只有用kill命令去殺掉進程。