金山云云服务器访问控制和操作审计

金山云云服务器访问控制和操作审计

公有云给用户不仅仅带来弹性和按量计费的资源,也提供了在任何地方操作和使用资源的灵活性。但是,为了保证用户在云上环境的安全性,避免环境管理混乱,需要对云资源的操作和访问进行严格的访问控制和操作审计。

为了达到这一目标,用户可以采用专业的堡垒机软件,也可以通过利用Linux操作系统,并结合云网络的特性来实现。本文介绍如何利用金山云的云网络能力,并通过配置Linux系统来实现堡垒机功能,提高对金山云云服务器的访问控制和操作审计,并实现如下需求:

  • 只有堡垒机具有公网IP,其他云服务器不能具有公网IP;
  • 所有云服务器操作必须先登录到堡垒机,然后通过堡垒机再SSH到其他云服务器,而且不能从一台应用服务器SSH到另外一台应用服务器;
  • 所有用户登录堡垒机必须采用密钥登录,不能采用口令登录;
  • 非root用户登录到堡垒机后,只能查看该用户到进程信息,不能查看其他用户的进程信息;
  • 所有在堡垒机上执行的shell命令将被记录用于后期审计;
  • 应用服务器能访问Linux yum源和金山云短信服务:https://ksms.api.ksyun.com,但不能访问其他服务;
  • 应用服务器提供的Web服务只能通过负载均衡提供的弹性IP访问。

本方案的整体架构描述如下图:

金山云云服务器堡垒机部署架构

本文包含如下内容:

  • 网络规划;
  • 准备云服务器;
  • 配置堡垒机;
  • 配置应用服务器;
  • 验证访问控制和审计。

1 网络规划

本指南所使用的环境位于金山云北京6区。

1.1 VPC配置

网络资源名称CIDR
VPCsbt-vpc10.34.0.0/16

1.2 子网配置

子网名称所属VPC可用区子网类型CIDR说明
public_asbt-vpc可用区A普通子网10.34.51.0/24用于堡垒机
private_asbt-vpc可用区A普通子网10.34.0.0/20用于云服务器

1.3 安全组配置

需要注意到是,同安全组下的服务器是直接互通的,无需进行相关设置。

作为实验环境,创建安全组sg-bastion和sg-app,其中绑定sg-bastion的云服务器可以被外网ping通,以及通过ssh访问。sg-bastion的入站规则如下:

协议行为起始端口结束端口源IP
ICMP允许全部协议全部协议0.0.0.0/0
TCP允许22220.0.0.0/0

sg-bastion的出站规则采用如下默认设置:

协议行为起始端口结束端口源IP
IP允许--0.0.0.0/0
TCP允许22220.0.0.0/0

安全组sg-app将绑定到应用服务器上。应用服务器可以被外部访问80端口(提供HTTP服务),并可接受来自于堡垒机(堡垒机的内部IP为10.34.32.21)的SSH请求,同时也可以被其他云服务器ping通。因此,sg-app的入站规则如下:

协议行为起始端口结束端口源IP
ICMP允许全部协议全部协议0.0.0.0/0
TCP允许2222110.34.32.21/32
HTTP允许80800.0.0.0/0

安全组sg-app的出站规则采用和sg-bastion相同出站规则。

1.3 网络ACL配置

需要注意的是,同一个子网内的主机不受关联的ACL策略控制,因此不能通过网络ACL配置,限制同一子网的云服务器之间相互SSH登录。

应用服务器不能被外网访问,但可以通过公网NAT访问外网服务(120.92.15.230是金山云短信服务域名ksms.api.ksyun.com的IP地址)。为了限制所能访问的外网服务,将为应用服务器所在的私有子网private_a(10.34.0.0/20)绑定一个网络ACL。该网络ACL的入站规则配置如下:

优先级协议行为起始端口结束端口目标IP备注
100IP允许--0.0.0.0/0可接受任意包

出站规则配置如下:

优先级协议行为起始端口结束端口目标IP备注
100IP允许--10.34.0.0/16可访问VPC中的任意服务
200UDP允许53530.0.0.0/0DNS服务
210ICMP允许全部协议全部协议0.0.0.0/0ping
300TCP允许8080219.216.128.25/32neusoft大学yum源
310TCP允许8080198.18.254.30/32金山云yum源
320TCP允许8080216.176.179.218/32mirrorlist-centos-org
400TCP允许443443120.92.15.230/32金山云短信服务
500IP拒绝--0.0.0.0/0拒绝其他服务

