1. 需求分析
1、 实际开发中,运维团队与 IDC 机房是分开的,即有专门的放置服务器服务器的机房(称为 IDC 机房)。因此运维人员只能远程连接操作服务器
2、 开发人员开发出一款软件经测试之后,交给运维人员,然后再远程将程序上线到服务器中
3、 一般一个公司会有很多 “业务线”,如:广告线、电商、等,不同的业务线一般也会配备多个运维人员,当一个运维休息时,另一个则接管
4、 运维人员以 SSH 方式连接远程服务器,服务器要防火墙策略来识别该 IP 是否安全,这样就需要给每台服务器设置防火墙策略,太过繁琐
5、 实际运维是以 VPN(虚拟专用网络,会形成一个安全隧道,供运维人员使用),它不受时间和地点的限制,即使不在公司,只要进入虚拟专用网络即可进入。
6、 人为因素导致的安全隐患:
- 假如同一条业务线上的几个运维人员A和B,他们都有操作服务器的权限(即知道这台服务器的账户密码)。
- 若A与B之间有矛盾,B 打算陷害A。他在休假前,在服务器中写了一个脚本程序(引发服务器某个错误),并且设置好定时任务(并清除痕迹)。
- 当A值班时,到时间脚本执行,服务器出现错误。不管A是否登录服务器,A都要负主要责任,然而这是B搞的鬼。
因此就需要有一个系统或程序来记录操作服务器的人员、时间、地点等,任何对服务器的操作,都要经过此程序记录(一般上市公司都会定期检查类似这种记录)。
7、 这个程序就是“堡垒机”,在运维人员与服务器之间有一台特殊的服务器(堡垒机),运维人员要想操作服务器就需要经过堡垒机,它会将所有操作都记录下来,并保存在堡垒机上。
堡垒机特点,包括但不限于:
- 它可以保存服务器的账户和密码,运维人员连接某台服务器时,不需要再手动输入账户密码,只需提供主机名即可。因为堡垒机上存储有服务器的登录账户、主机信息等。
- 记录操作服务器的账户(即运维人员)、时间、以及对服务器有哪些操作等,这在一定程度上提高了服务器的安全性。
- 允许用户对不同的目标设备有不同的访问权限,如:10.0.2.34 有mysql 用户的权限,192.168.3.22 有root用户的权限等
- 分组管理,即可以对设置进行分组,允许用户访问某组机器,但对组里的不同机器依然有不同的访问权限
- 堡垒机也是一台服务器,但是它是一台特殊的服务器,运维人员需要事先登录堡垒机,才能操作服务器。
2. 堡垒机架构
主要作用是权限控制和用户行为审计,所有的用户操作服务器都必须经过堡垒机,所有人的足迹都会有记录下来(不管是否愿意)。
不同的用户有不同的权限,能够操作服务器的范围也是有区别的,如:
- 运维:服务器的所有权限
- DBI:只能操作数据库
- Web:只能查看或其他权限等
3. 登录服务器的两种方式
3.1 密码形式登录
客户端通过 xshell
(SSH 形式),连接远程服务器,需要知道服务器:主机名、 账号、密码
3.2 SSH key(公钥)
当有很多服务器,而又不想使用密码登录,且较为安全。那么可以在客户端生成公钥,再将其 copy 到目标服务器上,进行相应的配置即可登录到目标服务器上。
1、 概述:
两个 Linux 机器之间使用 SSH 不需要用户名、密码,而是采用数字签名 RSA 或 DSA 来完成
2、 模型分析
- 客户机:192.168.20.59
- 目标机:192.168.20.60
3、 实现的目标
A 连接B,无需密码,加密方式使用 RSA 或 DSA 皆可,默认DSA
1、登录A机器,使用命令:ssh-keygen -t [rsa|dsa],生成公钥(id_rsa.pub)和私钥(id_rsa)
2、将公钥复制到 B 中的 .ssh 目录,(scp -rp id_rsa.pub 192.168.20.60:/home/xxx/)
3、将 id_rsa..pub 重命名为 authorized_keys,或直接内容覆盖(cat id_rsa.pub > authorized_keys),没有authorized_keys文件,就新建一个。
4、登录 B,直接运行 ssh 192.168.20.60 即可。
5、若失败,则要看看 authorized_keys 和 .ssh 权限,要保证用户自己有写权限。
Chmod 600 authorized_keys,chmod 700 -R.ssh
其他命令:
1. 把远程文件 copy 到本地
scp -rp alex@192.168.10.35:/home/alex/id_rsa /tmp/
2. 查看当前用户 id:whoami
3. 没有 .ssh 文件夹时,可以退出当前登录用户,再重新用 .ssh 登录下别的用户,再退出 exit就会生成 .ssh 文件夹
参考博客:https://blog.csdn.net/kongqz/article/details/6338690
4. Paramiko 模块
堡垒机基于 Python 第三方模块 Paramiko 实现,Paramiko 基于SSH 用于连接远程服务器并执行相关操作。
安装:
pip3 install paramiko
4.1 SSHClient
基于用户名和密码连接
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.21.128', port=22, username='hj', password='1xxx9')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls')
# 获取命令结果
result = stdout.read()
print(str(result, encoding='utf-8'))
# 关闭连接
ssh.close()
运行过程中报错:
hm.add_string(self.Q_C.public_numbers().encode_point())
原因:paramiko
依赖的 cryptography
,在新的版本中有一些 API
被弃用了
解决办法:
pip uninstall cryptography==2.5
pip install cryptography==2.4.2
参考博客:Python 使用 paramiko CryptographyDeprecationWarning 报警处理
SSHClient 封装 Transport:
import paramiko
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', password='123')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
print(stdout.read())
transport.close()
基于公钥密钥连接
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/hj/.ssh/id_rsa.pub')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.21.128', port=22, username='hj', key=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
print(result)
# 关闭连接
ssh.close()
SSHClient 封装 Transport:
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
transport.close()
4.2 SFTPClient
用于连接远程服务器并执行上传下载.
基于用户名密码上传下载:
import paramiko
transport = paramiko.Transport(('192.168.21.128', 22))
transport.connect(username='hj', password='xxx39')
sftp = paramiko.SFTPClient.from_transport(transport)
# 将 1.jpg 上传至服务器 /tmp/1.jpg
sftp.put('C:\Users\hj\Desktop\1.jpg', '/tmp/1.jpg')
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
基于公钥密钥上传下载:
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key )
sftp = paramiko.SFTPClient.from_transport(transport)
# 将 1.jpg 上传至服务器 /tmp/1.jpg
sftp.put('C:\Users\hj\Desktop\1.jpg', '/tmp/1.jpg')
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
4.3 示例
基于用户名和密码实现连接远程服务器,并执行相关命令操作以及上传下载文件:
import paramiko
import uuid
class SSHConnection(object):
def __init__(self, host='192.168.21.128', port=22, username='hj', pwd='abcd110139'):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None
def run(self):
self.connect()
pass
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 cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 获取命令结果
result = stdout.read()
return result
def upload(self,local_path, target_path):
# 连接,上传
sftp = paramiko.SFTPClient.from_transport(self.__transport)
# 将 1.jpg 上传至服务器 /home/hj/桌面/1.jpg
sftp.put(local_path, target_path)
ssh = SSHConnection()
ssh.connect()
r1 = ssh.cmd('df')
ssh.upload('1.jpg', "/home/hj/桌面/1.jpg")
ssh.close()
5. 模型设计
1、命令行模式:
2、批量命令:
2、批量文件上传及下载操作:
源码:https://github.com/hj1933/FortressMachine
6. 相关知识
6.1 Linux 中 .bashrc 文件
利用 Linux 系统启动时会加载执行 .bashrc
文件这一特性,我们可以将其设置为当用户开启堡垒机服务器时,就执行堡垒机中的一个脚本文件。
好处就是用户只能使用堡垒机,而不能修改堡垒机,用户的一切行为都将被记录下来。
sudo vim /home/hj/.bashrc
# 在最后添加两句后保存
echo '这句话开机就会启动' # 打印输出
python3 /home/hj/test.py # 执行 test.py 这个脚本
# 堡垒机执行脚本
# python3 FortressMachine/crazyeye_manage.py run
# logout # 当按下 Ctrl+C 终端脚本时,中断连接
连接堡垒机时启动相关脚本文件:
6.2 shellinabox
在上面我们都是以终端形式操控堡垒机,如果我们想以 Web 页面形式操控堡垒机可以使用 shellinabox
shellinbox 有一个内建的 web server作为基本的web ssh client,允许你通过指定的端口访问 Linux 服务器的 ssh shell,只要你的浏览器支持 AJAX/JS/CSS就可以访问,不需要额外的浏览器插件,十分的简单操作,软件轻量级,不过服务端需要 openssl 支持,debian和 ubuntu 官方还提供有 deb,centos也有 rpm包。
下载安装
# On Debian, Ubuntu and Linux Mint
$ sudo apt-cache search shellinabox
$ sudo apt-get install openssl shellinabox
# On RHEL, CentOS and Fedora
yum install openssl shellinabox
CentOS 部分系统可能找不到 shellinaboxd
包,可手动下载 rpm
包安装(找到适合自己系统版本的 rpm 包):
rpm 安装 shellinabox
:
yum install -y shellinabox-2.20-5.el7.x86_64.rpm
查看安装了哪些文件及安装位置命令:
[root@hj 桌面]# rpm -ql shellinabox
/etc/sysconfig/shellinaboxd
/usr/lib/systemd/system/shellinaboxd.service
/usr/sbin/shellinaboxd
/usr/share/doc/shellinabox-2.20
/usr/share/doc/shellinabox-2.20/AUTHORS
/usr/share/doc/shellinabox-2.20/NEWS
/usr/share/doc/shellinabox-2.20/README
/usr/share/doc/shellinabox-2.20/README.Fedora
/usr/share/doc/shellinabox-2.20/print-styles.css
/usr/share/doc/shellinabox-2.20/shell_in_a_box.js
/usr/share/doc/shellinabox-2.20/styles.css
/usr/share/man/man1/shellinaboxd.1.gz
/usr/share/shellinabox
/usr/share/shellinabox/color.css
/usr/share/shellinabox/monochrome.css
/usr/share/shellinabox/white-on-black.css
/var/lib/shellinabox
配置 shellinabox
编辑 /etc/sysconfig/shellinaboxd
,更改端口(默认 4200)及添加远程访问地址:
# Basic options
USER=shellinabox
GROUP=shellinabox
CERTDIR=/var/lib/shellinabox
PORT=4200 # 端口,可不更改
OPTS="--disable-ssl-menu -s /:LOGIN"
# Additional examples with custom options:
# Fancy configuration with right-click menu choice for black-on-white:
# OPTS="--user-css Normal:+black-on-white.css,Reverse:-white-on-black.css --disable-ssl-menu -s /:LOGIN"
# Simple configuration for running it as an SSH console with SSL disabled:
# OPTS="-t -s /:SSH:host.example.com"
OPTS="-t -s /:SSH:192.168.21.129" # 远程地址
在这里只是做简单的配置,更多配置可参考 :<https://github.com/shellinabox/shellinabox>
如果要外网访问,那么还需要配置防火墙,允许 shellinabox
端口通过:
$ sudo vim /etc/sysconfig/iptables
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 4200 -j ACCEPT # 添加这一行,需添加在 22 端口下面
-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 4200 -j ACCEPT
重启 iptables
服务:service iptables restart
。启动 shellinabox
服务:service shellinaboxd start
。
查看是否启动:
现在我们就可以在 Windows 上访问 Linux 了,访问:<http://192.168.21.129:4200/>
:
参考文章: