Python脚本:一键加固Ubuntu服务器

镜像文章:批处理脚本:一键加固Windows终端

严肃提醒,生产环境中运行以下脚本,一定要提前测试!!!
不同的服务器可能会产生不同结果!


#!/usr/bin/env python3
#vim:set fileencoding=utf-8

import os
import re

class CheckUser:
    def __init__(self):
        self.root_id = 0 #判断是否存在root用户
        self.pass_max_days = 'PASS_MAX_DAYS 90' #最长使用天数
        self.pass_min_days = 'PASS_MIN_DAYS 0' #最短使用天数
        self.pass_warn_age = 'PASS_WARN_AGE 7' #到期前提醒天数
        self.is_null = 0 #判断是否存在空口令
        self.is_history = 0 #判断是否已开启时间戳
        self.is_log = 0 #判断是否开启日志功能

    def check_root(self):
        # ubuntu中uid为0的用户拥有最高权限
        # 应确保只有root的uid为0
        # 检查是否存在uid为0的非Root用户
        with open('/etc/passwd','r') as f:
            for i in f.readlines():
                # print(i.split(':')[2])
                l = i.split(':')
                if l[2] == '0' and l[0] != 'root':
                    self.root_id += 1
                    print('---------------------------------------')
                    print('1.请检查,用户{}竟然有root权限!!!!'.format(l[0]))
                    print('---------------------------------------')
            if self.root_id == 0:
                print('---------------------------------------')
                print('1.未发现其他root用户.')
                print('---------------------------------------')

    def set_retiretime(self):
        # 用户口令失效设置,修改/etc/login.defs的配置文件如下
        # PASS_MAX_DAYS 90
        # PASS_MIN_DAYS 0
        # PASS_WARN_AGE 7
        file_data = ''
        with open('/etc/login.defs','r') as f1:
            for line in f1:
                if re.findall('^PASS_MAX_DAYS', line) != []:
                    #print(line)
                    line = self.pass_max_days + '\n'
                if re.findall('^PASS_MIN_DAYS', line) != []:
                    #print(line)
                    line = self.pass_min_days + '\n'
                if re.findall('^PASS_WARN_AGE', line) != []:
                    #print(line)
                    line = self.pass_warn_age + '\n'
                file_data += line
        with open('/etc/login.defs','w') as f2:
            f2.write(file_data)
        print('---------------------------------------')
        print('2.完成用户口令失效时间设置')
        print('---------------------------------------')

    
    def check_null_pass(self):
        # 列出空口令账户
        with open('/etc/shadow', 'r') as f:
            print('---------------------------------------')       
            for line in f.readlines(): 
                if line.split(':')[1] == '':
                    self.is_null += 1
                    print('3.请注意:账户{}存在空口令!!!'.format(line.split(':')[0]))
            if self.is_null == 0:
                print('3.未检测到空口令账户.')
            print('---------------------------------------')
    
    def user_pass_set(self):
        # 设置账户策略
        with open('/etc/pam.d/common-password', 'a') as f1:
            # 尝试3次,长度10位以上,至少包括一位大写、一位小写、一位字母、一位特殊字符
            f1.write('password requisite pam_cracklib.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 enforce_for_root')
        with open('/etc/pam.d/login','a') as f2:
            f2.write('auth required pam_tally2.so deny=3 unlock_time=300 even_deny_root root_unlock_time=300')
        print('---------------------------------------')
        print('请注意提前安装libpam-cracklib')
        print('安装方法:sudo apt-get install libpam-cracklib -y')
        print('4.设置口令策略,包括复杂度、有效期、锁定阈值等')
        print('---------------------------------------')
       
    def check_file_permit(self):
        # 将部分系统文件设置为仅Root权限
        file_list = ['/etc/crontab','/etc/securetty','/boot/grub/grub.cfg','/etc/inittab','/etc/login.defs']
        for file_name in file_list:
            m_cmd = 'chmod -R 750 '+file_name
            # print(m_cmd)
            os.system(m_cmd)
        print('---------------------------------------')
        print('5.对部分系统文件设置权限')
        print('---------------------------------------')
        
    def close_service(self):
        # 关闭不必要的服务,cups,postfix,pcscd,smartd,alsasound,iscsitarget,smb,acpid等
        service_list = ['cups','postfix','pcscd','smartd','alsasound','iscsitarget','smb','acpid']
        for m_ser in service_list:
            m_cmd1 = 'systemctl disable ' + m_ser + '.service'
            m_cmd2 = 'systemctl stop ' + m_ser +'.service'
            os.system(m_cmd1)
            os.system(m_cmd2)
        print('---------------------------------------')
        print('6.关闭不必要的服务')
        print('---------------------------------------')
        
        
    def set_history(self):
        # 在/etc/profile中开启history的时间戳
        with open('/etc/profile', 'r') as f:
            if ('export HISTTIMEFORMAT') in f.read():
                self.is_history = 1
                # print('is_history 1')
        if self.is_history == 0:
            with open('/etc/profile', 'a') as f2:
                f2.write('export HISTTIMEFORMAT="%F%T `whoami`"')
        os.system('source /etc/profile')
        print('---------------------------------------')
        print('7.开启history时间戳')
        print('---------------------------------------')
        
    def set_log(self):
        with open('/etc/rsyslog.conf', 'r') as f1:
            for line in f1.readlines():
                if line.find('authpriv.*') != -1:
                    if line.find('/var/log/auth.log') != -1:
                        self.is_log = 1
        if self.is_log == 1:
            print('---------------------------------------')
            print('8.已开启日志功能')
            print('---------------------------------------')
        else:
            print('---------------------------------------')
            print('8.未开启日志')
            print('请查看/etc/rsyslog.conf文件中的参数authpriv的值')
            print('必须要设置/var/log/auth.log')
            print('查看命令如下:cat /etc/rsyslog.conf | grep "authpriv"')
            print('---------------------------------------')        
    
    def set_audit(self):
        os.system('apt-get install auditd')
        os.system('systemctl enable auditd.service')
        os.system('systemctl start auditd.service')
        print('---------------------------------------')
        print('9.已开启审计功能')
        print('---------------------------------------')
    
    def set_login(self):
        # 1.登录超时设置
        # 2.禁止Root账户远程登录
        # 3.修改ssh默认端口为12345
        with open('/etc/profile','a') as f1:
            f1.write('TOUT=180')
        file_data = ''
        with open('/etc/ssh/sshd_config','r') as f2:
            for line in f2:
                if re.findall('^PermitRootLogin', line) != []:
                    #print(line)
                    line = 'PermitRootLogin no\n'
                if re.findall('Port ', line) != []:
                    #print(line)
                    line = 'Port 12345\n'
                file_data += line
        with open('/etc/login.defs','w') as f2:
            f2.write(file_data)
        print('---------------------------------------')
        print('10.已设置远程登录安全,请使用非root用户登录ssh的12345端口,登录180s后超时')
        print('---------------------------------------')
    
    
def main():
    print('Ubuntu一键安全加固脚本')
    print('请务必以Root权限运行!!!')
    print('回车后继续')
    input()
    test = CheckUser()
    test.check_root()
    test.set_retiretime()
    test.check_null_pass()
    test.user_pass_set()
    test.check_file_permit()
    test.close_service()
    test.set_history()
    test.set_log()
    test.set_audit()
    test.set_login()

if __name__ == '__main__':
    main()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,755评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,305评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,138评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,791评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,794评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,631评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,362评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,264评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,724评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,040评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,742评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,364评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,944评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,060评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,247评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,979评论 2 355

推荐阅读更多精彩内容