Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small changes + new script (in beta/incomplete) #18

Merged
merged 7 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .deepsource.toml

This file was deleted.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

This repository is a collection of scripts designed to secure/harden Linux based Distributions.

For information on each of the scripts, visit the [repo wiki](https://github.com/StrangeRanger/linux-security-scripts/wiki). Each page will provide information on the script in question, example output, and a changelog.
<!-- TODO: Add a list of all avaliable scripts and what they do. -->

## Getting Started

Expand All @@ -26,10 +26,10 @@ A majority of the scripts will require root privilege to be executed:

All of the scripts should work on most, if not all Linux Distributions. With that said, below is a list of Linux Distributions that the scripts have been officially tested and are confirmed to work on.

| Distributions | Distro Versions |
| ------------- | --------------- |
| Ubuntu | 22.04, 20.04 |
| Debian | 10, 9 |
| Distributions | Distro Versions |
| ------------- | ---------------------- |
| Ubuntu | 24.04, 22.04, 20.04 |
| Debian | 11, 10, 9 |

## Other Resources

Expand Down
11 changes: 4 additions & 7 deletions auditing/Lynis Installer/lynis-installer.bash
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
#!/bin/bash
#
# Name: lynis-installer.bash
#
# Description:
# This script downloads a security auditing tool called Lynis, designed to scan a
# system and identify security issues, and provides recommendations on how to better
# secure it. Lynis, unless an error is encountered, will always be downloaded to the
# user's root directory (/home/USERNAME/).
# This script downloads a security auditing tool called Lynis. It is designed to scan a
# system, identify security issues, and provide recommendations on how to better secure
# it. Unless an error is encountered, Lynis will always be downloaded to the current
# user's root directory (`/home/USERNAME/`).
#
# Version: v1.0.7
# License: MIT License
Expand Down
5 changes: 1 addition & 4 deletions hardening/Root Locker/root-locker.bash
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#!/bin/bash
#
# Name: root-locker.bash
#
# Description:
# This script locks the root account, preventing users from direct logins as root.
# This script locks the root account, preventing users from directly logging in as root.
#
# Note:
# Locking the root account doesn't prevent users from using something like `sudo su`
Expand Down
25 changes: 10 additions & 15 deletions hardening/SSHD Hardening/harden-sshd.bash
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
#!/bin/bash
#
# Name: harden-sshd.bash
#
# Description:
# This script hardens the sshd-server, by modifying it's configuration file
# (sshd_config).
# This script hardens the ssh server by modifying its configuration file, 'sshd_config'.
#
# Note:
# This configures sshd_config to the recommendations of the security auditing tool
# knonw as Lynis (https://github.com/CISOfy/lynis).
# These configurations align with the recommendations of the security auditing tool
# known as Lynis (https://github.com/CISOfy/lynis).
#
# Version: v2.0.0
# License: MIT License
Expand All @@ -31,11 +27,11 @@ C_NC="$(printf '\033[0m')"
readonly C_GREEN C_CYAN C_RED C_NC

## Short-hand colorized messages.
C_SUCCESS="${C_GREEN}==>${C_NC} "
C_WARNING="${C_YELLOW}==>${C_NC} "
C_ERROR="${C_RED}ERROR:${C_NC} "
C_INFO="${C_BLUE}==>${C_NC} "
C_NOTE="${C_CYAN}==>${C_NC} "
readonly C_SUCCESS="${C_GREEN}==>${C_NC} "
readonly C_WARNING="${C_YELLOW}==>${C_NC} "
readonly C_ERROR="${C_RED}ERROR:${C_NC} "
readonly C_INFO="${C_BLUE}==>${C_NC} "
readonly C_NOTE="${C_CYAN}==>${C_NC} "

# Associative array containing the configuration settings for sshd_config.
declare -A C_SSHD_CONFIG=(
Expand Down Expand Up @@ -83,10 +79,9 @@ readonly C_SSHD_CONFIG


####
# Description:
# Cleanly exit the script.
# Cleanly exit the script.
#
# Arguments:
# PARAMETERS:
# - $1: exit_code (Required)
# - The exit code to exit the script with.
clean_exit() {
Expand Down
208 changes: 208 additions & 0 deletions hardening/UFW Cloudflare/ufw-cloudflare.bash
100644 → 100755
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#!/bin/bash
#
# Sets up UFW to only allow HTTP and HTTPS traffic from Cloudflare's IP ranges.
#
# Version: v1.0.0-beta.1
# License: MIT License
# Copyright (c) 2024 Hunter T. (StrangeRanger)
#
########################################################################################
####[ Global Variables ]################################################################


## URL for retrieving the current Cloudflare IP ranges.
readonly C_CLOUDFLARE_IPV4_RANGES_URL="https://www.cloudflare.com/ips-v4/"
readonly C_CLOUDFLARE_IPV6_RANGES_URL="https://www.cloudflare.com/ips-v6/"

current_cloudflare_rule_numbers=()
current_cloudflare_ip_ranges=()
new_cloudflare_ip_ranges=()
stage=0


####[ Function ]########################################################################


####
# Check if a UFW rule exists for a specific IP address and port.
#
# PARAMETERS:
# - $1: ip (Required)
# - The IP address to check.
# - $2: port (Required)
# - The port to check.
#
# RETURN:
# - 0: The rule exists.
# - ?: The rule does not exist.
ufw_rule_exists() {
local ip="$1"
local port="$2"

ufw status | grep -qE "^${port}.*ALLOW.*${ip}.*$"
}

####
# Retrieves the rule number of all Cloudflare IP rules currently set in UFW, then
# stores them in an array.
#
# PARAMETERS:
# - $1: string_to_grep (Required)
# - The string to grep for in the UFW status output.
# - Acceptable values:
# - 0: "Cloudflare IP"
# - 1: "Temporary rule"
get_set_cloudflare_rule_numbers() {
if (( $1 == 0 )); then
local string_to_grep="Cloudflare IP"
elif (( $1 == 1 )); then
local string_to_grep="Temporary rule"
else
echo "Invalid argument: $1"
exit 1
fi

mapfile -t current_cloudflare_rule_numbers < <(
ufw status numbered \
| grep "$string_to_grep" \
| awk -F'[][]' '{print $2}' \
| sort -rn
)
}

####
# Retrieves the IP addresses of all Cloudflare IP rules currently set in UFW, then
# stores them in an array.
get_set_cloudflare_ip_ranges() {
while IFS= read -r line; do
ip=$(echo "$line" | awk '{print $3}') # Extract the IP address.
current_cloudflare_ip_ranges+=("$ip")
done < <(sudo ufw status | grep "Cloudflare IP")
}

####
# Set the new Cloudflare IP ranges in UFW, retrieved from the Cloudflare website.
set_new_cloudflare_ip_ranges() {
for ip in "${new_cloudflare_ip_ranges[@]}"; do
ufw_rule_exists "$ip" "80,443" \
|| ufw allow from "$ip" to any port 80,443 proto tcp comment "Cloudflare IP"
done
}

####
# Restores the previous (non-new) Cloudflare IP ranges in UFW.
restore_current_cloudflare_ip_ranges() {
for ip in "${current_cloudflare_ip_ranges[@]}"; do
ufw_rule_exists "$ip" "80,443" \
|| ufw allow from "$ip" to any port 80,443 proto tcp comment "Cloudflare IP"
done
}

####
# Deletes all Cloudflare IP rules currently set in UFW.
delete_set_cloudflare_rules() {
get_set_cloudflare_rule_numbers "0"

for rule_num in "${current_cloudflare_rule_numbers[@]}"; do
# TODO: Add configuration option to confirm deletion.
yes | ufw delete "$rule_num"
done
}

####
# Cleanup function to close ports 80 and 443 from any IP address.
cleanup() {
case $stage in
2)
delete_set_cloudflare_rules "1"
;;
3)
echo "Potential error or interruption detected."
echo "Restoring the previous Cloudflare IP ranges..."
restore_current_cloudflare_ip_ranges
delete_set_cloudflare_rules "1"
;;
4)
echo "Potential error or interruption detected."
echo "Restoring the previous Cloudflare IP ranges..."
delete_new_cloudflare_ip_ranges
restore_current_cloudflare_ip_ranges
delete_set_cloudflare_rules "1"
;;
5)
# Continue, as we are too far along to realistically undo anything
;;
*)
echo "Invalid stage: $stage"
;;
esac
}


