服务器初始化脚本

#!/bin/bash
## RHEL服务器初始化加固化脚本
## 2023/09/12
## zhengry
## version 1.0

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
export PATH
. /etc/profile

#########################可调整参数#########################

#iso文件名
IsoName=rhel.iso
#需要关闭的服务列表,以逗号隔开列表
ShutdownServiceList=("firewalld")
#需要确认开启的服务器列表
ConfirmServiceList=("crond","rsyslog")
# 定义限制类型和相应的soft和hard限制值
limits=("nofile 100000 100000" "nproc 65535 65535" "core unlimited unlimited")
#sshd配置文件路径
SshdConfigFile='/etc/ssh/sshd_config'
#sysctl配置文件路径
SysctlConfigFile='/etc/sysctl.conf'
#vimrc配置文件路径
VimrcConfigFile='/etc/vimrc'
#系统别名配置文件
AliasConfigFile='/etc/bashrc'

#########################固定参数#########################

#初始化日志路径和主机名
InitLogFile="./init-$(date +"%Y-%m-%d_%H:%M:%S").log"
HostName=$(hostname)

#########################功能性#########################

## 输出颜色
echored ()
{
echo -ne "\033[31m"$1"\033[0m\n"
}
echogreen ()
{
echo -ne "\033[32m"$1"\033[0m\n"
}
echoyellow ()
{
echo -ne "\033[33m"$1"\033[0m\n"
}

#yum安装输出
YumINstall ()
{
RpmName=${1}
if [[ `yum list installed ${RpmName} > /dev/null 2>&1 && echo ok` ]];then
     echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${RpmName} has been installed." | tee -a ${InitLogFile}
else
     yum -q -y install ${RpmName} > /dev/null 2>&1 && yum list installed | grep ${RpmName} > /dev/null 2>&1 && echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${RpmName} 安装成功" | tee -a ${InitLogFile} || echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${RpmName} 安装失败" | tee -a ${InitLogFile}
fi
}

#########################初始化#########################

#检查当前用户
function check_user(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 检查用户是否为root" | tee -a ${InitLogFile}
    if [ "$(id -u)" -ne 0 ]; then
        echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 当前用户不是root用户,请切换root用户执行此脚本,脚本将退出" | tee -a ${InitLogFile}
        exit 1
    fi
    echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 检查完成当前用户为root" | tee -a ${InitLogFile}
}

#检查ISO文件是否存在
function check_iso(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 检查ISO文件是否存在" | tee -a ${InitLogFile}
    if [ -e ${IsoName} ]; then
        echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ISO文件检查完成" | tee -a ${InitLogFile}
    else
        echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ISO文件不存在,请将iso文件放在和脚本同路径下,脚本将退出" | tee -a ${InitLogFile}
        exit 1
    fi
}

#配置repo源
function add_yum_repo(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` repo yum 源配置" | tee -a ${InitLogFile}
    mkdir -p /mnt/cdrom
    mount ./rhel.iso /mnt/cdrom > /dev/null 2>&1
	mkdir -p /etc/yum.repos.d/repo_bak
	mv /etc/yum.repos.d/*.repo  /etc/yum.repos.d/repo_bak
    echo '
[local repository]
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
    '>  /etc/yum.repos.d/redhat.repo
    echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` repo yum 源配置完成" | tee -a ${InitLogFile}
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 清理并创建yum缓存" | tee -a ${InitLogFile}
    yum clean all > /dev/null 2>&1
    yum makecache fast > /dev/null 2>&1
    echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 清理并创建yum缓存完成" | tee -a ${InitLogFile}
}

#检查当前LANG
function check_LANG(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"`  当前操作系统语言为 ${LANG}" | tee -a ${InitLogFile}
}

#时区配置
function config_localtime(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 同步时区(上海)" | tee -a ${InitLogFile}
    if [ `md5sum /etc/localtime | awk '{print $1}'` != `md5sum /usr/share/zoneinfo/Asia/Shanghai | awk '{print $1}'` ]; then
        mv /etc/localtime /tmp/localtime-$(date +"%Y-%m-%d_%H:%M:%S")
        ln -s  /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    fi
	echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 时区同步配置成功" | tee -a ${InitLogFile}
}