1.4 NAT配置信息

为了私有云子网的云服务器能访问外网服务(比如金山云短信服务),因此需要配置公网NAT实例。下面是NAT实例的配置信息。

名称所属VPC作用范围类型所绑定的子网
Ksc_Natsbt-vpc绑定的子网公网private_a

1.5 负载均衡配置

负载均衡名称IP版本状态网络类型所属项目VPC实例名弹性IP
ymq-slb001IPv4开启公网SBTsbt-vpc120.131.1.39

在该负载均衡实例下创建侦听器。此外,如果需要限制某些客户端访问,可以通过绑定ACL,实现对某些IP地址的封禁。

金山云云服务器堡垒机部署架构

下面是用于绑定到负载均衡实例侦听器上的网络ACL acl-slb,当前配置的规则是不限制任何访问IP。acl-slb的入站规则如下(负载均衡服务下创建的访问控制ACL无需定义出站规则)。

优先级协议行为起始端口结束端口目标IP备注
100IP允许--0.0.0.0/0可接受任意包

2 准备云服务器

金山云的云服务器可以非为全云盘(系统盘和数据盘都是云硬盘)和非全云盘两大类。全云盘服务器提供了更好的SLA,而非全云盘服务器可以充分利用本地盘的磁盘能力。
为了提高堡垒机的可用性,建议采用全云盘服务器。此外,该服务器将绑定一个弹性IP。为了避免被云服务器SSH账户密码被暴力破解,禁用口令登录,而采用SSH密钥登录。下面是堡垒机云服务器的配置信息

名称类型所属于VPC所属子网配置IPV4地址安全组操作系统登录方式弹性IP
ymq-bastion通用型N3sbt-vpcpublic_a2核8G10.34.32.21sg-bastionCentOS Linux release 7.7.1908 (Core)SSH Kkey120.92.42.167

应用服务器位于私有子网,可提供口令登录。下面是一台应用服务器的配置。

名称类型所属于VPC所属子网配置IPV4地址安全组操作系统登录方式
ymq-srv-1通用型N3sbt-vpcprivate_a8核32G10.32.0.2sg-appCentOS Linux release 7.7.1908 (Core)密码

为了对内网IP进行有序管理,建议在创建云服务器时选择手工指定IP,而不选择系统自动分配。

3 配置堡垒机

3.1 配置SSHD配置文件

通过修改配置文件,显示SSH登录后显示的提示,并记录所执行的shell命令,便于后期操作审计。
在创建堡垒机云服务器后,系统信息如下:

[root@ymq-bastion ~]# cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)

从github上获得堡垒机配置脚本。

wget https://raw.githubusercontent.com/ksc-sbt/bastion/master/bastion_bootstrap.sh

然后修改脚本的执行权限:

chmod +x bastion_bootstrap.sh 

然后运行SSHD配置脚本bastion_bootstrap.sh。

[root@ymq-bastion ~]# ./bastion_bootstrap.sh 
checkos Ended
verify_dependencies Ended
Setting up bastion session log in /var/log/bastion/bastion.log
BANNER_PATH = https://raw.githubusercontent.com/ksc-sbt/bastion/master/ssh-banner.txt
Creating Banner in /etc/ssh_banner
curl  -s https://raw.githubusercontent.com/ksc-sbt/bastion/master/ssh-banner.txt > /etc/ssh_banner
[INFO] Installing banner ... 
setup_os Started
setup_os Ended
setup_logs Started
prevent_process_snooping Ended
Bootstrap complete.
[root@ymq-bastion ~]# vi /etc/ssh
ssh/        ssh_banner  
[root@ymq-bastion ~]# vi /etc/ssh/sshd_config 

在重新登录后,将显示如下界面。

michaeldembp-2:~ myang$ ssh -i key/ksyun/ymq-ksyun.pem root@120.92.115.21

