jumpserver/jumpserver.py

227 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/python
# coding: utf-8
"""
This script is used to let server to be a jump server.
业务逻辑: 用户通过自己这套账号密码连接到跳板机,
然后从跳板机链接到各个业务Server, 该脚本可以实现
登录到其他业务机的功能,并且针对不同的用户实现不
同的授权的, 可以讲用户的负责的主机print出来
户的权限密码存放在数据库中。现在要考虑是否得用ex-
pect模块还是os.command.用户选择别的或者Ctrl+D,
Ctrl+C直接退出。改脚本二进制方式存放。
使用方法:
1. 把该文件放到合适的问题如/tmp保证所有用户都能访问的到。
2. vim /etc/profile.d/jump.sh
#/bin/bash
python /tmp/jump.py
if [ $USER == 'root' ]:
echo ""
else
exit
fi
数据库表结构:
user
id username password
server
id ip port
user_server
id user_id server_id
CREATE TABLE user(id INT NOT NULL,
username VARCHAR(30),
password VARCHAR(30),
PRIMARY KEY(id)
) ENGINE=INNODB;
CREATE TABLE server(id INT NOT NULL,
ip VARCHAR(20),
port SMALLINT,
PRIMARY KEY(id)
) ENGINE=INNODB;
CREATE TABLE user_server(id INT NOT NULL,
user_id INT,
server_id INT,
PRIMARY KEY(id),
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;
select * from user t1, server t2, user_server t3 where t1.username='ldapuser' and t1.id=t3.user_id and t2.id = t3.server_id;
"""
import os
import sys
import subprocess
import pexpect
import struct
import fcntl
import termios
import signal
import MySQLdb
import re
"""
#Test user
host = '192.168.2.143'
port = 22
user = 'ldapuser'
password = 'redhat'
"""
db_host = '127.0.0.1'
db_user = 'root'
db_password = 'redhat'
db_db = 'jump'
db_port = 3306
def sigwinch_passthrough (sig, data):
winsize = getwinsize()
global bar
bar.setwinsize(winsize[0],winsize[1])
def getwinsize():
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912L # Assume
s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s)
return struct.unpack('HHHH', x)[0:2]
def progress(second, nums, sym='.'):
for i in range(nums):
os.write(1, sym)
time.sleep(second)
sys.stdout.flush()
def connect_db(user, passwd, db, host='127.0.0.1', port=3306):
db = MySQLdb.connect(host=host,
port=port,
user=user,
passwd=passwd,
db=db)
cursor = db.cursor()
return (db, cursor)
def run_cmd(cmd):
pipe = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if pipe.stdout:
return pipe.stdout.read().strip()
if pipe.stderr:
return pipe.stdout.read()
def is_ip(ip):
ip_re = re.compile(r'^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$')
match = ip_re.match(ip)
if match:
return True
else:
return False
def connect(host, port, user, password ):
foo = pexpect.spawn('ssh -p %s %s@%s' % (port, user, host))
while True:
index = foo.expect(['continue',
'assword',
pexpect.EOF,
pexpect.TIMEOUT], timeout=3)
if index == 0:
foo.sendline('yes')
continue
elif index == 1:
foo.sendline(password)
index = foo.expect([']',
'assword',
pexpect.EOF,
pexpect.TIMEOUT], timeout=3)
if index == 0:
signal.signal(signal.SIGWINCH, sigwinch_passthrough)
size = getwinsize()
foo.setwinsize(size[0], size[1])
foo.interact()
print "Login success!"
break
else:
print "Login failed, please contact system administrator!"
break
def ip_all_select(username):
ip_all = []
db, cursor = connect_db(db_user, db_password, db_db, db_host, db_port)
cursor.execute('select t2.ip from user t1, server t2, user_server t3 where t1.username="%s" and t1.id=t3.user_id and t2.id = t3.server_id;' % username)
ip_all_record = cursor.fetchall()
if ip_all_record:
for record in ip_all_record:
ip_all.append(record[0])
db.close()
return ip_all
def sth_select(username='', ip=''):
db, cursor = connect_db(db_user, db_password, db_db, db_host, db_port)
if username:
cursor.execute('select password from user where username="%s"' % username)
try:
password = cursor.fetchone()[0]
except IndexError:
password = ''
return password
if ip:
cursor.execute('select port from server where ip="%s"' % ip)
try:
port = cursor.fetchone()[0]
except IndexError:
port = 22
return port
return Null
if __name__ == '__main__':
username = run_cmd('whoami')
print username
while True:
option = raw_input("""
Welcome Use JumpServer To Login.
1) Type L/l To Login.
2) Type P/p To Print The Servers You Available.
3) Other To Quit.
Your Choince: """)
if option in ['P', 'p']:
ip_all = ip_all_select(username)
for ip in ip_all:
print '\n' * 2
print ip
print '\n' * 2
continue
elif option not in ['L', 'l']:
sys.exit()
try:
while True:
ip = raw_input('Please input the Host IP: ')
if is_ip(ip) and ip in ip_all_select(username):
password = sth_select(username=username)
port = sth_select(ip=ip)
print "Connecting %s ." % ip
connect(ip, port, username, password)
elif ip == 'admin':
break
elif ip in ['Q', 'q']:
break
else:
print 'No permision.'
continue
except (BaseException,Exception):
print "Error!"
sys.exit()