日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

python连接linux堡垒机_利用Python Paramiko开发linux堡垒机

發布時間:2023/12/4 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python连接linux堡垒机_利用Python Paramiko开发linux堡垒机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.Paramiko模塊下的demo.py程序

前面利用Python中的Paramiko模塊可以進行SSH的連接,以及用來傳送文件(SFTP),但是無論是哪一種方式,連接都是短暫的,并非是長連的,即一次執行一個命令或上傳與下載一個文件,顯然效率是不如直接使用Linux shell下的ssh連接命令來進行連接。其實在將Paramiko的源碼解壓出來后,里面有一個demo的文件夾,里面有一個demo.py的程序,利用它,我們就可以進行長連接,即像ssh一樣連接遠程主機:xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6/sorftwares/demp_test/paramiko-1.7.7.1$?ls

demos??LICENSE??????paramiko???????????PKG-INFO??setup.cfg????????setup.py??tests

docs???MANIFEST.in??paramiko.egg-info??README????setup_helper.py??test.py

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6/sorftwares/demp_test/paramiko-1.7.7.1$?cd?demos/

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6/sorftwares/demp_test/paramiko-1.7.7.1/demos$?ls?-l?demo.py

-rwxrwxrwx?1?root?root?5340??6月?16??2010?demo.py

利用demo.py程序,我們可以進行ssh的長連接,比如這里有一臺IP地址為192.168.1.124的遠程主機需要進行連接,使用遠程主機的賬戶名為xpleaf,如下:xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6/sorftwares/demp_test/paramiko-1.7.7.1/demos$?python?demo.py

Hostname:?192.168.1.124

***?Host?key?OK.

Username?[xpleaf]:?xpleaf

Auth?by?(p)assword,?(r)sa?key,?or?(d)ss?key??[p]

Password?for?xpleaf@192.168.1.124:

***?Here?we?go!

Last?login:?Fri?Oct??9?17:19:42?2015?from?192.168.1.13

[xpleaf@moban?~]$?pwd

/home/xpleaf

這樣我們就可以像ssh連接一樣在遠程主機上執行相關的命令了,下面,我們就是通過觀察demo.py程序的源代碼來對相關的程序模塊作修改,然后實現簡單的堡壘主機監控程序的開發。

2.通過修改與demo.py相關的模塊來達到堡壘主機監控的功能

堡壘主機可以監控運維人員在服務器上做的命令操作,這里要做的,只是可以監控運維人員在Linux服務器上執行命令的操作,下面先給出這個監控程序的示意圖:

運維人員登陸認證示意圖:

運維人員命令監控記錄示意圖:

基于上面兩個圖示的說明,以及對Paramiko模塊中demo.py程序代碼的理解,可以對demo.py模塊以及相關的模塊程序源代碼作相應的修改,至于這個引導的過程,因為是Alex老師引導過來的,根據Alex老師修改源代碼的一些思想,然后自己再進一步修改其它部分的源代碼,所以這整一個探索的過程如果要講出來,篇幅比較大,這里就不提及了,下面直接給代碼:

修改后的demo.py源代碼:#!/usr/bin/env?python

import?base64

from?binascii?import?hexlify

import?getpass

import?os

import?select

import?socket

import?sys

import?threading

import?time

import?traceback

import?paramiko

import?interactive

def?agent_auth(transport,?username):

"""

Attempt?to?authenticate?to?the?given?transport?using?any?of?the?private

keys?available?from?an?SSH?agent.

"""

agent?=?paramiko.Agent()

agent_keys?=?agent.get_keys()

if?len(agent_keys)?==?0:

return

for?key?in?agent_keys:

print?'Trying?ssh-agent?key?%s'?%?hexlify(key.get_fingerprint()),

try:

transport.auth_publickey(username,?key)

print?'...?success!'

return

except?paramiko.SSHException:

print?'...?nope.'

def?manual_auth(username,?hostname,pw):