###############################################################################
#      _  ___                        __ _      _____ _                 _      # 
#      | |/ (_)                      / _| |    / ____| |               | |    #
#      | ' / _ _ __   __ _ ___  ___ | |_| |_  | |    | | ___  _   _  __| |    #
#      |  < | | '_ \ / _` / __|/ _ \|  _| __| | |    | |/ _ \| | | |/ _` |    #
#      | . \| | | | | (_| \__ \ (_) | | | |_  | |____| | (_) | |_| | (_| |    #
#      |_|\_\_|_| |_|\__, |___/\___/|_|  \__|  \_____|_|\___/ \__,_|\__,_|    #
#                     __/ |                                                   #
#                    |___/                                                    #
#-----------------------------------------------------------------------------#
#                           Authorized access only!                           #
#         Disconnect IMMEDIATELY if you are not an authorized user!!!         #
#                All actions will be monitored and recorded.                  #
###############################################################################
Last login: Sat Oct 12 17:35:39 2019 from 114.255.44.139

此外,通过查看/var/log/bastion/bastion.log,能看到操作信息。

[root@ymq-bastion ~]# tail -f /var/log/bastion/bastion.log 
[ON]:Mon Oct 14 10:25:49 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/root: ssh 10.34.0.3
[ON]:Mon Oct 14 10:26:21 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/root: vi /var/log/bastion/bastion.log 

3.2 配置堡垒机普通用户(user001),并只允许密钥登录

创建user001用户.

[root@ymq-bastion /]# useradd user001
[root@ymq-bastion /]# id user001
uid=1000(user001) gid=1000(user001) groups=1000(user001)

root用户切换到user001用户,并执行ssh-keygen命令生成密钥。

[root@ymq-bastion /]# su - user001
[user001@ymq-bastion ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user001/.ssh/id_rsa): 
Created directory '/home/user001/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/user001/.ssh/id_rsa.
Your public key has been saved in /home/user001/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+wqNDAm5J7z+GGr5ipENVBHjh3tRG7BeMvq5be5eARQ user001@ymq-bastion.ksc.com
The key's randomart image is:
+---[RSA 2048]----+
|   =o..E.        |
|  o.o + o        |
| .oo * +         |
|.. o=.= .        |
|. +o+o  S.       |
| + +oo.o ..      |
|o =  o+ o.       |
|.* o  oo..       |
|+.=o..==...      |
+----[SHA256]-----+
[user001@ymq-bastion ~]$ ls .ssh
id_rsa  id_rsa.pub

密钥生成后会在.ssh目录下创建两个文件,id_rsa和id_rsa.pub,其中id_rsa是私钥,id_rsa.pub这个是公钥。
在.ssh目录下形成authorized_keys文件。

[user001@ymq-bastion ~]$ cd .ssh
[user001@ymq-bastion .ssh]$ cp id_rsa.pub authorized_keys
[user001@ymq-bastion .ssh]$ chmod 600 authorized_keys
[user001@ymq-bastion .ssh]$ 

系统管理员然后把目录下id_rsa文件发送给user001账号对应的用户,并修改文件的访问模式为400。

MichaeldeMacBook-Pro-2:ksyun myang$ chmod 400 user001_id_rsa01
MichaeldeMacBook-Pro-2:ksyun myang$ ls -al user001_id_rsa01
-r--------  1 myang  staff  1675 Oct 14 11:17 user001_id_rsa01

下面用户就可以用user001账号登录堡垒机了。

MichaeldeMacBook-Pro-2:~ myang$ ssh -i key/ksyun/user001_id_rsa01 user001@120.92.115.21

###############################################################################
#      _  ___                        __ _      _____ _                 _      # 
#      | |/ (_)                      / _| |    / ____| |               | |    #
#      | ' / _ _ __   __ _ ___  ___ | |_| |_  | |    | | ___  _   _  __| |    #
#      |  < | | '_ \ / _` / __|/ _ \|  _| __| | |    | |/ _ \| | | |/ _` |    #
#      | . \| | | | | (_| \__ \ (_) | | | |_  | |____| | (_) | |_| | (_| |    #
#      |_|\_\_|_| |_|\__, |___/\___/|_|  \__|  \_____|_|\___/ \__,_|\__,_|    #
#                     __/ |                                                   #
#                    |___/                                                    #
#-----------------------------------------------------------------------------#
#                           Authorized access only!                           #
#         Disconnect IMMEDIATELY if you are not an authorized user!!!         #
#                All actions will be monitored and recorded.                  #
###############################################################################
Last login: Mon Oct 14 10:33:29 2019
[user001@ymq-bastion ~]$ id 
uid=1000(user001) gid=1000(user001) groups=1000(user001)
[user001@ymq-bastion ~]$ 

4 配置应用服务器

为了对所有的ssh登录行为进行审计,应用服务器只允许通过堡垒机进行ssh登录。
修改/etc/hosts.allow,允许从堡垒机(10.34.32.21)上登录。

[root@srv001 ~]# cat /etc/hosts.allow
#
# hosts.allow	This file contains access rules which are used to
#		allow or deny connections to network services that
#		either use the tcp_wrappers library or that have been
#		started through a tcp_wrappers-enabled xinetd.
#
#		See 'man 5 hosts_options' and 'man 5 hosts_access'
#		for information on rule syntax.
#		See 'man tcpd' for information on tcp_wrappers
#
sshd:10.34.32.21:allow

修改/etc/hosts.deny,禁止所有服务器ssh登录。

[root@srv001 ~]# cat /etc/hosts.deny 
#
# hosts.deny	This file contains access rules which are used to
#		deny connections to network services that either use
#		the tcp_wrappers library or that have been
#		started through a tcp_wrappers-enabled xinetd.
#
#		The rules in this file can also be set up in
#		/etc/hosts.allow with a 'deny' option instead.
#
#		See 'man 5 hosts_options' and 'man 5 hosts_access'
#		for information on rule syntax.
#		See 'man tcpd' for information on tcp_wrappers
#
sshd:ALL

然后重新启动sshd服务。

systemctl restart sshd

此时再次从非堡垒机ssh登录,将出现如下提示信息。

[root@ymq-bastion /]# ssh 10.34.0.3
root@10.34.0.3's password: 
Last login: Mon Oct 14 10:08:55 2019 from 10.34.32.21
[root@srv002 ~]# ssh 10.34.0.2
ssh_exchange_identification: read: Connection reset by peer

5 验证访问控制和审计

5.1 只有堡垒机具有公网IP,其他云服务器不能具有公网IP

该功能通过金山云控制台给堡垒机绑定公网IP。如果用户采用金山云访问控制(IAM)服务设置多用户,需要严格控制非系统管理账户的弹性IP创建和修改权限。

5.2 SSH登录限制

所有云服务器操作必须先登录到堡垒机,然后通过堡垒机再SSH到其他云服务器,而且不能从一台应用服务器SSH到另外一台应用服务器。

下面验证能通过堡垒机ssh一台云服务器(10.34.0.3),但不能从该云云服务器(10.34.0.3)ssh到另外一台云服务器(10.34.0.2)。

[root@ymq-bastion ~]# ssh 10.34.0.3
root@10.34.0.3's password: 
Last login: Mon Oct 14 11:57:33 2019 from 10.34.32.21
[root@srv002 ~]# ssh 10.34.0.2 
ssh_exchange_identification: read: Connection reset by peer
[root@srv002 ~]# 

5.3 所有用户登录堡垒机必须采用密钥登录,不能采用口令登录

下面验证如果不带密钥ssh,将提示登录失败。

michaeldembp-2:~ myang$ ssh user001@120.92.115.21

###############################################################################
#      _  ___                        __ _      _____ _                 _      # 
#      | |/ (_)                      / _| |    / ____| |               | |    #
#      | ' / _ _ __   __ _ ___  ___ | |_| |_  | |    | | ___  _   _  __| |    #
#      |  < | | '_ \ / _` / __|/ _ \|  _| __| | |    | |/ _ \| | | |/ _` |    #
#      | . \| | | | | (_| \__ \ (_) | | | |_  | |____| | (_) | |_| | (_| |    #
#      |_|\_\_|_| |_|\__, |___/\___/|_|  \__|  \_____|_|\___/ \__,_|\__,_|    #
#                     __/ |                                                   #
#                    |___/                                                    #
#-----------------------------------------------------------------------------#
#                           Authorized access only!                           #
#         Disconnect IMMEDIATELY if you are not an authorized user!!!         #
#                All actions will be monitored and recorded.                  #
###############################################################################
user001@120.92.115.21: Permission denied (publickey).
michaeldembp-2:~ myang$ 

5.4 非root用户登录到堡垒机后,只能查看该用户到进程信息,不能查看其他用户的进程信息。

