diff --git a/app/OS/neato_Alpine.php b/app/OS/neato_Alpine.php index ce61bd7..a287b25 100644 --- a/app/OS/neato_Alpine.php +++ b/app/OS/neato_Alpine.php @@ -5,6 +5,7 @@ final class neato { const get_opt = '/opt/'; const get_etc = '/etc/'; const get_bin = '/bin/'; + const get_super_bin = '/sbin/'; const get_user_bin = '/usr/bin/'; const get_super_user_bin = '/usr/sbin/'; const get_user_local_bin = '/usr/local/bin/'; @@ -24,11 +25,11 @@ final class neato { check_for_error($exit_code, "Unable to {$action} Service called: {$name}"); return $exit_code; } - - public static function systemctl($name, $action = 'enable') { -// exec(self::get_bin . 'systemctl ' . safe_cmd($action, $name), $output, $exit_code); -// check_for_error($exit_code, "Unable to {$action} Service called: {$name}"); -// return $exit_code; + // actions: add or del + public static function systemctl($name, $action = 'add') { + exec(self::get_super_bin . 'rc-update ' . safe_cmd($action, $name), $output, $exit_code); + check_for_error($exit_code, "Unable to {$action} Service called: {$name}"); + return $exit_code; } public static function upgrade($prog) { @@ -53,10 +54,11 @@ final class neato { } public static function add_repo($repo) { -// exec(self::get_user_bin . 'add-apt-repository -y -u ' . safe_cmd_quotes($repo) . stderr(), $output, $exit_code); -// display($output); // -u = DO UPDATE once done... -// check_for_error($exit_code, "Unable to uninstall: {$repo}"); -// return $exit_code; + exec("echo \"$repo\" >> /etc/apk/repositories"); + exec(self::get_user_bin . 'apk update' . stderr(), $output, $exit_code); + display($output); + check_for_error($exit_code, "Unable to add new repo: {$repo}"); + return $exit_code; } public static function update() { diff --git a/app/OS/neato_Ubuntu.php b/app/OS/neato_Ubuntu.php index 6700d23..7c7c2ea 100644 --- a/app/OS/neato_Ubuntu.php +++ b/app/OS/neato_Ubuntu.php @@ -47,6 +47,13 @@ final class neato { return $exit_code; } + public static function purge($prog) { + exec(self::get_user_bin . 'apt-get --purge remove -y ' . safe_cmd_quotes($prog) . stderr(), $output, $exit_code); + display($output); + check_for_error($exit_code, "Unable to uninstall: {$prog}"); + return $exit_code; + } + public static function uninstall($prog) { exec(self::get_user_bin . 'apt-get remove -y ' . safe_cmd_quotes($prog) . stderr(), $output, $exit_code); display($output); @@ -73,6 +80,15 @@ final class neato { return $exit_code; } + public static function no_sticky_bit($file) { + if (! file_exists($file)) { + return true; + } + exec(self::get_user_bin . 'chmod -s ' . safe_cmd($file), $output, $exit_code); + check_for_error($exit_code, "Unable to remove sticky bit with chmod: {$file}"); + return $exit_code; + } + public static function chmod_on_folders($dir, $kind) { if (!is_dir($dir)) { $exit_code = false; @@ -115,6 +131,61 @@ final class neato { return $exit_code; } + public static function userdel($username) { + exec(self::get_super_user_bin . 'userdel ' . safe_cmd($username), $output, $exit_code); + if ($exit_code === true || $exit_code === 0) { + display(getTermColors("Deleted user account named: $username", ['color'=>'green'])); + } + check_for_error($exit_code, "Unable to delete user: {$username}"); + return $exit_code; + } + + public static function useradd($username) { + exec(self::get_super_user_bin . 'useradd ' . safe_cmd($username), $output, $exit_code); + check_for_error($exit_code, "Unable to add new user: {$username}"); + return $exit_code; + } + + public static function lock_status($username) { + exec(self::get_user_bin . 'passwd -S ' . safe_cmd($username) . " | awk '{print $2}'", $output, $exit_code); + $sw = $output[0] ?? ""; + switch ($sw) { + case "P": echo "Account is not locked"; break; + case "NP": echo "Account has no password"; break; + case "L": echo "Account is Locked"; break; + default: echo "Account does not exist?!"; break; + } + check_for_error($exit_code, "Unable to view account: {$username}"); + return $exit_code; + } + + public static function passwd($username) { + exec(self::get_user_bin . 'passwd ' . safe_cmd($username), $output, $exit_code); + check_for_error($exit_code, "Unable to set user password: {$username}"); + return $exit_code; + } + + // Details about age of passwords + public static function chage($username) { + exec(self::get_user_bin . 'chage -l ' . safe_cmd($username), $output, $exit_code); + check_for_error($exit_code, "Unable to view user password changes: {$username}"); + return $exit_code; + } + // yyyy-mm-dd + public static function lock(string $username, string $expires_on="") { + $exp = (! empty($expires_on)) ? "--expiredate ". safe_cmd($expires_on) . " " : ""; + exec(self::get_super_user_bin . 'usermod -L '. $exp . safe_cmd($username), $output, $exit_code); + check_for_error($exit_code, "Unable to Lock user account: {$username}"); + return $exit_code; + } + + public static function unlock(string $username, string $expires_on="") { + $exp = (! empty($expires_on)) ? "--expiredate ". safe_cmd($expires_on) . " " : "--expiredate '' "; + exec(self::get_super_user_bin . 'usermod -U ' . $exp . safe_cmd($username), $output, $exit_code); + check_for_error($exit_code, "Unable to Unlock user account: {$username}"); + return $exit_code; + } + } // end of neato installer commands diff --git a/app/neato_colors.php b/app/neato_colors.php index a81cf38..bb171b9 100644 --- a/app/neato_colors.php +++ b/app/neato_colors.php @@ -56,7 +56,17 @@ function getTermColors($input, $options) { if ($bg_color !== '' && isset($bg_colors[$bg_color])) { $colored_string .= "\033[" . $bg_colors[$bg_color] . "m"; } - $colored_string .= $input . "\033[0m"; + + $str = ''; + if (is_array($input)) { + foreach ($input as $s) { + $str .= $s . PHP_EOL; + } + } else { + $str = $input; + } + + $colored_string .= $str . "\033[0m"; return $colored_string; } diff --git a/config_files/deploy_security.php b/config_files/deploy_security.php new file mode 100644 index 0000000..23195d3 --- /dev/null +++ b/config_files/deploy_security.php @@ -0,0 +1,81 @@ +'blue'])); +$remove_users = Configure::get('remove_users'); +foreach($remove_users as $del_user) { + do_command('userdel', $del_user); +} + +display(getTermColors("Removing old un-needed programs", ['color'=>'blue'])); +do_command('purge', "xinetd nis yp-tools tftpd atftpd tftpd-hpa telnetd rsh-server rsh-redone-server"); + +if ($updates === "yes") { + display("Full updates and unattended-upgrades"); + do_command('full_update'); + do_command('install', "unattended-upgrades"); + do_command('systemctl', "unattended-upgrades", "start"); + do_command('systemctl', "unattended-upgrades", "enable"); +} + +display(getTermColors("List services", ['color'=>'blue'])); +exec(neato::get_bin . 'systemctl list-unit-files --type=service', $output, $exit_code); +display($output); +unset($output); + +display(getTermColors("Verify no Accounts have Empty passwords", ['color'=>'blue'])); +exec(neato::get_bin . 'awk -F: \'($2 == "") {print}\' /etc/shadow', $output, $exit_code); +if (count($output) > 0) { + display(getTermColors($output, ['color'=>'red'])); +} else { + display(getTermColors("All accounts have passwords.", ['color'=>'green'])); +} +unset($output); + +display(getTermColors("Make sure No Non-Root accounts have UID set to 0", ['color'=>'blue'])); +exec(neato::get_bin . 'awk -F: \'($3 == "0") {print}\' /etc/passwd', $output, $exit_code); +if (count($output) > 1) { + display(getTermColors($output, ['color'=>'red'])); +} else { + display(getTermColors("All accounts are normal.", ['color'=>'green'])); +} +unset($output); + +display(getTermColors("World Writable files", ['color'=>'blue'])); +exec(neato::get_bin . 'find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print', $output, $exit_code); +if (count($output) > 0) { + display(getTermColors($output, ['color'=>'red'])); +} else { + display(getTermColors("No world writable files exists.", ['color'=>'green'])); +} +unset($output); + +display(getTermColors("Unwanted SUID and SGID bins", ['color'=>'blue'])); +exec(neato::get_bin . 'find / \( -perm -4000 -o -perm -2000 \) -print', $output, $exit_code); +if (count($output) > 0) { + display(getTermColors($output, ['color'=>'red'])); +} else { + display(getTermColors("No sticky bits found.", ['color'=>'green'])); +} +unset($output); + +display(getTermColors("No-owner Files", ['color'=>'blue'])); +exec(neato::get_bin . 'find / -xdev \( -nouser -o -nogroup \) -print', $output, $exit_code); +if (count($output) > 0) { + display(getTermColors($output, ['color'=>'red'])); +} else { + display(getTermColors("All files have owner-ship.", ['color'=>'green'])); +} +unset($output); \ No newline at end of file