#关闭selinux服务
function shutdown_selinux(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 关闭selinux"
    setenforce 0 > /dev/null 2>&1
    cp /etc/selinux/config /tmp/selinux-config-$(date +"%Y-%m-%d_%H:%M:%S")
    sed -i 's:SELINUX=enforcing:SELINUX=disabled:g' /etc/selinux/config  && echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` selinux关闭完成" | tee -a ${InitLogFile} || echored "Error: selinux关闭失败请检查" | tee -a ${InitLogFile}
}

#安装常用工具
function install_pkgs(){
    #下载程序
    YumINstall wget
    #时间服务
    YumINstall ntp
    #远程telnet工具
    YumINstall telnet
    #传输工具
    YumINstall lrzsz
    #系统状态工具
    YumINstall sysstat
    #tty终端加强工具
    YumINstall screen
    #标准服务工具
    YumINstall xinetd
    #同步文件工具
    YumINstall rsync
    #解压缩工具
    YumINstall unzip
    #编辑工具
    YumINstall vim
    #网络排查工具
    YumINstall net-tools
    #yum加强工具
    YumINstall yum-utils
}

#修改history记录格式
function optimize_history(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 优化history记录" | tee -a ${InitLogFile}
    if [ -f /etc/profile ]; then
        if ! grep -q "export HISTTIMEFORMAT\=\"\%\Y\-\%m\-\%d \%H\:\%M\:\%S  \`who am i \| awk \'{print \$1\,\$5}\'\` \"" "/etc/profile"; then
            echo "HISTSIZE=10000" >> /etc/profile
            echo "HISTFILESIZE=20000" >> /etc/profile
            echo "export HISTTIMEFORMAT=\"%Y-%m-%d %H:%M:%S  \`who am i | awk '{print \$1,\$5}'\` \" " >>/etc/profile
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 优化history记录完成" | tee -a ${InitLogFile}
        else
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` history记录已优化过,无须优化" | tee -a ${InitLogFile}
        fi
    else
        echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` /etc/profile不存在请尽快检查,脚本将退出" | tee -a ${InitLogFile}
        exit 1
    fi
}

#确认需要关闭和启动的服务
function shutdown_and_start_services() {
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 关闭需要关闭的服务" | tee -a ${InitLogFile}
    for service in "${ShutdownServiceList[@]}"; do
        if systemctl is-active --quiet "${service}"; then
            echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务正在运行,将关闭它" | tee -a ${InitLogFile}
            systemctl stop --quiet "${service}"
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已关闭" | tee -a ${InitLogFile}
        else
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务未运行" | tee -a ${InitLogFile}
        fi

        if systemctl is-enabled --quiet "${service}"; then
            echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已自动启动,将禁用它" | tee -a ${InitLogFile}
            systemctl disable --quiet "${service}"
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 服务已禁用" | tee -a ${InitLogFile}
        else
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 服务未自动启动" | tee -a ${InitLogFile}
        fi
    done

    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 启动需要启动的服务" | tee -a ${InitLogFile}
    for service in "${ConfirmServiceList[@]}"; do
        if ! systemctl is-active --quiet "${service}"; then
            echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已关闭,将开启它" | tee -a ${InitLogFile}
            systemctl start "${service}"
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已开启" | tee -a ${InitLogFile}
        else
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已运行" | tee -a ${InitLogFile}
        fi

        if ! systemctl is-enabled --quiet "${service}"; then
            echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` ${service} 服务已禁用自动启动,将启动它" | tee -a ${InitLogFile}
            systemctl enable "${service}"
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 服务已开启自动启动" | tee -a ${InitLogFile}
        else
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 服务已自动启动" | tee -a ${InitLogFile}
        fi
    done
}

#修改limits限制
function change_limits(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 修改limits限制" | tee -a ${InitLogFile}
    for limit in "${limits[@]}"; do
        limit_type=$(echo "${limit}" | awk '{print $1}')
        soft_limit=$(echo "${limit}" | awk '{print $2}')
        hard_limit=$(echo "${limit}" | awk '{print $3}')
        if grep -q "${limit_type}" /etc/security/limits.conf; then
            sudo sed -i "/${limit_type}/d" /etc/security/limits.conf
            echo "*    soft    ${limit_type}    ${soft_limit}" | sudo tee -a /etc/security/limits.conf 
            echo "*    hard    ${limit_type}    ${hard_limit}" | sudo tee -a /etc/security/limits.conf
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 已更新所有用户的 ${limit_type} 限制" | tee -a ${InitLogFile}
        else
            echo "*    soft    ${limit_type}    ${soft_limit}" | sudo tee -a /etc/security/limits.conf
            echo "*    hard    ${limit_type}    ${hard_limit}" | sudo tee -a /etc/security/limits.conf
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 已添加所有用户的 ${limit_type} 限制" | tee -a ${InitLogFile}
        fi
    done
}

#添加kernel日志
function add_kernel_log() {
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 添加kernel日志" | tee -a ${InitLogFile}
    if grep -q "CustomRsyslogConfig" /etc/rsyslog.conf; then
        echo "rsyslog 已配置,不需要再次修改"
    else
        echo -e "kern.*   /var/log/kernel.log" | sudo tee -a /etc/rsyslog.conf
        echo "# CustomRsyslogConfig" | sudo tee -a /etc/rsyslog.conf
    fi
    systemctl restart rsyslog && echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` kernel日志已配置,内核日志将分级并写入 /var/log/kernel.log" | tee -a ${InitLogFile} || echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` kernel日志配置异常请检查" | tee -a ${InitLogFile}
}

#加固SSHD服务
function check_sshd_parameter() {
    local parameter="${1}"
    if grep -q "^${parameter}" "${SshdConfigFile}"; then
        echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` sshd 参数 ${parameter} 已配置并生效"
    else
        echo "${1}" | sudo tee -a ${SshdConfigFile}
        echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` sshd 参数 ${parameter} 已配置"
    fi
}

function optimize_sshd() {
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 加固sshd服务" | tee -a ${InitLogFile}
    if [ ! -f ${SshdConfigFile} ]; then echored "文件 ${SshdConfigFile} 不存在" exit 1; fi
    cp ${SshdConfigFile} /tmp/sshd_config-$(date +"%Y-%m-%d_%H:%M:%S")
    #进制空密码登陆
    check_sshd_parameter "PermitEmptyPasswords no"
    #密码错误试错3次
    check_sshd_parameter "MaxAuthTries 3"
    #禁止X11登陆
    check_sshd_parameter "X11Forwarding no"
    check_sshd_parameter "AllowTcpForwarding no"
    #修改ssh默认端口为60022
    check_sshd_parameter "Port 60022"
    systemctl restart --quiet sshd && echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` SSHD服务加固完成" | tee -a ${InitLogFile} || echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` SSHD加固服务异常请检查" | tee -a ${InitLogFile}
}

#内核参数调优
function change_sysctl_config() {
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 内核参数调优" | tee -a ${InitLogFile}
    if [ ! -f ${SysctlConfigFile} ]; then echored "文件 ${SysctlConfigFile} 不存在" exit 1; fi
    cp ${SysctlConfigFile} /tmp/sysctl-$(date +"%Y-%m-%d_%H:%M:%S")
    declare -A params
    params=(
        #开启反向路径过滤
        ["net.ipv4.conf.default.rp_filter"]="1"
        ["net.ipv4.conf.all.rp_filter"]="1"
        #处理无源路由包
        ["net.ipv4.conf.all.accept_source_route"]="0"
        ["net.ipv4.conf.default.accept_source_route"]="0"
        #core文件名中添加pid作为扩展名
        ["kernel.core_uses_pid"]="1"
        #开启syn洪水攻击保护
        ["net.ipv4.tcp_syncookies"]="1"
        #修改消息队列长度
        ["kernel.msgmnb"]="65536"
        ["kernel.msgmax"]="65536"
        #修改最大内存共享段大小bytes
        ["kernel.shmmax"]="18446744073692774399"
        ["kernel.shmall"]="18446744073692774399"
        ["kernel.shmmni"]="4096"
        #timewait数量默认18000
        ["net.ipv4.tcp_max_tw_buckets"]="600"
        ["net.ipv4.tcp_sack"]="1"
        ["net.ipv4.tcp_window_scaling"]="1"
        ["net.ipv4.tcp_rmem"]="4096 87380 16777216"
        ["net.ipv4.tcp_wmem"]="4096 65536 16777216"
        ["net.core.rmem_default"]="8388608"
        ["net.core.wmem_max"]="16777216"
        #未收到客户端确认信息连接请求的最大值
        ["net.ipv4.tcp_max_syn_backlog"]="262144"
        #放弃建立连接之前发送的synack包
        ["net.ipv4.tcp_syn_retries"]="2"
        #开启重用,允许time—wait socket 重新用语新的tcp连接
        ["net.ipv4.tcp_tw_reuse"]="1"
        ["net.ipv4.tcp_fin_timeout"]="1"
        #防止简单的ddos攻击
        ["net.ipv4.tcp_max_orphans"]="3276800"
        #启用timewait快速收回
        ["net.ipv4.tcp_tw_recycle"]="0"
        #keeptime启用时tcp发送keepalive消息的频度,默认2h
        ["net.ipv4.tcp_keepalive_time"]="600"
        #允许系统打开的端口范围
        ["net.ipv4.ip_local_port_range"]="1024 65535"
        #资源回收
        ["net.ipv4.tcp_tw_recycle"]="0"
        #禁止IP转发
        ["net.ipv4.ip_forward"]="1"
        ["net.ipv6.conf.all.forwarding"]="0"
        #解禁ping
        ["net.ipv4.icmp_echo_ignore_all"]="0"
        # 禁止ICMP重定向
        ["net.ipv4.conf.all.accept_redirects"]="0"
        ["net.ipv4.conf.default.accept_redirects"]="0"
        #控制系统调试内核的功能要求
        ["kernel.sysrq"]="0"
        #大页内存数
        ["vm.nr_hugepages"]="16384"
        #最大进程号
        ["kernel.pid_max"]="65535"
    )
    for param_name in "${!params[@]}"; do
        expected_value="${params[$param_name]}"
        current_value=$(sysctl -n "${param_name}")
        if [ "${current_value}" != "${expected_value}" ]; then
            sysctl -w "${param_name}=${expected_value}" > /dev/null 2>&1 && echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 修改 $param_name 为 $expected_value 成功" | tee -a ${InitLogFile} || echored "Error: ${HostName} `date +"%Y-%m-%d %H:%M:%S"`  修改 $param_name 为 $expected_value 失败请检查" | tee -a ${InitLogFile}
            echo "${param_name}=${expected_value}" | sudo tee -a ${SysctlConfigFile}
        else
            echogreen "Ok: ${param_name} 已经是预期值 ${expected_value},不需要修改" | tee -a ${InitLogFile}
        fi
    done
}