[user001@vm10-34-32-21 ~]$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
user001   7702  7701  0 11:23 pts/1    00:00:00 -bash
user001   9329  7702  0 12:03 pts/1    00:00:00 -bash
user001   9332  9329  0 12:03 pts/1    00:00:00 logger -t [ON]:Mon Oct 14 12:03:45 CST 2019   [FROM]:114.255.44.14
user001  10464 10463  0 12:35 pts/3    00:00:00 -bash
user001  10493 10464  0 12:35 pts/3    00:00:00 -bash
user001  10496 10493  0 12:35 pts/3    00:00:00 logger -t [ON]:Mon Oct 14 12:35:16 CST 2019   [FROM]:114.255.44.14
user001  10497 10464  0 12:35 pts/3    00:00:00 ps -ef

5.5 所有在堡垒机上执行的shell命令将被记录用于后期审计

下面是通过root用户查看操作日志文件/var/log/bastion/bastion.log 看到的信息。

[root@vm10-34-32-21 ~]# tail -f /var/log/bastion/bastion.log 
[ON]:Mon Oct 14 11:48:14 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/: ifconfig
[ON]:Mon Oct 14 12:00:22 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: ssh root@10.34.0.2
[ON]:Mon Oct 14 12:00:28 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: curl 120.131.1.39
[ON]:Mon Oct 14 12:02:34 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: ping 120.131.1.39
[ON]:Mon Oct 14 12:03:11 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: curl 120.131.1.39
[ON]:Mon Oct 14 12:03:20 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/root: service firewalld status
[ON]:Mon Oct 14 12:08:51 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/root: ssh 10.34.0.3
[ON]:Mon Oct 14 12:35:03 CST 2019   [FROM]:114.255.44.141   [USER]:root   [PWD]:/root: ssh 10.34.0.2
[ON]:Mon Oct 14 12:35:19 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: ps -ef
[ON]:Mon Oct 14 12:35:48 CST 2019   [FROM]:114.255.44.141   [USER]:user001   [PWD]:/home/user001: tail -f /var/log/bastion/bastion.log 

5.6 应用服务器能访问Linux yum源和金山云短信服务,但不能访问其他服务

应用服务器能访问yum源服务和金山云短信服务,但不能访问其他服务(比如baidu.com)。

[root@srv001 ~]# curl mirrors.neusoft.edu.cn -I
HTTP/1.1 200 OK
Date: Mon, 14 Oct 2019 04:45:24 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Server: nginx/1.16.1
X-Frame-Options: DENY

[root@srv001 ~]# curl https://ksms.api.ksyun.com -I
HTTP/1.1 400 Bad Request
Date: Mon, 14 Oct 2019 04:38:17 GMT
Content-Type: application/xml
Connection: keep-alive
Server: ksyun-open-platform

[root@srv001 ~]# curl baidu.com -I
^C

5.7 应用服务器提供的Web服务只能通过负载均衡提供的弹性IP访问

MichaeldeMacBook-Pro-2:~ myang$ curl 120.131.1.39
Master

6 总结

本文总结了如何在金山云上自建堡垒机,并结合网络访问控制功能,提升金山云云服务器环境的访问控制和审计。通过金山云控制台的访问控制和操作审计分别是通过“访问控制”和“操作审计”服务实现。

7 参考资料

  1. Linux日常之允许或禁止指定用户或IP进行SSH登录: https://blog.youkuaiyun.com/qq_37124744/article/details/83088410

  2. 金山云安全组: https://docs.ksyun.com/documents/70

  3. 金山云网络ACL: https://docs.ksyun.com/documents/71

  4. Linux Bastion Hosts on the AWS Cloud: Quick Start Reference Deployment

8 附:bastion_bootstrap.sh

#!/bin/bash -e
# Bastion Bootstrapping
# The script is based on AWS basition quick start. More detail can been found at https://github.com/aws-quickstart/quickstart-linux-bastion.


# Configuration
PROGRAM='Linux Bastion'

##################################### Functions Definitions
# 本脚本只支持Linux操作系统。
function checkos () {
    platform='unknown'
    unamestr=`uname`
    if [[ "${unamestr}" == 'Linux' ]]; then
        platform='linux'
    else
        echo "[WARNING] This script is not supported on MacOS or FreeBSD"
        exit 1
    fi
    echo "${FUNCNAME[0]} Ended"
}

