python批量上传执行脚本_批量执行(Linux命令,上传/下载文件)

前言:

每个公司的网络环境大都划分 办公网络、线上网络,之所以划分的主要原因是为了保证线上操作安全;

对于外部用户而言也只能访问线上网络的特定开放端口,那么是什么控制了用户访问线上网络的呢?

防火墙过滤......!

对于内部员工而言对线上系统日常运维、代码部署如何安全访问线上业务系统呢?如何监控、记录技术人员的操作记录?

堡垒机策略:

1.回收所有远程登录Linux主机的用户名、密码;

2.中间设置堡垒机(保存所有线上Linux主机的用户名、密码);

3.所有技术人员都要通过堡垒机去获取用户名、密码,然后在再去连接 线上系统,并记录操作日志;

堡垒机策略优点:

1.记录用户操作;

2.实现远程操作权限集中管理;

一、堡垒机表结构设计

from django.db importmodelsfrom django.contrib.auth.models importUser#Create your models here.

classIDC(models.Model):

name= models.CharField(max_length=64,unique=True)def __str__(self):returnself.nameclassHost(models.Model):"""存储所有主机信息"""hostname= models.CharField(max_length=64,unique=True)

ip_addr= models.GenericIPAddressField(unique=True)

port= models.IntegerField(default=22)

idc= models.ForeignKey("IDC")#host_groups = models.ManyToManyField("HostGroup")

#host_users = models.ManyToManyField("HostUser")

enabled = models.BooleanField(default=True)def __str__(self):return "%s-%s" %(self.hostname,self.ip_addr)classHostGroup(models.Model):"""主机组"""name= models.CharField(max_length=64,unique=True)

host_user_binds= models.ManyToManyField("HostUserBind")def __str__(self):returnself.nameclassHostUser(models.Model):"""存储远程主机的用户信息

root 123

root abc

root sfsfs"""auth_type_choices= ((0,'ssh-password'),(1,'ssh-key'))

auth_type= models.SmallIntegerField(choices=auth_type_choices)

username= models.CharField(max_length=32)

password= models.CharField(blank=True,null=True,max_length=128)def __str__(self):return "%s-%s-%s" %(self.get_auth_type_display(),self.username,self.password)classMeta:

unique_together= ('username','password')classHostUserBind(models.Model):"""绑定主机和用户"""host= models.ForeignKey("Host")

host_user= models.ForeignKey("HostUser")def __str__(self):return "%s-%s" %(self.host,self.host_user)classMeta:

unique_together= ('host','host_user')classSessionLog(models.Model):'''记录每个用户登录操作,ID传给 shell生成文件命名'''account=models.ForeignKey('Account')

host_user_bind=models.ForeignKey('HostUserBind')

start_date=models.DateField(auto_now_add=True)

end_date=models.DateField(blank=True,null=True)def __str__(self):return '%s-%s'%(self.account,self.host_user_bind)classAuditLog(models.Model):"""审计日志"""

classAccount(models.Model):"""堡垒机账户

1. 扩展

2. 继承

user.account.host_user_bind"""user=models.OneToOneField(User)

name= models.CharField(max_length=64)

host_user_binds= models.ManyToManyField("HostUserBind",blank=True)

host_groups= models.ManyToManyField("HostGroup",blank=True)

models.py

二、通过堡垒机远程登录Linux主机

2种堡垒机登录方式:

命令行登录堡垒机方式:

方式1:通过 修改open_shh源码扩展-Z option生成唯一 ssh进程,使用Linux的strace 命令对唯一 ssh进程进行检测生成日志文件;

0.用户执行audit_shell出现交互界面,提示用户输入机组和主机;

importsys,os,django

os.environ.setdefault("DJANGO_SETTINGS_MODULE","zhanggen_audit.settings")

django.setup()#在Django视图之外,调用Django功能设置环境变量!

from audit.backend importuser_interactiveif __name__ == '__main__':

shell_obj=user_interactive.UserShell(sys.argv)

shell_obj.start()

audit_shell.py

from django.contrib.auth importauthenticateclassUserShell(object):'''用户登录堡垒机,启动自定制shell'''

def __init__(self,sys_argv):

self.sys_argv=sys_argv

self.user=Nonedefauth(self):

count=0while count < 3:

username=input('username:').strip()

password=input('password:').strip()

user=authenticate(username=username,password=password)#none 代表认证失败,返回用户对象认证成功!

if notuser:

count+=1

print('无效的用户名或者,密码!')else:

self.user=userreturnTrueelse:print('输入次数超过3次!')defstart(self):"""启动交互程序"""

ifself.auth():#print(self.user.account.host_user_binds.all()) #select_related()

whileTrue:

host_groups=self.user.account.host_groups.all()for index, group inenumerate(host_groups):print("%s.\t%s[%s]" %(index, group, group.host_user_binds.count()))print("%s.\t未分组机器[%s]" %(len(host_groups), self.user.account.host_user_binds.count()))

choice= input("select group>:").strip()ifchoice.isdigit():

choice=int(choice)

host_bind_list=Noneif choice >= 0 and choice

selected_group=host_groups[choice]

host_bind_list=selected_group.host_user_binds.all()elif choice == len(host_groups): #选择的未分组机器

#selected_group = self.user.account.host_user_binds.all()

host_bind_list =self.user.account.host_user_binds.all()ifhost_bind_list:whileTrue:for index, host inenumerate(host_bind_list):print("%s.\t%s" %(index, host,))

choice2= input("select host>:").strip()ifchoice2.isdigit():

choice2=int(choice2)if choice2 >= 0 and choice2

selected_host=host_bind_list[choice2]print("selected host", selected_host)elif choice2 == 'b':break

user_interactive.py

知识点:

在Django视图之外,调用Django功能设置环境变量!(切记放在和Django manage.py 同级目录);

importsys,os,django

os.environ.setdefault("DJANGO_SETTINGS_MODULE","Sensors_Data.settings")

django.setup()#在Django视图之外,调用Django功能设置环境变量!

from app01 importmodels

objs=models.AlarmInfo.objects.all()for row inobjs:print(row.comment)

注意:在Django启动时会自动加载一些 文件,比如每个app中admin.py,不能在这些文件里面设置加载环境变量,因为已经加载完了,如果违反这个规则会导致Django程序启动失败;

1.实现ssh用户指令检测

1.0  修改open_shh源码,扩展 ssh -Z  唯一标识符;(这样每次ssh远程登录,都可以利用唯一标识符,分辨出 每个ssh会话进程;)

修改OpenSsh下的ssh.c文件的608和609行、935行增加;while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvxz:"

"ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYyZ:")) != -1) {case 'Z':break;

ssh.c

知识点:

OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现项目。

1.1  修改openssh之后,编译、安装

chmod 755configure

./configure --prefix=/usr/local/openssh

make

chmod755mkinstalldirs

make install

sshpass-p xxxxxx123 /usr/local/openssh/bin/ssh [email protected] -Z s1123ssssd212

1.2  每个ssh会话进程可以唯一标识之后,在堡垒机使用会话脚本shell脚本检测 ssh会话进程;(strace命令进行监控,并生产 log日志文件);

#!/usr/bin/bash

for i in $(seq 1 30);doecho$i $1process_id=`ps -ef | grep $1 | grep -v 'ession_check.sh' | grep -v grep | grep -v sshpass | awk '{print $2}'`

echo"process: $process_id"

if [ ! -z "$process_id"];then

echo 'start run strace.....'

strace-fp $process_id -t -o $2.log;break;

fi

sleep5done;

ssh 会话检测脚本

知识点:

strace 检测进程的IO调用,监控用户shell输入的命令字符;

strace -fp 60864 -o /ssh.log

cat /ssh.log |grep 'write(8'

rz -E #从xshell上传文件

sshpass无需提示输入密码登录

[root@localhost sshpass-1.06]#sshpass -p wsnb ssh [email protected]  -o StrictHostKeyChecking=no

Last login: Tue Jul 10 16:39:53 2018 from 192.168.113.84[root@ecdb ~]#

python生成唯一标识符

s=string.ascii_lowercase+string.digits

random_tag=''.join(random.sample(s,10))

解决普通用户,无法执行 strace命令;

方式1:执行文件  +s权限

chmod u+s `which strace`

方式2:修改sudo配置文件,使普通用户sudo时无需输入密码!

修改sudo配置文件,防止修改出错,一定要切换到root用户;%普通用户 ALL=(ALL) NOPASSWD: ALL

wq!#退出

vim /etc/sudoers

#!/usr/bin/python3#-*- coding: utf-8 -*

from django.contrib.auth importauthenticateimportsubprocess,string,randomfrom audit importmodelsfrom django.conf importsettingsclassUserShell(object):'''用户登录堡垒机,启动自定制shell'''

def __init__(self,sys_argv):

self.sys_argv=sys_argv

self.user=Nonedefauth(self):

count=0while count < 3:

username=input('username:').strip()

password=input('password:').strip()

user=authenticate(username=username,password=password)#none 代表认证失败,返回用户对象认证成功!

if notuser:

count+=1

print('无效的用户名或者,密码!')else:

self.user=userreturnTrueelse:print('输入次数超过3次!')defstart(self):"""启动交互程序"""

ifself.auth():#print(self.user.account.host_user_binds.all()) #select_related()

whileTrue:

host_groups=self.user.account.host_groups.all()for index, group inenumerate(host_groups):print("%s.\t%s[%s]" %(index, group, group.host_user_binds.count()))print("%s.\t未分组机器[%s]" %(len(host_groups), self.user.account.host_user_binds.count()))

choice= input("select group>:").strip()ifchoice.isdigit():

choice=int(choice)

host_bind_list=Noneif choice >= 0 and choice

selected_group=host_groups[choice]

host_bind_list=selected_group.host_user_binds.all()elif choice == len(host_groups): #选择的未分组机器

#selected_group = self.user.account.host_user_binds.all()

host_bind_list =self.user.account.host_user_binds.all()ifhost_bind_list:whileTrue:for index, host inenumerate(host_bind_list):print("%s.\t%s" %(index, host,))

choice2= input("select host>:").strip()ifchoice2.isdigit():

choice2=int(choice2)if choice2 >= 0 and choice2

selected_host=host_bind_list[choice2]

s= string.ascii_lowercase +string.digits

random_tag= ''.join(random.sample(s, 10))

session_obj=models.SessionLog.objects.create(account=self.user.account,host_user_bind=selected_host)

session_tracker_scipt='/bin/sh %s %s %s'%(settings.SESSION_TRACKER_SCRIPT,random_tag,session_obj.pk)

session_tracker_process=subprocess.Popen(session_tracker_scipt,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

cmd='sshpass -p %s /usr/local/openssh/bin/ssh %s@%s -p %s -o stricthostkeychecking=no -Z %s' %(selected_host.host_user.password,

selected_host.host_user.username,

selected_host.host.ip_addr,

selected_host.host.port,random_tag)

subprocess.run(cmd,shell=True)#开启子进程交互

print(session_tracker_process.stdout.readlines(),

session_tracker_process.stderr.readlines())elif choice2 == 'b':break

汇总

2.shell远程登录程序检查日志文件,分析;

tab补全的命令,需要搜素write(5,该脚本实现思路,按键去尝试,循环多种条件判断;

importreclassAuditLogHandler(object):'''分析audit log日志'''

def __init__(self,log_file):

self.log_file_obj=self._get_file(log_file)def_get_file(self,log_file):returnopen(log_file)defparse(self):

cmd_list=[]

cmd_str= ''catch_write5_flag= False #for tab complication

for line inself.log_file_obj:#print(line.split())

line =line.split()try:

pid,time_clock,io_call,char= line[0:4]if io_call.startswith('read(4'):if char == '"\\177",':#回退

char = '[1

if char == '"\\33OB",': #vim中下箭头

char = '[down 1]'

if char == '"\\33OA",': #vim中下箭头

char = '[up 1]'

if char == '"\\33OC",': #vim中右移

char = '[->1]'

if char == '"\\33OD",': #vim中左移

char = '[1

if char == '"\33[2;2R",': #进入vim模式

continue

if char == '"\\33[>1;95;0c",': #进入vim模式

char = '[----enter vim mode-----]'

if char == '"\\33[A",': #命令行向上箭头

char = '[up 1]'catch_write5_flag= True #取到向上按键拿到的历史命令

if char == '"\\33[B",': #命令行向上箭头

char = '[down 1]'catch_write5_flag= True #取到向下按键拿到的历史命令

if char == '"\\33[C",': #命令行向右移动1位

char = '[->1]'

if char == '"\\33[D",': #命令行向左移动1位

char = '[1

catch_write5_flag=Truecontinue

if char == '"\\r",':

cmd_list.append([time_clock,cmd_str])

cmd_str= '' #重置

if char == '"':#space

cmd_str += ' '

if catch_write5_flag: #to catch tab completion

if io_call.startswith('write(5'):if io_call == '"\7",': #空键,不是空格,是回退不了就是这个键

pass

else:

cmd_str+= char.strip('"",')

catch_write5_flag=FalseexceptValueError as e:print("\033[031;1mSession log record err,please contact your IT admin,\033[0m",e)#print(cmd_list)

for cmd incmd_list:print(cmd)returncmd_listif __name__ == "__main__":

parser= AuditLogHandler(r'D:\zhanggen_audit\log\6.log')

parser.parse()

日志分析

3.修改bashrc文件,限制用户登录行为;

alias rm='rm -i'aliascp='cp -i'aliasmv='mv -i'# Source global definitionsif [ -f /etc/bashrc ]; then./etc/bashrcfi

echo '-----------------------welcome to zhanggen audit --------------------------'python3/root/zhanggen_audit/audit_shell.pyecho 'bye'logout

vim ~/.bashrc

缺陷:

虽然限制了用户shell登录,但无法阻止用户使用程序(paramiko)上传恶意文件!

方式2:提取paramiko源码demos文件,对其进行修改支持交互式操作;

from django.db importmodelsfrom django.contrib.auth.models importUser#Create your models here.

classIDC(models.Model):

name= models.CharField(max_length=64,unique=True)def __str__(self):returnself.nameclassHost(models.Model):"""存储所有主机信息"""hostname= models.CharField(max_length=64,unique=True)

ip_addr= models.GenericIPAddressField(unique=True)

port= models.IntegerField(default=22)

idc= models.ForeignKey("IDC")#host_groups = models.ManyToManyField("HostGroup")

#host_users = models.ManyToManyField("HostUser")

enabled = models.BooleanField(default=True)def __str__(self):return "%s-%s" %(self.hostname,self.ip_addr)classHostGroup(models.Model):"""主机组"""name= models.CharField(max_length=64,unique=True)

host_user_binds= models.ManyToManyField("HostUserBind")def __str__(self):returnself.nameclassHostUser(models.Model):"""存储远程主机的用户信息

root 123

root abc

root sfsfs"""auth_type_choices= ((0,'ssh-password'),(1,'ssh-key'))

auth_type= models.SmallIntegerField(choices=auth_type_choices)

username= models.CharField(max_length=32)

password= models.CharField(blank=True,null=True,max_length=128)def __str__(self):return "%s-%s-%s" %(self.get_auth_type_display(),self.username,self.password)classMeta:

unique_together= ('username','password')classHostUserBind(models.Model):"""绑定主机和用户"""host= models.ForeignKey("Host")

host_user= models.ForeignKey("HostUser")def __str__(self):return "%s-%s" %(self.host,self.host_user)classMeta:

unique_together= ('host','host_user')classAuditLog(models.Model):"""审计日志"""session= models.ForeignKey("SessionLog")

cmd=models.TextField()

date= models.DateTimeField(auto_now_add=True)def __str__(self):return "%s-%s" %(self.session,self.cmd)classSessionLog(models.Model):

account= models.ForeignKey("Account")

host_user_bind= models.ForeignKey("HostUserBind")

start_date= models.DateTimeField(auto_now_add=True)

end_date= models.DateTimeField(blank=True,null=True)def __str__(self):return "%s-%s" %(self.account,self.host_user_bind)classAccount(models.Model):"""堡垒机账户

1. 扩展

2. 继承

user.account.host_user_bind"""user=models.OneToOneField(User)

name= models.CharField(max_length=64)

host_user_binds= models.ManyToManyField("HostUserBind",blank=True)

host_groups= models.ManyToManyField("HostGroup",blank=True)

model.py

__author__ = 'Administrator'

importsubprocess,random,stringfrom django.contrib.auth importauthenticatefrom django.conf importsettingsfrom audit importmodelsfrom audit.backend importssh_interactiveclassUserShell(object):"""用户登录堡垒机后的shell"""

def __init__(self,sys_argv):

self.sys_argv=sys_argv

self.user=Nonedefauth(self):

count=0while count < 3:

username= input("username:").strip()

password= input("password:").strip()

user= authenticate(username=username,password=password)#None 代表认证不成功

#user object ,认证对象 ,user.name

if notuser:

count+= 1

print("Invalid username or password!")else:

self.user=userreturnTrueelse:print("too many attempts.")defstart(self):"""启动交互程序"""

ifself.auth():#print(self.user.account.host_user_binds.all()) #select_related()

whileTrue:

host_groups=self.user.account.host_groups.all()for index,group inenumerate(host_groups):print("%s.\t%s[%s]"%(index,group,group.host_user_binds.count()))print("%s.\t未分组机器[%s]"%(len(host_groups),self.user.account.host_user_binds.count()))try:

choice= input("select group>:").strip()ifchoice.isdigit():

choice=int(choice)

host_bind_list=Noneif choice >=0 and choice

selected_group=host_groups[choice]

host_bind_list=selected_group.host_user_binds.all()elif choice == len(host_groups): #选择的未分组机器

#selected_group = self.user.account.host_user_binds.all()

host_bind_list =self.user.account.host_user_binds.all()ifhost_bind_list:whileTrue:for index,host inenumerate(host_bind_list):print("%s.\t%s"%(index,host,))

choice2= input("select host>:").strip()ifchoice2.isdigit():

choice2=int(choice2)if choice2 >=0 and choice2

selected_host=host_bind_list[choice2]

ssh_interactive.ssh_session(selected_host,self.user)#s = string.ascii_lowercase +string.digits

#random_tag = ''.join(random.sample(s,10))

#session_obj = models.SessionLog.objects.create(account=self.user.account,host_user_bind=selected_host)

# #cmd = "sshpass -p %s /usr/local/openssh/bin/ssh %s@%s -p %s -o StrictHostKeyChecking=no -Z %s" %(selected_host.host_user.password,selected_host.host_user.username,selected_host.host.ip_addr,selected_host.host.port ,random_tag)

##start strace ,and sleep 1 random_tag, session_obj.id

#session_tracker_script = "/bin/sh %s %s %s " %(settings.SESSION_TRACKER_SCRIPT,random_tag,session_obj.id)

# #session_tracker_obj =subprocess.Popen(session_tracker_script, shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

# #ssh_channel = subprocess.run(cmd,shell=True)

#print(session_tracker_obj.stdout.read(), session_tracker_obj.stderr.read())

# elif choice2 == 'b':break

exceptKeyboardInterrupt as e :pass

user_interactive.py

#!/usr/bin/env python

#Copyright (C) 2003-2007 Robey Pointer #

#This file is part of paramiko.#

#Paramiko is free software; you can redistribute it and/or modify it under the#terms of the GNU Lesser General Public License as published by the Free#Software Foundation; either version 2.1 of the License, or (at your option)#any later version.#

#Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY#WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR#A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more#details.#

#You should have received a copy of the GNU Lesser General Public License#along with Paramiko; if not, write to the Free Software Foundation, Inc.,#59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

importbase64from binascii importhexlifyimportgetpassimportosimportselectimportsocketimportsysimporttimeimporttracebackfrom paramiko.py3compat importinputfrom audit importmodelsimportparamikotry:importinteractiveexceptImportError:from . importinteractivedefmanual_auth(t, username, password):#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

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

#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, password)defssh_session(bind_host_user, user_obj):#now connect

hostname = bind_host_user.host.ip_addr #自动输入 主机名

port = bind_host_user.host.port #端口

username =bind_host_user.host_user.username

password=bind_host_user.host_user.passwordtry:

sock= socket.socket(socket.AF_INET, socket.SOCK_STREAM) #生成socket连接

sock.connect((hostname, port))exceptException as e:print('*** Connect failed:' +str(e))

traceback.print_exc()

sys.exit(1)try:

t= paramiko.Transport(sock) #使用paramiko的方法去连接服务器执行命令!

try:

t.start_client()exceptparamiko.SSHException:print('*** SSH negotiation failed.')

sys.exit(1)try:

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

keys= paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))exceptIOError:print('*** Unable to open host keys file')

keys={}#check server's host key -- this is important.

key =t.get_remote_server_key()if hostname not inkeys:print('*** WARNING: Unknown host key!')elif key.get_name() not inkeys[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 nott.is_authenticated():

manual_auth(t, username, password)#密码校验

if nott.is_authenticated():print('*** Authentication failed. :(')

t.close()

sys.exit(1)

chan=t.open_session()

chan.get_pty()#terminal

chan.invoke_shell()print('*** Here we go!\n')

session_obj= models.SessionLog.objects.create(account=user_obj.account,

host_user_bind=bind_host_user)

interactive.interactive_shell(chan, session_obj)#开始进入交换模式·

chan.close()

t.close()exceptException as e:print('*** Caught exception:' + str(e.__class__) + ':' +str(e))

traceback.print_exc()try:

t.close()except:passsys.exit(1)

ssh_interactive.py

#Copyright (C) 2003-2007 Robey Pointer #

#This file is part of paramiko.#

#Paramiko is free software; you can redistribute it and/or modify it under the#terms of the GNU Lesser General Public License as published by the Free#Software Foundation; either version 2.1 of the License, or (at your option)#any later version.#

#Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY#WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR#A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more#details.#

#You should have received a copy of the GNU Lesser General Public License#along with Paramiko; if not, write to the Free Software Foundation, Inc.,#59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

importsocketimportsysfrom paramiko.py3compat importufrom audit importmodels#windows does not have termios...

try:importtermiosimporttty

has_termios=TrueexceptImportError:

has_termios=Falsedefinteractive_shell(chan,session_obj):if has_termios: # posix_shell(chan,session_obj) #unix 通用协议标准

else:

windows_shell(chan)defposix_shell(chan,session_obj):importselect

oldtty=termios.tcgetattr(sys.stdin)try:

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

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

chan.settimeout(0.0)

flag=False

cmd= ''

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

if flag: #如果用户输入的Tab补全,服务器端返回

cmd +=x

flag=False

sys.stdout.write(x)

sys.stdout.flush()exceptsocket.timeout:pass

if sys.stdin in r: #本地输入

x = sys.stdin.read(1) #输入1个字符就发送远程服务器

if len(x) ==0:break

if x == '\r': #回车·

models.AuditLog.objects.create(session=session_obj,cmd=cmd)

cmd= ''

elif x == '\t':#tab 本地1个字符+远程返回的

flag =Trueelse:

cmd+=x

chan.send(x)#发送本地输入 到远程服务器

finally:

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)#thanks to Mike Looijmans for this code

defwindows_shell(chan):importthreading

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

data= sock.recv(256)if notdata:

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

sys.stdout.flush()breaksys.stdout.write(data)

sys.stdout.flush()

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

writer.start()try:whileTrue:

d= sys.stdin.read(1)if notd:breakchan.send(d)exceptEOFError:#user hit ^Z or F6

pass

interactive.py

程序流程:用户界面---------->ssh自动输入用户&登录密码---------->进入shell命令交互模式

知识点:

1对1:      1个 对应  1个   (1个女人嫁给了1个男人,生活慢慢平淡下来,)

1对多:      1个 对应  N个   (这个女人隐瞒丈夫相继出轨了N个男人,这个男人发现老婆出轨了,很愤懑)

多对多:     双方都存在1对多关系 (也相继找了N个女情人,而这些女情人中就有他老婆出轨男人的老婆,故事结束。)

感悟:

这个故事很混乱! 怎么设计男、女表结构?  其实在做数据库表关系设计的时候,纠结2张表到底需要设计成什么关系?到不如加几张关系绑定表!

完全是出于  你的程序在允许的过程中到底 要向用户展示什么信息? 而决定的!

web页面使用堡垒机方式:

web开发模式

1.MTV/MVC 前后端杂交模式;(面向公司内部OA)

优势:简单,一人全栈;

缺陷:前后端耦合性高,性能低、单点压力

2.前后端分离(面向大众用户)

优势:前、后端开发人员商定好接口和数据格式,并行开发,效率高;解决了后端独自渲染模板的压力;

缺陷:招前端得花钱

3.hostlist 展示主机组和主机

主机组

你可能感兴趣的:(python批量上传执行脚本)