####[ Trap Logic ]######################################################################


trap cleanup EXIT


####[ Main ]############################################################################


###
### [ Initial Setup ]
###

stage=1

get_set_cloudflare_ip_ranges
mapfile -t new_cloudflare_ip_ranges < <(curl -s "$C_CLOUDFLARE_IPV4_RANGES_URL")
mapfile -t new_cloudflare_ipv6_ranges < <(curl -s "$C_CLOUDFLARE_IPV6_RANGES_URL")

new_cloudflare_ip_ranges+=("${new_cloudflare_ipv6_ranges[@]}")
unset new_cloudflare_ipv6_ranges

###
### [ Opening ports 80 and 443 from any IP address ]
###

stage=2

echo "Temporarily opening ports 80 and 443 from any IP address..."
ufw allow from any to any port 80,443 proto tcp comment "Temporary rule"
sleep 1 # Wait for the rule to take effect.

###
### [ Removing the existing Cloudflare IP ranges ]
###

stage=3

if (( ${#current_cloudflare_ip_ranges[@]} != 0 )); then
echo "Removing the existing Cloudflare IP ranges..."
delete_set_cloudflare_rules
fi

sleep 1 # Wait for the rule to take effect.

###
### [ Adding the new Cloudflare IP ranges ]
###

stage=4

echo "Adding the new Cloudflare IPv4 and IPv6 ranges..."
set_new_cloudflare_ip_ranges
sleep 1 # Wait for the rule to take effect.

###
### [ Finalizing ]
###

stage=5

echo "Removing temporary rules..."
ufw delete allow from any to any port 80,443 proto tcp
sleep 1 # Wait for the rule to take effect.

echo "Done."