# 初始化必要的目录和文件,并设置环境变量
# 其中在堡垒机上执行的所有命令将被记录在/var/log/bastion/bastion.log文件下。
function setup_environment_variables() {

    # LOGGING CONFIGURATION
    BASTION_MNT="/var/log/bastion"
    BASTION_LOG="bastion.log"
    echo "Setting up bastion session log in ${BASTION_MNT}/${BASTION_LOG}"
    mkdir -p ${BASTION_MNT}
    BASTION_LOGFILE="${BASTION_MNT}/${BASTION_LOG}"
    BASTION_LOGFILE_SHADOW="${BASTION_MNT}/.${BASTION_LOG}"
    touch ${BASTION_LOGFILE}
    if ! [ -L "$BASTION_LOGFILE_SHADOW" ]; then
      ln ${BASTION_LOGFILE} ${BASTION_LOGFILE_SHADOW}
    fi
    mkdir -p /usr/bin/bastion
    touch /tmp/messages
    chmod 770 /tmp/messages

    export BASTION_MNT BASTION_LOG BASTION_LOGFILE BASTION_LOGFILE_SHADOW 
}

function verify_dependencies(){
    echo "${FUNCNAME[0]} Ended"
}

function usage() {
    echo "$0 <usage>"
    echo " "
    echo "options:"
    echo -e "--help \t Show options for this script"
    echo -e "--banner \t Enable or Disable Bastion Message"
    echo -e "--enable \t SSH Banner"
    echo -e "--tcp-forwarding \t Enable or Disable TCP Forwarding"
    echo -e "--x11-forwarding \t Enable or Disable X11 Forwarding"
}

function chkstatus () {
    if [[ $? -eq 0 ]]
    then
        echo "Script [PASS]"
    else
        echo "Script [FAILED]" >&2
        exit 1
    fi
}

function osrelease () {
    OS=`cat /etc/os-release | grep '^NAME=' |  tr -d \" | sed 's/\n//g' | sed 's/NAME=//g'`
    if [[ "${OS}" == "Ubuntu" ]]; then
        echo "Ubuntu"
    elif [[ "${OS}" == "CentOS Linux" ]]; then
        echo "CentOS"
    else
        echo "Operating System Not Found"
    fi
}

# 修改sshd_config文件,当用户在堡垒机上执行shell命令时,将首先自动执行定义的脚本文件/usr/bin/basition/shell

function harden_ssh_security () {
    # Make OpenSSH execute a custom script on logins
    echo -e "\nForceCommand /usr/bin/bastion/shell" >> /etc/ssh/sshd_config

cat <<'EOF' >> /usr/bin/bastion/shell
bastion_mnt="/var/log/bastion"
bastion_log="bastion.log"
# Check that the SSH client did not supply a command. Only SSH to instance should be allowed.
export Allow_SSH="ssh"
export Allow_SCP="scp"
if [[ -z $SSH_ORIGINAL_COMMAND ]] || [[ $SSH_ORIGINAL_COMMAND =~ ^$Allow_SSH ]] || [[ $SSH_ORIGINAL_COMMAND =~ ^$Allow_SCP ]]; then
#Allow ssh to instance and log connection
    if [[ -z "$SSH_ORIGINAL_COMMAND" ]]; then
        /bin/bash
        exit 0
    else
        $SSH_ORIGINAL_COMMAND
    fi
    log_shadow_file_location="${bastion_mnt}/.${bastion_log}"
    log_file=`echo "$log_shadow_file_location"`
    DATE_TIME_WHOAMI="`whoami`:`date "+%Y-%m-%d %H:%M:%S"`"
    LOG_ORIGINAL_COMMAND=`echo "$DATE_TIME_WHOAMI:$SSH_ORIGINAL_COMMAND"`
    echo "$LOG_ORIGINAL_COMMAND" >> "${bastion_mnt}/${bastion_log}"
    log_dir="/var/log/bastion/"
else
# The "script" program could be circumvented with some commands
# (e.g. bash, nc). Therefore, I intentionally prevent users
# from supplying commands.

    echo "This bastion supports interactive sessions only. Do not supply a command"
    exit 1
fi
EOF

    # Make the custom script executable
    chmod a+x /usr/bin/bastion/shell

    release=$(osrelease)
    if [[ "${release}" == "CentOS" ]]; then
        semanage fcontext -a -t ssh_exec_t /usr/bin/bastion/shell
    fi

    echo "${FUNCNAME[0]} Ended"
}

function setup_logs () {
    echo "${FUNCNAME[0]} Started"
}

