예제 #1
0
def fail2ban(EMAIL):

    # Application Intrusion Detection And Prevention With Fail2Ban
    f_f2b_jail = '/etc/fail2ban/jail.local'
    if not General.answer('Do you want to install and configure Fail2Ban?'):
        return

    General.run_cmd('apt install fail2ban -y')
    General.run_cmd('systemctl start fail2ban', 'systemctl enable fail2ban')
    General.output_message("fail2ban is running")

    with open(f_f2b_jail, 'w') as file:
        lan_segment = General.input_message(
            'What is you lan segment? (ex. 192.168.1.1/24) :')
        file.write(f'''
    [DEFAULT]
    # the IP address range we want to ignore
    ignoreip = 127.0.0.1/8 {lan_segment}

    # who to send e-mail to
    destemail = {EMAIL}

    # who is the email from
    sender = {General.USER}.{General.HOSTNAME}.{EMAIL}

    # since we're using exim4 to send emails
    mta = mail

    # get email alerts
    action = %(action_mwl)s
                ''')

    General.output_message('Configuring Intrusion and detection tools')

    if not General.answer(
            'Do You need a jail for SSH that tells fail2ban to look at SSH logs and use ufw to ban/unban IPs ?'
    ):
        return

    with open(f_f2b_jail, 'a') as jail_file:
        jail_file.write('''
    [sshd]
    enabled = true
    banaction = ufw
    port = ssh
    filter = sshd
    logpath = %(sshd_log)s
    maxretry = 5
    ''')

    General.run_cmd('fail2ban-client start', 'fail2ban-client reload')
    General.output_message("Tools reloaded")
    General.run_cmd('systemctl restart fail2ban')
예제 #2
0
def psad(EMAIL):
    # iptables Intrusion Detection And Prevention with

    f_psad_conf = '/etc/psad/psad.conf'
    f_before_rules = '/etc/ufw/before.rules'
    f_before6_rules = '/etc/ufw/before6.rules'

    if not General.answer('Do you want to install and configure psad?'): return

    General.run_cmd('apt install psad -y')
    homenet = General.input_message('Type your Home net: ex(192.168.1.1/24) ')
    General.output_message('Configuring psad')
    General.change_lines(
        f_psad_conf,
        _1=[
            'EMAIL_ADDRESSES             root@localhost;',
            f'EMAIL_ADDRESSES             {EMAIL};\n'
        ],
        _2=[
            'HOSTNAME                     _CHANGEME_;',
            f'HOSTNAME                   {General.HOSTNAME};\n'
        ],
        _3=[
            'ENABLE_AUTO_IDS             N;',
            'ENABLE_AUTO_IDS             Y;\n'
        ],
        _4=[
            'HOME_NET                    any;',
            f'HOME_NET                    {homenet};\n'
        ],
        _5=[
            'PORT_RANGE_SCAN_THRESHOLD   1;',
            'PORT_RANGE_SCAN_THRESHOLD   2;\n'
        ],
        _6=[
            'ENABLE_MAC_ADDR_REPORTING   N;',
            'ENABLE_MAC_ADDR_REPORTING   Y;\n'
        ],
        _7=[
            'ALERT_ALL                   Y;',
            'ALERT_ALL                   N;\n'
        ])

    General.output_message(f'''
These changes have been made to the config '/etc/psad/psad.conf'.
If u need more advanced options feel free to modify it.
    - EMAIL_ADDRESSES             {EMAIL};
    - HOSTNAME                   {General.HOSTNAME};
    - ENABLE_AUTO_IDS             Y;
    - HOME_NET                    {homenet};
    - PORT_RANGE_SCAN_THRESHOLD   2;
    - ENABLE_MAC_ADDR_REPORTING   Y;
    - ALERT_ALL                   N;

                ''')

    with open(f_before_rules, 'r') as file:
        lines = file.readlines()
        text = file.read()
        if not (General.check_lines_in_file(
                f_before_rules, '# log all traffic so psad can analyze',
                '-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES]"',
                '-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES]"'
        )):

            for index, line in enumerate(lines):
                if line.strip() == "COMMIT":
                    lines.insert(
                        index - 2,
                        '# log all traffic so psad can analyze\n-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES]"\n-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES]"'
                    )
                    break
            with open(f_before_rules, 'w') as file:
                for line in lines:
                    file.write(line)

    with open(f_before6_rules, 'r') as file:
        lines = file.readlines()
        text = file.read()
        if not (General.check_lines_in_file(
                f_before_rules, '# log all traffic so psad can analyze',
                '-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES]"',
                '-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES]"'
        )):
            for index, line in enumerate(lines):
                if line.strip() == "COMMIT":
                    lines.insert(
                        index - 2,
                        '# log all traffic so psad can analyze\n-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES]"\n-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES]"'
                    )
                    break
            with open(f_before6_rules, 'w') as file:
                for line in lines:
                    file.write(line)

    General.warning_message('Restarting psad and Firewall..\n')
    General.warning_message('Maybe existing ssh connections will be stopped\n')
    General.run_cmd('ufw --force enable')
    General.run_cmd('ufw reload')
    subprocess.check_call(['psad', '-R'],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.STDOUT)
    General.run_cmd('psad --sig-update')
    General.run_cmd('psad -H')
    General.output_message('Done')
