python连接linux堡垒机_python 堡垒机续-----终端方式

第一步:环境准备

堡垒机服务器:192.168.1.1

后端服务器1:192.168.1.2

后端服务器2:192.168.1.3

堡垒机安装paramiko 版本:paramiko-1.16.0

堡垒机python版本:Python 2.7.7

第二步:编写menu.py文件,实现类似菜单功能

#!/usr/bin/env python

# encoding: utf-8

# @author: eddy

# @contact: 278298125@qq.com

# @site: http://my.oschina.net/eddylinux

# @file: menu.py

# @time: 2016-01-18 21:58

# @version: 1.0

import os

import sys

msg = '''

\033[42;1mWelcome using eddy's auditing system!\033[0m

'''

print msg

host_dict = {

'eddy1':'192.168.1.2',

'eddy2':'192.168.1.3',

}

while True:

for hostname, ip in host_dict.items():

print hostname,ip

try:

host = raw_input('Please choose one server to login:').strip()

if host == 'quit':

print 'Goodbye'

break

except KeyboardInterrupt:

continue

except EOFError:

continue

if len(host) == 0:

continue

if not host_dict.has_key(host):

print 'No host matched,try again'

continue

print '\033[32;1mGoing to connect \033[0m',host_dict[host]

os.system("python eddy_auditing.py %s" %host_dict[host])

第三步:编写核心功能代码

eddy_auditing.py

#!/usr/bin/env python

# encoding: utf-8

# @author: eddy

# @contact: 278298125@qq.com

# @site: http://my.oschina.net/eddylinux

# @file: menu.py

# @time: 2016-01-18 21:58

# @version: 1.0

import base64

from binascii import hexlify

import getpass

import os

import select

import socket

import sys

import time

import traceback

from paramiko.py3compat import input

import paramiko

try:

#导入interactive模块

import interactive

except ImportError:

from . import interactive

def agent_auth(transport, username):

agent = paramiko.Agent()

agent_keys = agent.get_keys()

if len(agent_keys) == 0:

return

#对key认证方式进行处理

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):

default_auth = 'p'

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

if len(auth) == 0:

auth = default_auth

#判断key是否是rsa

if auth == 'r':

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

path = 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)

#判断key是否是dsa

elif auth == 'd':

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

path = 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)

# 设置日志

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

#定义用户名

username = ''

if len(sys.argv) > 1:

hostname = sys.argv[1]

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

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

else:

hostname = input('Hostname: ')

if len(hostname) == 0:

print('*** Hostname required.')

sys.exit(1)

#定义端口

port = 6666

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

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

port = int(portstr)

#建立连接

try:

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

sock.connect((hostname, port))

except Exception as e:

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

traceback.print_exc()

sys.exit(1)

#使用paramiko进行登陆处理

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 = {}

# 检查服务器密钥

key = t.get_remote_server_key()

if hostname not in keys:

print('*** WARNING: Unknown host key!')

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

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.')

#获取用户名

if username == '':

default_username = getpass.getuser()

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

if len(username) == 0:

username = default_username

agent_auth(t, username)

if not t.is_authenticated():

manual_auth(username, hostname)

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!\n')

interactive.interactive_shell(chan)

chan.close()

t.close()

except Exception as e:

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

traceback.print_exc()

try:

t.close()

except:

pass

sys.exit(1)

编写linux与windows处理方法

interactive.py

#!/usr/bin/env python

# encoding: utf-8

# @author: eddy

# @contact: 278298125@qq.com

# @site: http://my.oschina.net/eddylinux

# @file: menu.py

# @time: 2016-01-18 21:58

# @version: 1.0

import socket

import sys

from paramiko.py3compat import u

try:

import termios

import tty

has_termios = True

except ImportError:

has_termios = False

def interactive_shell(chan):

if has_termios:

posix_shell(chan)

else:

windows_shell(chan)

#linux处理方法

def posix_shell(chan):

import select

#获取原来的tty

oldtty = termios.tcgetattr(sys.stdin)

try:

#设置tty

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

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

chan.settimeout(0.0)

while True:

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

if chan in r:

try:

x = u(chan.recv(1024))

if len(x) == 0:

sys.stdout.write('\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

chan.send(x)

finally:

#把修改的tty变回来

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

#windows处理方法

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

另外在堡垒机上,在用户登录堡垒机的家目录下的bashrc文件中添加一下内容,例如eddy用户登录堡垒机就在eddy用户家目录下的.bashrc添加一下内容

/usr/bin/python /root/script/menu.py

exit

以防止在终端堡垒机程序之后终端会话留在堡垒机上

以上三步完成一个简单堡垒机功能

总共三个文件 menu.py eddy_auditing.py interactive.py

关系:menu.py 菜单文件

eddy_auditing.py 核心功能文件,会调用interactive.py

interactive.py  处理linux与windows方法

http://my.oschina.net/eddylinux/blog/604317

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值