'''default_auth?=?'p'

auth?=?raw_input('Auth?by?(p)assword,?(r)sa?key,?or?(d)ss?key??[%s]?'?%?default_auth)

if?len(auth)?==?0:

auth?=?default_auth

if?auth?==?'r':

default_path?=?os.path.join(os.environ['HOME'],?'.ssh',?'id_rsa')

path?=?raw_input('RSA?key?[%s]:?'?%?default_path)

if?len(path)?==?0:

path?=?default_path

try:

key?=?paramiko.RSAKey.from_private_key_file(path)

except?paramiko.PasswordRequiredException:

password?=?getpass.getpass('RSA?key?password:?')

key?=?paramiko.RSAKey.from_private_key_file(path,?password)

t.auth_publickey(username,?key)

elif?auth?==?'d':

default_path?=?os.path.join(os.environ['HOME'],?'.ssh',?'id_dsa')

path?=?raw_input('DSS?key?[%s]:?'?%?default_path)

if?len(path)?==?0:

path?=?default_path

try:

key?=?paramiko.DSSKey.from_private_key_file(path)

except?paramiko.PasswordRequiredException:

password?=?getpass.getpass('DSS?key?password:?')

key?=?paramiko.DSSKey.from_private_key_file(path,?password)

t.auth_publickey(username,?key)

else:

pw?=?getpass.getpass('Password?for?%s@%s:?'?%?(username,?hostname))

t.auth_password(username,?pw)'''

t.auth_password(username,pw)

#?setup?logging

paramiko.util.log_to_file('demo.log')

username?=?''

if?len(sys.argv)?>?1:

hostname?=?sys.argv[1]

if?hostname.find('@')?>=?0:

username,?hostname?=?hostname.split('@')

else:

hostname?=?raw_input('Hostname:?')

if?len(hostname)?==?0:

print?'***?Hostname?required.'

sys.exit(1)

port?=?22

if?hostname.find(':')?>=?0:

hostname,?portstr?=?hostname.split(':')

port?=?int(portstr)

#?now?connect

try:

sock?=?socket.socket(socket.AF_INET,?socket.SOCK_STREAM)

sock.connect((hostname,?port))

except?Exception,?e:

print?'***?Connect?failed:?'?+?str(e)

traceback.print_exc()

sys.exit(1)

try:

t?=?paramiko.Transport(sock)

try:

t.start_client()

except?paramiko.SSHException:

print?'***?SSH?negotiation?failed.'

sys.exit(1)

try:

keys?=?paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))

except?IOError:

try:

keys?=?paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))

except?IOError:

print?'***?Unable?to?open?host?keys?file'

keys?=?{}

#?check?server's?host?key?--?this?is?important.

key?=?t.get_remote_server_key()

if?not?keys.has_key(hostname):

print?'***?WARNING:?Unknown?host?key!'

elif?not?keys[hostname].has_key(key.get_name()):

print?'***?WARNING:?Unknown?host?key!'

elif?keys[hostname][key.get_name()]?!=?key:

print?'***?WARNING:?Host?key?has?changed!!!'

sys.exit(1)

else:

print?'***?Host?key?OK.'

#?get?username

'''if?username?==?'':

default_username?=?getpass.getuser()

username?=?raw_input('Username?[%s]:?'?%?default_username)

if?len(username)?==?0:

username?=?default_username'''

#changed?by?xpleaf?at?2015.10.9

username?=?sys.argv[2]

password?=?sys.argv[3]

sa_username?=?sys.argv[4]

agent_auth(t,?username)

if?not?t.is_authenticated():

manual_auth(username,?hostname,password)

if?not?t.is_authenticated():

print?'***?Authentication?failed.?:('

t.close()

sys.exit(1)

chan?=?t.open_session()

chan.get_pty()

chan.invoke_shell()

print?'***?Here?we?go!'

print

interactive.interactive_shell(chan,hostname,username,sa_username)

chan.close()

t.close()

except?Exception,?e:

print?'***?Caught?exception:?'?+?str(e.__class__)?+?':?'?+?str(e)

traceback.print_exc()

try:

t.close()

except:

pass

sys.exit(1)

修改后的interactive.py源代碼:import?socket

import?sys,time

#?windows?does?not?have?termios...

try:

import?termios

import?tty

has_termios?=?True

except?ImportError:

has_termios?=?False

def?interactive_shell(chan,hostname,username,sa_username):

if?has_termios:

posix_shell(chan,hostname,username,sa_username)

else:

windows_shell(chan)

def?posix_shell(chan,hostname,username,sa_username):

import?select

date?=?time.strftime('%Y_%m_%d')?#Here?is?changed!

f?=?file('/tmp/%s_%s_record.log'?%?(sa_username,date),'a+')?#Here?is?changed!

record?=?[]?#Here?is?changed!

oldtty?=?termios.tcgetattr(sys.stdin)

try:

tty.setraw(sys.stdin.fileno())

tty.setcbreak(sys.stdin.fileno())