function disable_restart(){
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用ctrl+alt+del重启处理" | tee -a ${InitLogFile}
    if [ -f /usr/lib/systemd/system/ctrl-alt-del.target ];then
        cp /usr/lib/systemd/system/ctrl-alt-del.target{,.bak}
        rm -f /usr/lib/systemd/system/ctrl-alt-del.target
    echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用ctrl+alt+del重启处理成功" | tee -a ${InitLogFile}
    else
    echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用ctrl+alt+del已处理" | tee -a ${InitLogFile}
    fi
}

function optimize_alias() {    
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用rm命令处理" | tee -a ${InitLogFile}
    if ! grep -q "CustomRmConfig" ${AliasConfigFile}; then
        echo -e "alias rm='DIR=/tmp/rm\`date +%F%T\`;mkdir \$DIR;mv -t \$DIR'" | sudo tee -a ${AliasConfigFile}
        echo -e "alias vi=vim" | sudo tee -a ${AliasConfigFile}
        echo "# CustomRmConfig" | sudo tee -a ${AliasConfigFile}
        source ${AliasConfigFile}
        echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用rm命令处理成功"
    else
        echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 禁用rm命令已处理"
    fi
}

#优化vim选项
function vimrc() {
    echoyellow "Info: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 优化vim处理" | tee -a ${InitLogFile}
    if [ ! `rpm -qa | grep vim > /dev/null 2>&1` ]; then
        if grep -q "CustomVimConfig" ${VimrcConfigFile}; then
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 优化vim已处理"
        else
            cat >>${VimrcConfigFile} <<-EOF
set ts=4
set expandtab
set ignorecase
set cursorline
set autoindent
" CustomVimConfig
EOF
            echogreen "Ok: ${HostName} `date +"%Y-%m-%d %H:%M:%S"` 优化vim处理成功"
        fi
    fi
}

#########################入口方法#########################

function main(){
    echoyellow "===`date +"%Y-%m-%d %H:%M:%S"`==${HostName}====初始化检查================================="
        check_user
        # check_iso
        # add_yum_repo
    echoyellow "===`date +"%Y-%m-%d %H:%M:%S"`==${HostName}====初始化开始================================="
        check_LANG
        config_localtime
        shutdown_selinux
        install_pkgs
        optimize_history
        shutdown_and_start_services
        change_limits
        add_kernel_log
        optimize_sshd
        change_sysctl_config
        disable_restart
        vimrc
    echoyellow "==`date +"%Y-%m-%d %H:%M:%S"`==${HostName}====初始化完成请执行'source /etc/profile命令'==="
}

main

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值