YaYaTang

知识参鉴: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、实现过程

..

分类:

技术点:

相关文章:

  • 2021-11-18
  • 2021-11-18
  • 2021-11-18
  • 2021-11-18
  • 2021-11-18
  • 2022-12-23
猜你喜欢
  • 2021-11-29
  • 2021-11-18
  • 2022-01-29
  • 2021-11-18
  • 2021-11-18
  • 2022-12-23
  • 2021-11-29
相关资源
相似解决方案