chan.settimeout(0.0)

while?True:

date?=?time.strftime('%Y_%m_%d?%H:%M:%S')?#Here?is?changed!

r,?w,?e?=?select.select([chan,?sys.stdin],?[],?[])

if?chan?in?r:

try:

x?=?chan.recv(1024)

if?len(x)?==?0:

print?'\r\n***?EOF\r\n',

break

sys.stdout.write(x)

sys.stdout.flush()

except?socket.timeout:

pass

if?sys.stdin?in?r:

x?=?sys.stdin.read(1)

if?len(x)?==?0:

break

#print?x

record.append(x)

chan.send(x)

if?x?==?'\r':????#Here?is?changed!Follow:

#print?record

cmd?=?''.join(record).split('\r')[-2]

log?=?"%s?|?%s?|?%s?|?%s\n"?%?(hostname,date,sa_username,cmd)

f.write(log)

f.flush()

f.close()????#Here?is?changed!Above:

finally:

termios.tcsetattr(sys.stdin,?termios.TCSADRAIN,?oldtty)

#?thanks?to?Mike?Looijmans?for?this?code

def?windows_shell(chan):

import?threading

sys.stdout.write("Line-buffered?terminal?emulation.?Press?F6?or?^Z?to?send?EOF.\r\n\r\n")

def?writeall(sock):

while?True:

data?=?sock.recv(256)

if?not?data:

sys.stdout.write('\r\n***?EOF?***\r\n\r\n')

sys.stdout.flush()

break

sys.stdout.write(data)

sys.stdout.flush()

writer?=?threading.Thread(target=writeall,?args=(chan,))

writer.start()

try:

while?True:

d?=?sys.stdin.read(1)

if?not?d:

break

chan.send(d)

except?EOFError:

#?user?hit?^Z?or?F6

pass

存放在堡壘主機下的Menus程序,這里命名為run_demo.py:#!/usr/bin/env?python

import?os,MySQLdb

os.system('clear')

print?'='*35

print?'''\033[32;1mWelcome?to?the?Connecting?System!\033[0m

Choose?the?Server?to?connect:

1.DNS?Server:??192.168.1.124

2.DHCP?Server:?192.168.1.134'''

print?'='*35

choice?=?raw_input('Your?choice:')

if?choice?==?'1':

address?=?'192.168.1.124'

elif?choice?==?'2':

address?=?'192.168.1.134'

sa_user?=?'yonghaoye'

try:

conn?=?MySQLdb.connect(host?=?'localhost',?user?=?'root',?\

passwd?=?'123456',?db?=?'Server_list',?port?=?3306)

cur?=?conn.cursor()

cur.execute("select?*?from?users?where?sa?=?'%s'"?%?sa_user)

qur_result?=?cur.fetchall()

for?record?in?qur_result:

if?record[3]?==?address:

hostname?=?record[3]

username?=?record[4]

password?=?record[5]

cur.close()

conn.close()

except?MySQLdb.Error,e:

print?'Mysql?Error?Msg:',e

cmd?=?'python?/mnt/hgfs/Python/day6/sorftwares/paramiko-1.7.7.1/demos/demo.py?%s?%s?%s?%s'?%?(hostname,username,password,sa_user)

os.system(cmd)

在堡壘主機上添加數據庫:添加了下面這樣的數據庫

mysql>?show?databases;

+--------------------+

|?Database???????????|

+--------------------+

|?information_schema?|

|?Server_list????????|

|?ftp_user???????????|

|?linkman????????????|

|?mysql??????????????|

|?performance_schema?|

|?s6py???????????????|

+--------------------+

7?rows?in?set?(0.01?sec)

mysql>?use?Server_list

Reading?table?information?for?completion?of?table?and?column?names

You?can?turn?off?this?feature?to?get?a?quicker?startup?with?-A

Database?changed

mysql>?show?tables;

+-----------------------+

|?Tables_in_Server_list?|

+-----------------------+

|?users?????????????????|

+-----------------------+

1?row?in?set?(0.00?sec)

mysql>?describe?users;

+-----------------+------------------+------+-----+---------+----------------+

|?Field???????????|?Type?????????????|?Null?|?Key?|?Default?|?Extra??????????|

+-----------------+------------------+------+-----+---------+----------------+

|?id??????????????|?int(10)?unsigned?|?NO???|?PRI?|?NULL????|?auto_increment?|

|?sa??????????????|?char(20)?????????|?NO???|?????|?NULL????|????????????????|