# 修改bashrc文件。当用户登录到堡垒机时,将自动执行bashrc文件。
function setup_os () {

    echo "${FUNCNAME[0]} Started"

    if [[ "${release}" == "CentOS" ]]; then
        bash_file="/etc/bashrc"
    else
        bash_file="/etc/bash.bashrc"
    fi

cat <<EOF >> "${bash_file}"
#Added by Linux bastion bootstrap
declare -rx IP=\$(echo \$SSH_CLIENT | awk '{print \$1}')
declare -rx BASTION_LOG=${BASTION_LOGFILE}
declare -rx PROMPT_COMMAND='history -a >(logger -t "[ON]:\$(date)   [FROM]:\${IP}   [USER]:\${USER}   [PWD]:\${PWD}" -s 2>>\${BASTION_LOG})'
EOF

    echo "Defaults env_keep += \"SSH_CLIENT\"" >> /etc/sudoers

    if [[ "${release}" == "Ubuntu" ]]; then
        user_group="ubuntu"
    elif [[ "${release}" == "CentOS" ]]; then
        user_group="root"
    fi

    chown root:"${user_group}" "${BASTION_MNT}"
    chown root:"${user_group}" "${BASTION_LOGFILE}"
    chown root:"${user_group}" "${BASTION_LOGFILE_SHADOW}"
    chmod 662 "${BASTION_LOGFILE}"
    chmod 662 "${BASTION_LOGFILE_SHADOW}"
    chattr +a "${BASTION_LOGFILE}"
    chattr +a "${BASTION_LOGFILE_SHADOW}"
    touch /tmp/messages
    chown root:"${user_group}" /tmp/messages

    if [[ "${release}" == "CentOS" ]]; then
        restorecon -v /etc/ssh/sshd_config
        systemctl restart sshd
    fi

    if [[ "${release}" == "SLES" ]]; then
        echo "0 0 * * * zypper patch --non-interactive" > ~/mycron
    elif [[ "${release}" == "Ubuntu" ]]; then
        apt-get install -y unattended-upgrades
        echo "0 0 * * * unattended-upgrades -d" > ~/mycron
    else
        echo "0 0 * * * yum -y update --security" > ~/mycron
    fi

    crontab ~/mycron
    rm ~/mycron

    echo "${FUNCNAME[0]} Ended"
}
# 不允许登录到堡垒机上的用户能通过ps -ef看到别的用户的进程信息。
function prevent_process_snooping() {
    # Prevent bastion host users from viewing processes owned by other users.
    mount -o remount,rw,hidepid=2 /proc
    awk '!/proc/' /etc/fstab > temp && mv temp /etc/fstab
    echo "proc /proc proc defaults,hidepid=2 0 0" >> /etc/fstab
    echo "${FUNCNAME[0]} Ended"
}

##################################### End Function Definitions

# Read the options from cli input
TEMP=`getopt -o h --longoptions help,banner:,enable:,tcp-forwarding:,x11-forwarding: -n $0 -- "$@"`
eval set -- "${TEMP}"

# Call checkos to ensure platform is Linux
checkos
# Verify dependencies are installed.
verify_dependencies
# Assuming it is, setup environment variables.
setup_environment_variables

# BANNER CONFIGURATION
ENABLE="true"
BANNER_FILE="/etc/ssh_banner"
BANNER_PATH="https://raw.githubusercontent.com/ksc-sbt/bastion/master/ssh-banner.txt"

if [[ ${ENABLE} == "true" ]];then
    if [[ -z ${BANNER_PATH} ]];then
        echo "BANNER_PATH is null skipping ..."
    else
        echo "BANNER_PATH = ${BANNER_PATH}"
        echo "Creating Banner in ${BANNER_FILE}"
        echo "curl  -s ${BANNER_PATH} > ${BANNER_FILE}"
        curl  -s ${BANNER_PATH} > ${BANNER_FILE}
        if [[ -e ${BANNER_FILE} ]] ;then
            echo "[INFO] Installing banner ... "
            echo -e "\n Banner ${BANNER_FILE}" >>/etc/ssh/sshd_config
        else
            echo "[INFO] banner file is not accessible skipping ..."
            exit 1;
        fi
    fi
else
    echo "Banner message is not enabled!"
fi

release=$(osrelease)
if [[ "${release}" == "Operating System Not Found" ]]; then
    echo "[ERROR] Unsupported Linux Bastion OS"
    exit 1
else
    setup_os
    setup_logs
fi

prevent_process_snooping

echo "Bootstrap complete."
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值