예제 #3
0
def wpVirtualHost(EMAIL):

    ####################################################
    # SETUP APACHE VIRTUALHOST ( FOR MULTIPLE WEBSITES )
    ####################################################

    General.output_message("-- Creation of apache2 Virtual Host --")
    DOMAIN_FULL = General.input_message("Insert a domain[ domain.(com/.it/.org/etc..) ] ")
    DOMAIN = '.'.join(DOMAIN_FULL.split(".")[:-1]) if len(DOMAIN_FULL.split(".")) > 2 else DOMAIN_FULL.split(".")[0]
    General.run_cmd(f"mkdir /var/www/{DOMAIN}")  # create a directory for the virtual host
    General.run_cmd(f"chown -R $USER:$USER /var/www/{DOMAIN}")  # assign the directory to $USER
    General.run_cmd(f"chmod -R 755 /var/www/{DOMAIN}")  # be sure that permissions are correct

    f_apache_domain_conf = f'/etc/apache2/sites-available/{DOMAIN}.conf'
    with open(f_apache_domain_conf, 'w') as file:
        file.write(
"""
<VirtualHost *:80>
    ServerAdmin """ + EMAIL + """
    ServerName """ + DOMAIN_FULL + """
    ServerAlias www.""" + DOMAIN_FULL + """
    DocumentRoot /var/www/""" + DOMAIN + """
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost> 
<Directory /var/www/""" + DOMAIN + """/>
    AllowOverride All
</Directory>
""")

    General.run_cmd(f"sudo a2ensite {DOMAIN}.conf")  # Enable the new configuration ( you can enable as many different configs as you want )
    General.run_cmd(f"sudo a2dissite 000-default.conf")  # Disable the default configuration
    General.run_cmd("sudo a2enmod rewrite")
    General.run_cmd("sudo systemctl restart apache2")  # restart apache
    # Test apache configs
    # sudo apachectl -t -D DUMP_VHOSTS
    # sudo apachectl configtest

    # Add SSL to apache virtualhost
    General.run_cmd("apt install certbot python3-certbot-apache -y")
    General.run_cmd("mkdir /var/lib/letsencrypt")
    General.run_cmd("chmod -R o+rx /var/lib/letsencrypt")
    General.output_message("""
-- Certbot configuration --
If questions are promp type the following answers:
> Terms of service: A
> Share mail address: N
> redirect HTTP traffic to HTTPS: 2
> If the validation of the domain go wrong just exit the script and investigate on the problem.
  You can restart the script on the same domain and it will work correctly""")
    General.run_cmd_interactive(f"sudo certbot --apache -d {DOMAIN_FULL} -d www.{DOMAIN_FULL}") # runs interactive certbot configuration
    General.output_message('If certbot failed chek the apache2 logs ( Ubuntu: /var/log/apache2/error.log ) ')

    # wordpress virtualhost setup
    General.output_message("-- Configuring wordpress Db --")
    DB_NAME = General.input_message("Database Name ")
    DB_USER = General.input_message("Database User Name ")

    DB_USER_PASS = General.sensitive_input_message("Database User Password ")

    General.run_cmd(
        f""" mysql -e " CREATE DATABASE {DB_NAME} DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; " """,
        f""" mysql -e " CREATE USER '{DB_USER}'@'localhost' IDENTIFIED BY '{DB_USER_PASS}'; " """,
        f""" mysql -e " GRANT ALL PRIVILEGES ON {DB_NAME}.* TO '{DB_USER}'@'localhost'; " """,
        """ mysql -e " FLUSH PRIVILEGES; " """
    )

    if(not os.path.exists('/tmp/wordpress')):
        General.output_message("\n-- WORDPRESS DOWNLOAD --")
        General.run_cmd("wget -P /tmp 'https://wordpress.org/latest.tar.gz' ")
        General.run_cmd("tar -C /tmp -zxvf /tmp/latest.tar.gz")
        General.run_cmd("touch /tmp/wordpress/.htaccess")
        General.run_cmd("cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php")
        General.run_cmd("mkdir /tmp/wordpress/wp-content/upgrade")

    General.run_cmd(f"cp -a /tmp/wordpress/. /var/www/{DOMAIN}")
    General.run_cmd(f"chown -R www-data:www-data /var/www/{DOMAIN}")
    General.run_cmd("find /var/www/" + DOMAIN + "/ -type d -exec chmod 750 {} \;")
    General.run_cmd("find /var/www/" + DOMAIN + "/ -type f -exec chmod 640 {} \;")
    f_wp_domain_config = f"/var/www/{DOMAIN}/wp-config.php"

    General.run_cmd("apt install curl -y")

    OUTPUT_KEYS = General.output_run_cmd("curl -s https://api.wordpress.org/secret-key/1.1/salt/").decode(
        "utf-8").split("');")
    for key in OUTPUT_KEYS:
        if key.strip() == '': OUTPUT_KEYS.remove(key)
    OUTPUT_KEYS_DICT = dict()
    for index, key in enumerate(OUTPUT_KEYS):
        index += 1
        OUTPUT_KEYS_DICT["_" + str(index)] = [
            '( '.join(key.split(",")[0].split('(')).strip() + ',',
            key.strip() + "');\n"
        ]
    General.change_lines(
        f_wp_domain_config,
        **OUTPUT_KEYS_DICT
    )
    General.change_lines(
        f_wp_domain_config,
        _1=["define( 'DB_NAME',", f"define( 'DB_NAME', '{DB_NAME}');"],
        _2=["define( 'DB_USER',", f"define( 'DB_USER', '{DB_USER}');"],
        _3=["define( 'DB_PASSWORD',", f"define( 'DB_PASSWORD', '{DB_USER_PASS}');"],
    )
    General.insert_lines(
        f_wp_domain_config,
        "define( 'FS_METHOD', 'direct');",
        index_surplus=1,
        anchor_line=f"define( 'DB_PASSWORD', 'DB_USER_PASS');"
    )


    General.output_message('-- INFO --')
    General.output_message(f" > Finish the WP GUI installation going to https://{DOMAIN}")
    General.output_message(" > We did a setup for SSL certificate with Let’s Encrypt CERTBOT, THis Certificate expire")
    General.output_message("   after 90 days, A Bot that automatic does the renewal is also installed, Check that ")
    General.output_message("   it is working by typing 'sudo systemctl status certbot.timer' ")
    General.output_message(" > For check that PHP was installed sucesfully and it is working correctly do this steps: ")
    General.output_message(f"    - sudo nano /var/www/{DOMAIN}/info.php")
    General.output_message("    - Add the following line to the file '<?php phpinfo(); ?>' ")
    General.output_message(f"    - Visit this link 'http://{DOMAIN_FULL}/info.php'")
    General.output_message(f"    If a table with php information was displayed and nothing went wrong remove the file\n"
                           f"    previously created 'sudo rm /var/www/{DOMAIN}/info.php'")
    time.sleep(5)