|?server_name?????|?char(20)?????????|?NO???|?????|?NULL????|????????????????|

|?server_address??|?char(20)?????????|?NO???|?????|?NULL????|????????????????|

|?server_username?|?char(20)?????????|?NO???|?????|?NULL????|????????????????|

|?server_password?|?char(20)?????????|?NO???|?????|?NULL????|????????????????|

+-----------------+------------------+------+-----+---------+----------------+

6?rows?in?set?(0.00?sec)

mysql>?selec?*?from?users;

ERROR?1064?(42000):?You?have?an?error?in?your?SQL?syntax;?check?the?manual?that?corresponds?to?your?MySQL?server?version?for?the?right?syntax?to?use?near?'selec?*?from?users'?at?line?1

mysql>?select?*?from?users;

+----+-----------+-------------+----------------+-----------------+-----------------+

|?id?|?sa????????|?server_name?|?server_address?|?server_username?|?server_password?|

+----+-----------+-------------+----------------+-----------------+-----------------+

|??1?|?yonghaoye?|?DNS?Server??|?192.168.1.124??|?xpleaf??????????|?123456??????????|

|??2?|?yonghaoye?|?DHCP?Server?|?192.168.1.134??|?public??????????|?123456??????????|

+----+-----------+-------------+----------------+-----------------+-----------------+

2?rows?in?set?(0.00?sec)

就不對數據庫中的內容做解釋說明了,其實看了前面的示意圖,再看這里的代碼就可以理解了。

3.監控程序演示

演示的網絡環境如下:

由于我在堡壘主機上安裝了shellinabox程序,所以在運維人員主機上,可以直接在web界面輸入堡壘主機的IP地址進行遠程連接,來看下面操作:

(1)運維人員主機登陸堡壘主機

(2)輸入堡壘主機賬號密碼

(3)登陸成功并進入服務器連接列表選擇界面

(4)選擇連接相應服務器

(5)運維人員執行相關命令

(6)在堡壘主機上查看運維人員的命令操作xpleaf@xpleaf-machine:/tmp$?tail?-f?yonghaoye_2015_10_10_record.log

192.168.1.124?|?2015_10_10?00:36:44?|?yonghaoye?|?pwd

192.168.1.124?|?2015_10_10?00:36:48?|?yonghaoye?|?whoami

192.168.1.124?|?2015_10_10?00:37:13?|?yonghaoye?|?echo?$PATH

可以看到,在堡壘主機上生成了一個相對應用戶的命令記錄日志文件,這里可以查看用戶執行的每一個命令,需要注意的是,這里記錄了用戶名“yonghaoye”,是堡壘主機上的用戶,并不是Linux服務器上面的,該用戶是分配給運維人員的,因此,也再一次看到,運維人員并不知道Linux服務器的賬戶和密碼,這樣就比較安全了。

3.不足與優化思路

通過上面的操作,這樣的一個程序確實是可以記錄運維人員在Linux服務器上做的操作,但是不足的是:

(1)程序還存在非常多的細節問題和Bug

(2)界面操作不夠人性化

但不管怎么說,這個小程序只是作為學習過程中的一個練習程序而已,但思路基本上是沒有問題的,根據上面的兩個缺點,往后可以進一步修改源代碼以保證程序運行的穩定性,同時對于界面問題,往后應該是要做成Web界面的,而不是借助shellinabox程序,這就需要調用Python中的Django模塊來做Web方面的開發,當然還有其它技術。

剛過國慶放假期間,看到Alex老師開發了一個開源的堡壘機監控程序,大家可以去看看,而我這里所的這個小程序,作為入門來學習,其實也是非常不錯的。

真的,那就非常了不得了,目前自己也在努力學習過程中,堅持下來就一定可以學到很多!Python不會讓我們失望的!

4.對于堡壘主機監控程序的進一步開發計劃

由于現在知道的真的是太少,往后會不斷學習,希望以后也能以這里這個小程序的思路自己開發一個開源的堡壘主機監控系統,雖然目前已經有開源的了,但作為自己來練手我想也是非常不錯的。

文章的思路寫得有點唐突,因為實在是很難把這其中學習的一個完整的過程寫下來,因為所花費時間非常多。所以我選擇了在演示操作里進行了更多的說明,至于源代碼的修改,有興趣的朋友可以對比修改前的代碼進行比對的。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的python连接linux堡垒机_利用Python Paramiko开发linux堡垒机的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。