測試環境為 CentOS 8 x86_64 (虛擬機)
paramiko 套件允許我們可以透過 SSH 連線方式來執行遠端機器的程式.
安裝所需套件.
[root@localhost ~]# pip install paramiko
[root@localhost ~]# python3 Python 3.6.8 (default, Mar 25 2022, 11:15:52) [GCC 8.5.0 20210514 (Red Hat 8.5.0-10)] on linux Type "help", "copyright", "credits" or "license" for more information.
使用密碼方式進行連線
import paramiko username = "root" password = "111111" hostname = "192.168.31.132" port = 22 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname, port, username, password) stdin, stdout, stderr = client.exec_command('ls /') result = stdout.readlines() print (result)
執行結果
['bin\n', 'boot\n', 'dev\n', 'etc\n', 'home\n', 'lib\n', 'lib64\n', 'media\n', 'mnt\n', 'opt\n', 'powercycle\n', 'proc\n', 'root\n', 'run\n', 'sbin\n', 'srv\n', 'sys\n', 'tmp\n', 'usr\n', 'var\n']
程式說明:
匯入 paramiko 套件
import paramiko
後面 connect 函數所需參數.
username = "root" password = "111111" hostname = "192.168.31.132" port = 22
建立 paramiko 物件.
client = paramiko.SSHClient()
set_missing_host_key_policy 函數為不使用 host key 來建立連線方式, paramiko.AutoAddPolicy() 會將收到的 SSH Public 公鑰儲存起起來到預設路徑 ( root 為 /rot/.ssh/known_hosts )
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
建立連線
client.connect(hostname, port, username, password)
透過 SSH 執行遠端程式.
stdin, stdout, stderr = client.exec_command('ls /')
使用金鑰安全驗證方式進行連線
事前準備
我們可以透過建立 Public Key 而不需輸入密碼.實作上的步驟如下 :
- Client 端 ( SSH Client / paramiko : IP: 192.168.31.132)
先在 Client 上面建立 Public Key 跟 Private Key 這兩把鑰匙,利用的指令為 ssh-keygen 這個命令:[root@localhost ~]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:d9roPISeul9kCny111111Cx1jXFCfyJGhq222222vfw root@localhost.localdomain The key's randomart image is: +---[RSA 3072]----+ | .+* e.B.oB+. | | o + ..B+.+. | | tto.o5 o o . | | +. t.+ . o | | oo.S.= . | | Ej.B.= | | ..o= . | | o+. | | o+. o. | +----[SHA256]-----+
上面指令產生的 key 為 RSA ,儲存在 $HOME/.ssh 中 (id_rsa 為私鑰, id_rsa.pub 為公鑰),passphrase 主要是保護私鑰 (你需要一串密碼來解開私鑰,也可以不設).
[root@localhost ~]# ll .ssh/ id_rsa id_rsa.pub known_hosts
要這把 Client 的 Public Key 放在任何一個你想要用來登入的主機的 Server 端 User 的家目錄內 (請先確認有 ~/.ssh 目錄).
[root@localhost ~]# scp .ssh/id_rsa.pub 192.168.31.128:/root/.ssh/ root@192.168.31.128's password:
- server 端 (IP: 192.168.31.128)
匯入剛才 client 端產生的公鑰至 $HOME/.ssh/ 裏面的認證檔案 authorized_keys 即可完成[root@localhost ~]# cd .ssh/ [root@localhost .ssh]# cat id_rsa.pub >> authorized_keys
回到 Python 程式.
import paramiko username = "root" hostname = "192.168.31.128" port = 22 client = paramiko.SSHClient() client.load_system_host_keys() client.connect(hostname, port, username) stdin, stdout, stderr = client.exec_command('ls /') result = stdout.readlines() print (result)
執行結果
['bin\n', 'boot\n', 'dev\n', 'etc\n', 'home\n', 'lib\n', 'lib64\n', 'media\n', 'mnt\n', 'opt\n', 'powercycle\n', 'proc\n', 'root\n', 'run\n', 'sbin\n', 'srv\n', 'sys\n', 'tmp\n', 'usr\n', 'var\n']
主要差別在於使用系統預設的公私鑰 ( root 公鑰預設儲存路徑 為 /rot/.ssh/ )
client.load_system_host_keys()
multiple hosts
import paramiko username = "root" password = "111111" hosts = ['192.168.31.132', '192.168.31.128'] port = 22 for host in hosts: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host, port, username, password) stdin, stdout, stderr = client.exec_command('ls /') result = stdout.readlines() print (result)
執行結果
['bin\n', 'boot\n', 'dev\n', 'etc\n', 'home\n', 'lib\n', 'lib64\n', 'media\n', 'mnt\n', 'opt\n', 'powercycle\n', 'proc\n', 'root\n', 'run\n', 'sbin\n', 'srv\n', 'sys\n', 'tmp\n', 'usr\n', 'var\n'] ['bin\n', 'boot\n', 'dev\n', 'etc\n', 'home\n', 'lib\n', 'lib64\n', 'media\n', 'mnt\n', 'opt\n', 'proc\n', 'root\n', 'run\n', 'sbin\n', 'srv\n', 'sys\n', 'tmp\n', 'usr\n', 'var\n']
主要差別在於使用陣列定義 hots 並使用 for 迴圈 來執行.
hosts = ['192.168.31.132', '192.168.31.128']
for host in hosts:
遇過的問題
>>> client.exec_command('ls /') (<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 -> <paramiko.Transport at 0x90e6e438 (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 -> <paramiko.Transport at 0x90e6e438 (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 -> <paramiko.Transport at 0x90e6e438 (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>)
paramiko 物件 exec_command 函數回傳多個結果,需正確使用多個物件來承接資料.
>>> stdin, stdout, stderr = client.exec_command('ls /')
沒有解決問題,試試搜尋本站其他內容