Python【09】【网络编程】- 堡垒机及数据库操作

知识参鉴:Mr.7

堡垒机实现原理

堡垒机中用于与客户端与服务端交互的过程是由paramiko模块来实现,paramiko提供了客户端与服务器的功能

1、paramiko-SSHClient

SSHClient用于在客户端远程连接服务端进行操作,实现基础的远程命令。

(1)基于用户名密码:

#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko

# 定义一个SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接主机
ssh.connect(hostname='10.0.7.4', port=2369, username='tom', password='xxx')
# 执行命令
stdin, stdout ,stderr = ssh.exec_command('ls')
# 返回内容
result = stdout.read()
print result
# 关闭连接
ssh.close()
#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko

transport = paramiko.Transport(('10.0.7.4', 2369))
transport.connect(username='tom', password='xxx')

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()

transport.close()
SSHClient 封装 Transport

(2)基于公钥私钥:

#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file('/home/king/.ssh/id_rsa')
 
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='10.0.7.4', port=2369, username='tom', key=private_key)
 
# 执行命令
stdin, stdout, stderr = ssh.exec_command('who')
# 获取命令结果
result = stdout.read()
print result 
# 关闭连接
ssh.close()
#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/home/tom/.ssh/id_rsa')

transport = paramiko.Transport(('10.0.7.4', 2369))
transport.connect(username='tom', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('who')

transport.close()
SSHClient 封装 Transport

2、paramiko-SFTPClient

SFTPClient用于连接远服务器上传下载文件

(1)基于用户名密码:

#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko

transport = paramiko.Transport(('10.0.7.4', 2369))
transport.connect(username='tom', password='xxx')


sftp = paramiko.SFTPClient.from_transport(transport)
"""
        :argument:(cls, t, window_size=None, max_packet_size=None)

        Create an SFTP client channel from an open `.Transport`.

"""
# 将本地的1212.jpg 上传到服务端
sftp.put('/data/1212.jgp', '/home/tom/')
# 将服务端的1212.jpg下载到本地
sftp.get('/home/tom/1212.jpg', '/data1')

transport.close()

(2)基于公钥私钥:

#!/usr/bin/env python
# coding:utf-8
__author__ = "King"

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/home/king/.ssh/id_rsa')

transport = paramiko.Transport(('10.0.7.4', 2369))
transport.connect(username='tom', pkey=private_key)

sftp = paramiko.SFTPClient.from_transport(transport)
"""
        :argument:(cls, t, window_size=None, max_packet_size=None)

        Create an SFTP client channel from an open `.Transport`.

"""
# 将本地的1212.jpg 上传到服务端
sftp.put('/data/1212.jgp', '/home/tom/')
# 将服务端的1212.jpg下载到本地
sftp.get('/home/tom/1212.jpg', '/data1')

transport.close()

(3)应用实例

#!/usr/bin/env python
# coding:utf-8
__author__ = "king"

import paramiko
import uuid

class UPfile(object):

    def __init__(self):
        self.host = '10.0.7.4'
        self.port = 2369
        self.username = 'tom'
        self.pwd = 'xxx'
        self.__k = None

    def create_file(self):
        file_name = str(uuid.uuid4())
        with open(file_name,'w') as f:
            f.write('hello girls')
        return file_name

    def run(self):
        self.connect()
        self.upload()
        # self.rename()
        self.close()

    def connect(self):
        transport = paramiko.Transport((self.host,self.port))
        transport.connect(username=self.username,password=self.pwd)
        self.__transport = transport

    def close(self):

        self.__transport.close()

    def upload(self):
        # 连接,上传
        file_name = self.create_file()

        sftp = paramiko.SFTPClient.from_transport(self.__transport)
        # 将location.py 上传至服务器 /tmp/test.py
        sftp.put(file_name, '/home/tom/file.py')

    def rename(self):

        ssh = paramiko.SSHClient()
        ssh._transport = self.__transport
        # 执行命令
        stdin, stdout, stderr = ssh.exec_command('mv /home/tom/file.py /home/tom/.py')
        # 获取命令结果
        result = stdout.read()


ha = UPfile()
ha.run()

Mysql数据库的基本操作

python 的 mysql 模块安装,用于操作mysql数据库

linux:
    yum install MySQL-python
 
window:
    https://files.cnblogs.com/files/wupeiqi/py-mysql-win.zip

1、SQL的基础操作

(1)数据库安装

# 0.1 下载
wget https:// downloads.mariadb.com/archives/mysql-5.5/mysql-5.5.32-linux2.6-x86_64.tar.gz
# 0.2 创建用户及用户组
groupadd -r mysql
useradd -r -g mysql -M -s /sbin/nologin mysql
# 0.3 创建数据目录并设定目录权限
mkdir -p /app/mysql_data/
chown -R mysql.mysql /app/mysql_data/
# 0.4 解压安装包到指定目录
tar zxvf mysql-5.5.32-linux2.6-x86_64.tar.gz -C /app
ln -sv /app/mysql-5.5.32-linux2.6-x86_64/ /app/mysql
chown -R mysql.mysql /app/mysql-5.5.32-linux2.6-x86_64/
# 0.5 初始化配置文件
cd /app/mysql
./scripts/mysql_install_db --user=mysql --basedir=/app/mysql --datadir=/app/mysql_data
# 0.6 复制启动文件与配置文件
cp support-files/mysql.server /etc/init.d/mysqld
cp support-files/my-small.cnf /etc/my.cnf
# 0.7 添加到环境变量
echo "PATH=/app/mysql/bin:$PATH" >> /etc/profile
tail -1 /etc/profile
source /etc/profile
# 0.8 启停服务
/etc/init.d/mysqld start|stop
chkconfig --level 35 mysqld on

(2)数据库操作

mysql> show databases;
mysql> use test;
mysql> create database test;
mysql> drop database test;

(3)数据表操作

mysql> show tables;
mysql> create table students
    (
        id int  not null auto_increment primary key,
        name char(8) not null,
        sex char(4) not null,
        age tinyint unsigned not null,
        tel char(13) null default "-"
    );
mysql> drop table students;

# or

CREATE TABLE `www_x` ( 
    `id` smallint(8) unsigned NOT NULL, 
    `catid` smallint(5) unsigned NOT NULL DEFAULT '0', 
    `title` varchar(80) NOT NULL DEFAULT '', 
    `content` text NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `catename` (`catid`) 
) ;

(4)数据操作

mysql> insert into test.students(name,sex,age,tel) values('tom','man',18,'88881234')
mysql> delete from test.students where id =2;
mysql> update test.students set name = 'sb' where id =1;
mysql> select name,age from test.students

(5)其它知识点

主键 ( primary key )  

能够唯一标识表中某一行的属性或属性组。一个表只能有一个主键,但可以有多个候选索引。主键常常与外键构成参照完整性约束,防止出现数据不一致。主键可以保证记录的唯一和主键域非空,数据库管理系统对于主键自动生成唯一索引,所以主键也是一个特殊的索引。

外键(foreign key)   

是用于建立和加强两个表数据之间的链接的一列或多列。外键约束主要用来维护两个表之间数据的一致性。简言之,表的外键就是另一表的主键,外键将两表联系起来。一般情况下,要删除一张表中的主键必须首先要确保其它表中的没有相同外键(即该表中的主键没有一个外键和它相关联)。

索引 ( index )   

是用来快速地寻找那些具有特定值的记录。主要是为了检索的方便,是为了加快访问速度, 按一定的规则创建的,一般起到排序作用。所谓唯一性索引,这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。

总结:
主键一定是唯一性索引,唯一性索引并不一定就是主键。
一个表中可以有多个唯一性索引,但只能有一个主键。
主键列不允许空值,而唯一性索引列允许空值。
主键可以被其他字段作外键引用,而索引不能作为外键引用。

内联接

典型的联接运算,使用像 =  或 <> 之类的比较运算符。
包括相等联接和自然联接。    
内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索 students和courses表中学生标识号相同的所有行。  

外联接

外联接可以是左向外联接、右向外联接或完整外部联接。    
在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:    
LEFT  JOIN或LEFT OUTER JOIN  
左向外联接的结果集包括  LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。   
RIGHT  JOIN 或 RIGHT  OUTER  JOIN    
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。      
FULL  JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

交叉联接

交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。
FROM 子句中的表或视图可通过内联接或完整外部联接按任意顺序指定;但是,用左或右向外联接指定表或视图时,表或视图的顺序很重要。

2、Python MySQL API

(1)插入数据

import MySQLdb
  
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb')
  
cur = conn.cursor()
  
reCount = cur.execute('insert into UserInfo(Name,Address) values(%s,%s)',('alex','usa'))
# reCount = cur.execute('insert into UserInfo(Name,Address) values(%(id)s, %(name)s)',{'id':12345,'name':'wupeiqi'})
  
conn.commit()
  
cur.close()
conn.close()
  
print reCount


# 批量添加数据

import MySQLdb

conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb')

cur = conn.cursor()

li =[
     ('alex','usa'),
     ('sb','usa'),
]
reCount = cur.executemany('insert into UserInfo(Name,Address) values(%s,%s)',li)

conn.commit()
cur.close()
conn.close()

print reCount

(2)删除数据

import MySQLdb
 
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb')
 
cur = conn.cursor()
 
reCount = cur.execute('delete from UserInfo')
 
conn.commit()
 
cur.close()
conn.close()
 
print reCount

(3)查询数据

# ############################## fetchone/fetchmany(num)  ##############################
 
import MySQLdb
 
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb')
cur = conn.cursor()
 
reCount = cur.execute('select * from UserInfo')
 
print cur.fetchone()
print cur.fetchone()
cur.scroll(-1,mode='relative')
print cur.fetchone()
print cur.fetchone()
cur.scroll(0,mode='absolute')
print cur.fetchone()
print cur.fetchone()
 
cur.close()
conn.close()
 
print reCount
 
 
 
# ############################## fetchall  ##############################
 
import MySQLdb
 
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb')
#cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
cur = conn.cursor()
 
reCount = cur.execute('select Name,Address from UserInfo')
 
nRet = cur.fetchall()
 
cur.close()
conn.close()
 
print reCount
print nRet
for i in nRet:
    print i[0],i[1]

堡垒机的实现过程

1、思路 Light bulbLight bulb

绘图1

(1)堡垒机在架构中的位置与作用

堡垒机在企业应用中是可ssh登录到堡垒保护的内部网络中的入口,它表面的作用如同小区的保卫科,出入者登记,但深层的作用还可以是物业,指定哪片地是你可以胡作非为的。

它在可实现用户跳板登录到真实服务器,可作用户权限、审计控制,可记录用户操作过程

(2)可实现的功能点

jump

流程应该是这样的:

1、管理员创建用户,分配用户可登录的主机或主机组、分配用户可执行的sudo权限

2、用户登录跳板机,查看可操作的主机,登录可操作的主机,上传下载文件,退出

3、用户登录主机,可执行授予的权限

(3)别人家是怎么实现的

crazyeye : 作者:alex,用户体验为负数,我喜欢docker版

jumpserver : 作者:一堆小心眼的程序员,我在群了提出了改进意见,第二天就把我给删了,难道我说错了….

2、实现过程

..

posted @ 2016-01-12 16:58  YaYaTang  阅读(407)  评论(0编辑  收藏  举报