예제 #4
0
파일: ClamAv.py 프로젝트: Linch1/SSLOCK
def clamAv(EMAIL):
    # Anti-Virus Scanning With ClamAV

    f_clam_conf = '/etc/clamav/freshclam.conf'

    if not General.answer('Do you want to use ClamAV for Anti-virus Scanning with root permissions?'): return

    General.run_cmd('apt install clamav clamav-freshclam -y')
    General.change_lines(
        f_clam_conf,
        _1=[
            '# Check for new database 24 times a day',
            '# Check for new database 1 times a day\n'
        ],
        _2=[
            'Checks 24',
            'Checks 1\n'
        ]
    )
    General.run_cmd('freshclam -v')




    user = ''
    while True:
        user = General.input_message(
            "Using clamscan as root is dangerous because if a file is in fact a virus there is risk that it could use the root privileges.\n"
            "You can create another user by writing [U] \nPlease chose a user that can run clamscan"
        )
        if UsersConfig.user_exists(user): break
        if user.upper() == 'U':
            UsersConfig.create_users()
        else:
            General.error_message("User doesn't exists")
            General.output_message('For create a new user type [U]')


    dir_to_scan = ''
    all_directories_exists = False
    while not all_directories_exists:
        all_directories_exists = True
        dir_to_scan = General.input_message('Which direcotry should be scanned by clamAV? (ex. /var/www /var/vmail): ')
        for dir in dir_to_scan.split():
            if not os.path.exists(dir):
                General.error_message(f"The directory {dir} doesn't exists, select another path")
                all_directories_exists = False
    General.output_message('Configuration Anti-virus Scanning tools..')

    f_clam_daily = f'/home/{user}/clamscan_daily.sh'

    with open(f_clam_daily, 'w') as file:
        file.write(f'''
    #!/bin/bash
    LOGFILE="/var/log/clamav/clamav-$(date +'%Y-%m-%d').log";
    EMAIL_MSG="Please see the log file attached.";
    EMAIL_FROM="''' + EMAIL + '''";
    DIRTOSCAN="''' + dir_to_scan + '''";

    for S in ${DIRTOSCAN}; do
     DIRSIZE=$(du -sh "$S" 2>/dev/null | cut -f1);

     echo "Starting a daily scan of "$S" directory.
     Amount of data to be scanned is "$DIRSIZE".";

     clamscan -ri "$S" >> "$LOGFILE";

     # get the value of "Infected lines"
     MALWARE=$(tail "$LOGFILE"|grep Infected|cut -d" " -f3);

     # if the value is not equal to zero, send an email with the log file attached
     if [ "$MALWARE" -ne "0" ];then
     # using heirloom-mailx below
     echo "$EMAIL_MSG"|mail -A "$LOGFILE" -s "Malware Found" "$EMAIL_FROM";
    fi 
    done

    exit 0
                    ''')

    General.run_cmd('chmod 0755 /root/clamscan_daily.sh')
    General.run_cmd('ln /root/clamscan_daily.sh /etc/cron.daily/clamscan_daily')
    General.run_cmd('service clamav-freshclam start')
    if not General.answer("Do you want to run the virus scan on the given directories now? This can take some time"): return
    General.output_message('Running first scan for check if all is ok')
    subprocess.run(['clamscan', '-r', dir_to_scan])
예제 #5
0
if os.geteuid() != 0:
    General.error_message(
        "You need to have root privileges to run this script.\nRe-run the script using 'sudo'. Exiting..."
    )
    exit()

General.output_message('YES')

# Store global informations
EMAIL_ENABLE = General.answer(
    "To receive notifications from the system and for the correct configuration of some tools, email and Exim4 will"
    " be used ok? \n[if your system is already configured to send mail, you don't have to follow this step] "
)

if EMAIL_ENABLE:
    EMAIL = General.input_message("Email")
else:
    EMAIL = General.input_message(
        "Also if you don't want to configure Exim4 we need your email for othe tools setup\nEmail"
    )

SSH_ENABLE = General.answer("Do you want to enable the SSH service?")
if SSH_ENABLE:
    SSH_PORT = General.input_message(
        "Insert the port on which you want the ssh service to run, it will be used if you want to configure the ssh service"
    )
else:
    SSH_PORT = None

# Main Terminal Menu
예제 #6
0
파일: SSHConfig.py 프로젝트: Linch1/SSLOCK
def ssh(SSH_ENABLE, EMAIL_ENABLE, SSH_PORT, EMAIL):

    f_ssh_config = '/etc/ssh/sshd_config'
    if not SSH_ENABLE or not EMAIL_ENABLE: return
    General.run_cmd("apt install ssh -y")
    options_list = [
        'Port', 'ClientAliveCountMax', 'ClientAliveInterval', 'LoginGraceTime',
        'MaxAuthTries', 'MaxSessions', 'MaxStartups', 'PasswordAuthentication',
        'AllowGroups', 'PermitRootLogin'
    ]

    for option in options_list:
        status1 = General.check_lines_in_file(f_ssh_config, option)
        status2 = General.check_lines_in_file(f_ssh_config, '#' + option)
        if not status1 and not status2:
            with open(f_ssh_config, 'a') as file:
                file.write(option + '\n')

    generate_key = General.answer('Do you want enable ssh for some users?')
    if generate_key:
        generate_root_key = General.answer(
            f'Do you also want to enable ssh for Current user [{General.USER}] ? '
        )
        if generate_root_key:
            key_path = f'/{General.USER}/.ssh/id_rsa'
            if not os.path.exists(key_path):
                key_pass = General.input_message(
                    'Enter a passphrase for the key (empty for no passphrase):'
                )
                General.run_cmd(
                    f'ssh-keygen -C "{EMAIL}" -b 2048 -t rsa -f {key_path} -q -N "{key_pass}"'
                )
                General.warning_message(
                    f'[ALERT] your private key has been sent by email to {EMAIL}, please retrieve and save it, after destroy the email\n'
                )
                time.sleep(3)
                General.run_cmd(
                    f'echo " DANGER here you will find your private key attached for your device, destroy this mail and its contents instantly." | mail -s "Private key for: {General.USER} on {General.HOSTNAME}" {EMAIL} -A {key_path}'
                )
            else:
                General.error_message(
                    'A key pair for the current user yet exists')
        else:
            General.change_lines(
                f_ssh_config,
                _19=['#PermitRootLogin yes', 'PermitRootLogin no\n'],
                _20=['PermitRootLogin yes', 'PermitRootLogin no\n'])

        General.run_cmd('groupadd sshusers')
        General.output_message("which user do you want to have ssh enabled?")
        while True:
            user = General.input_message("User to enable ssh  [S to skip]: ")
            if user.upper() in ['S', 'SKIP']: break

            if not UsersConfig.user_exists(user):
                General.error_message("User doesn't exists")
            else:
                General.run_cmd(f'usermod -a -G sshusers {user}')
                generate_key_for_user = General.answer(
                    f'[{user}] Do you want a ssh key pair for this user?')
                if generate_key_for_user:
                    key_path = f'/home/{user}/.ssh/id_rsa'
                    if not os.path.exists(f'/home/{user}/.ssh'):
                        os.mkdir(f'/home/{user}/.ssh')
                    if not os.path.exists(key_path):
                        key_pass = General.input_message(
                            'Enter a passphrase for the key (empty for no passphrase):'
                        )
                        General.run_cmd(
                            f'ssh-keygen -C "{EMAIL}" -b 2048 -t rsa -f {key_path} -q -N "{key_pass}"'
                        )
                        General.warning_message(
                            f'[ALERT] your private key has been sent by email to {EMAIL}, please retrieve and save it, after destroy the email\n'
                        )
                        time.sleep(3)
                        General.run_cmd(
                            f'echo " DANGER here you will find your private key attached for your device, destroy this mail and its contents instantly." | mail -s "Private key for: {user} on {General.HOSTNAME}" {EMAIL} -A {key_path}'
                        )
                    else:
                        General.error_message(
                            f'A key pair for the user "{user}" yet exists')

        General.change_lines(
            f_ssh_config,
            _1=['Port', f"Port {SSH_PORT}\n"],
            _2=['#Port', f"Port {SSH_PORT}\n"],
            _3=['ClientAliveCountMax', "ClientAliveCountMax 0\n"],
            _4=['#ClientAliveCountMax', "ClientAliveCountMax 0\n"],
            _5=['ClientAliveInterval', "ClientAliveInterval 300\n"],
            _6=['#ClientAliveInterval', "ClientAliveInterval 300\n"],
            _7=['LoginGraceTime', "LoginGraceTime 30\n"],
            _8=['#LoginGraceTime', "LoginGraceTime 30\n"],
            _9=['MaxAuthTries', "MaxAuthTries 2\n"],
            _10=['#MaxAuthTries', "MaxAuthTries 2\n"],
            _11=['MaxSessions', "MaxSessions 2\n"],
            _12=['#MaxSessions', "MaxSessions 2\n"],
            _13=['MaxStartups', "MaxStartups 2\n"],
            _14=['#MaxStartups', "MaxStartups 2\n"],
            _15=['PasswordAuthentication', "PasswordAuthentication no\n"],
            _16=['#PasswordAuthentication', "PasswordAuthentication no\n"],
            _17=['AllowGroups', "AllowGroups sshusers\n"],
            _18=['#AllowGroups', "AllowGroups sshusers\n"],
        )

        General.output_message('These changes have been made to the config')
        General.warning_message('/etc/ssh/sshd_config')
        General.output_message(
            f'''If u need more advanced options feel free to modify it.
    - Port                      {SSH_PORT};
    - ClientAliveCountMax                0;
    - ClientAliveInterval              300;
    - LoginGraceTime                    30;
    - MaxAuthTries                       2;
    - MaxSessions                        2;
    - MaxStartups                        2;
    - PasswordAuthentication            no;
    - AllowGroups                 sshusers;
    - PermitRootLogin                   no;
''')

        General.output_message(
            'removing all Diffie-Hellman keys that are less than 3072 bits long'
        )
        General.run_cmd(
            "awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp")
        General.run_cmd('mv /etc/ssh/moduli.tmp /etc/ssh/moduli')

        response = General.answer('do you want to enable 2FA/MFA for SSH?')
        if response:
            General.warning_message(
                'Note: a user will only need to enter their 2FA/MFA code if they are logging on with their password but not if they are using SSH public/private keys.\n'
            )
            General.run_cmd('apt install libpam-google-authenticator -y')
            General.warning_message(
                '\n[ALERT]  Notice this can not run as root, at the next machine restart RUN "google-authenticator"\n'
            )
            time.sleep(5)
            General.output_message(
                'Select default option (y in most cases) for all the questions it asks and remember to save the emergency scratch codes.'
            )
            time.sleep(2)
            General.run_cmd(
                'echo -e "\nauth       required     pam_google_authenticator.so nullok         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | tee -a /etc/pam.d/sshd'
            )