Skip to content
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
64 changes: 40 additions & 24 deletions scripts/setup/setup.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/bash

# ============================================
# Silver Mail Setup Script - This script is responsible for generating all the configs for our services.
# Silver Mail Setup Script
# Generates all configurations for services
# ============================================

# Colors
Expand All @@ -11,21 +12,19 @@ readonly YELLOW="\033[1;33m"
readonly RED="\033[0;31m"
readonly NC="\033[0m" # No Color

# Get the script directory (where the scripts are located)
# Get directories
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Services directory contains config-scripts
readonly SERVICES_DIR="$(cd "${SCRIPT_DIR}/../../services" && pwd)"
# Conf directory contains config files
readonly CONF_DIR="$(cd "${SCRIPT_DIR}/../../conf" && pwd)"
readonly CONFIG_FILE="${CONF_DIR}/silver.yaml"
# Read silver-config from the configuration file

# Read config repository URL
readonly SILVER_CONFIG=$(grep -m 1 '^config-url:' "${CONFIG_FILE}" | sed 's/config-url: //' | xargs)

# ASCII Banner
echo -e "${CYAN}"
cat <<'EOF'


SSSSSSSSSSSSSSS iiii lllllll
SS:::::::::::::::S i::::i l:::::l
S:::::SSSSSS::::::S iiii l:::::l
Expand All @@ -50,39 +49,56 @@ echo
echo -e " πŸš€ ${GREEN}Welcome to the Silver Mail System Setup${NC}"
echo "---------------------------------------------"

MAIL_DOMAIN=""

# ================================
# Step 1: Domain Configuration
# ================================
echo -e "\n${YELLOW}Step 1/3: Configure domain name${NC}"
echo -e "\n${YELLOW}Step 1/3: Configure domain names${NC}"

# Extract primary (first) domain from the domains list in silver.yaml
readonly MAIL_DOMAIN=$(grep -m 1 '^\s*-\s*domain:' "${CONFIG_FILE}" | sed 's/.*domain:\s*//' | xargs)
# Extract ALL domains
readonly MAIL_DOMAINS=$(grep '^\s*-\s*domain:' "${CONFIG_FILE}" | sed 's/.*domain:\s*//' | xargs)

# Validate if MAIL_DOMAIN is empty
if [[ -z "${MAIL_DOMAIN}" ]]; then
echo -e "${RED}ERROR: Domain name is not configured. Please set it in '${CONFIG_FILE}'.${NC}"
# Validate domains exist
if [[ -z "${MAIL_DOMAINS}" ]]; then
echo -e "${RED}ERROR: No domains configured. Please set them in '${CONFIG_FILE}'.${NC}"
exit 1
else
echo "Domain name found: ${MAIL_DOMAIN}"
fi

if ! [[ "${MAIL_DOMAIN}" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo -e "${RED}βœ— ERROR: '${MAIL_DOMAIN}' does not look like a valid domain name.${NC}"
exit 1
fi
# Primary domain (first one)
readonly PRIMARY_DOMAIN=$(echo "${MAIL_DOMAINS}" | awk '{print $1}')

echo "Primary domain: ${PRIMARY_DOMAIN}"
echo "Configured domains:"

for domain in ${MAIL_DOMAINS}; do
echo " - ${domain}"
done

# Validate each domain
for domain in ${MAIL_DOMAINS}; do
if ! [[ "${domain}" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo -e "${RED}βœ— ERROR: '${domain}' does not look like a valid domain name.${NC}"
exit 1
fi
done

# ================================
# Step 2: Config Generation
# Step 2: Clone Config Repository
# ================================
echo -e "\n${YELLOW}Step 2/3: Clone configuration repository${NC}"

git clone ${SILVER_CONFIG} "${SERVICES_DIR}/silver-config"
if [ -d "${SERVICES_DIR}/silver-config" ]; then
echo "Configuration repository already exists. Skipping clone."
else
git clone "${SILVER_CONFIG}" "${SERVICES_DIR}/silver-config"
fi

# ================================
# Step 3: Generate Service Configurations
# Step 3: Generate Configurations
# ================================
echo -e "\n${YELLOW}Step 3/3: Generate service configurations${NC}"

bash ${SERVICES_DIR}/config-scripts/gen-configs.sh
bash "${SERVICES_DIR}/config-scripts/gen-configs.sh"

echo
echo -e "${GREEN}βœ“ Setup completed successfully!${NC}"
echo
130 changes: 66 additions & 64 deletions services/config-scripts/gen-certbot-certs.sh
Original file line number Diff line number Diff line change
@@ -1,101 +1,103 @@
#!/bin/bash
#
# This script initializes the certbot certs
# This script initializes certbot certificates with wildcard support
# for ALL domains defined in silver.yaml
#

# --- Sanity Checks & Configuration ---
set -euo pipefail

# Define constant paths
# --- Paths ---
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly ROOT_DIR="$(dirname "$SCRIPT_DIR")"
readonly SILVER_YAML_FILE="${ROOT_DIR}/../conf/silver.yaml"
readonly CONFIGS_PATH="${ROOT_DIR}/silver-config/certbot"
readonly LETSENCRYPT_PATH="${ROOT_DIR}/silver-config/certbot/keys"
readonly DKIM_KEY_SIZE=2048

# --- Main Logic ---
# Extract ALL domains from the domains list in silver.yaml
# Extract domains from silver.yaml
DOMAINS=$(grep '^\s*-\s*domain:' "${SILVER_YAML_FILE}" | sed 's/.*domain:\s*//' | xargs)

if [ -z "$DOMAINS" ]; then
echo "❌ Error: No domains found in ${SILVER_YAML_FILE}"
exit 1
fi

# Get primary domain for certificate name and email
PRIMARY_DOMAIN=$(echo "$DOMAINS" | awk '{print $1}')

echo "========================================="
echo " Multi-Domain Certificate Setup"
echo " Wildcard Certificate Setup"
echo "========================================="
echo ""
echo "Domains to be covered by this certificate:"

echo "Domains detected:"
for domain in $DOMAINS; do
echo " β€’ $domain"
echo " β€’ $domain"
done
echo " β€’ mail.$PRIMARY_DOMAIN"

echo ""
echo "Using HTTP-01 challenge (port 80 required)"
echo "Certificate will be non-interactive"
echo "Each domain will receive:"
echo " - domain certificate"
echo " - wildcard subdomain certificate"
echo ""

if [ -d "${LETSENCRYPT_PATH}/etc/live/${PRIMARY_DOMAIN}" ]; then
echo "An existing certificate was found for ${PRIMARY_DOMAIN}."
read -p "Do you want to attempt to renew it? (y/n): " RENEW_CHOICE
if [[ "$RENEW_CHOICE" == "y" || "$RENEW_CHOICE" == "Y" ]]; then
echo "Attempting renewal..."
docker run --rm \
-p 80:80 \
-v "${LETSENCRYPT_PATH}/etc:/etc/letsencrypt" \
-v "${LETSENCRYPT_PATH}/lib:/var/lib/letsencrypt" \
-v "${LETSENCRYPT_PATH}/log:/var/log/letsencrypt" \
certbot/certbot \
renew
exit 0
else
echo "Skipping renewal. If you want a new certificate, please remove the directory: ${LETSENCRYPT_PATH}/etc/live/${PRIMARY_DOMAIN}"
exit 0
fi
fi
read -p "Press Enter to continue..."

echo "No existing certificate found. Requesting a new multi-domain certificate..."
echo "========================================="
echo ""
# Loop through each domain
for DOMAIN in $DOMAINS; do

read -p "Press Enter to continue with certificate request..."
echo ""
echo "========================================="
echo "Processing domain: ${DOMAIN}"
echo "========================================="

if [ -d "${LETSENCRYPT_PATH}/etc/live/${DOMAIN}" ]; then
echo "Existing certificate found for ${DOMAIN}"
read -p "Attempt renewal for ${DOMAIN}? (y/n): " RENEW_CHOICE

if [[ "$RENEW_CHOICE" =~ ^[Yy]$ ]]; then
docker run --rm \
-v "${LETSENCRYPT_PATH}/etc:/etc/letsencrypt" \
-v "${LETSENCRYPT_PATH}/lib:/var/lib/letsencrypt" \
-v "${LETSENCRYPT_PATH}/log:/var/log/letsencrypt" \
certbot/certbot renew --cert-name "${DOMAIN}"
else
echo "Skipping ${DOMAIN}"
fi

continue
fi

echo ""
echo "Certificate will cover:"
echo " β€’ ${DOMAIN}"
echo " β€’ *.${DOMAIN}"
echo ""

echo "DNS verification will be required."
echo "You will need to create TXT records manually."
echo ""

read -p "Press Enter to request certificate for ${DOMAIN}..."

docker run -it --rm \
-v "${LETSENCRYPT_PATH}/etc:/etc/letsencrypt" \
-v "${LETSENCRYPT_PATH}/lib:/var/lib/letsencrypt" \
-v "${LETSENCRYPT_PATH}/log:/var/log/letsencrypt" \
certbot/certbot \
certonly \
--manual \
--preferred-challenges dns \
--agree-tos \
--email "admin@${DOMAIN}" \
--key-type rsa \
-d "${DOMAIN}" \
-d "*.${DOMAIN}"

echo ""
echo "βœ… Certificate generated for ${DOMAIN}"

# Build the certbot command with all domains
DOMAIN_ARGS=""
for domain in $DOMAINS; do
DOMAIN_ARGS="$DOMAIN_ARGS -d $domain"
done
# Add mail subdomain at the end
DOMAIN_ARGS="$DOMAIN_ARGS -d mail.$PRIMARY_DOMAIN"

# Request certificate using HTTP-01 challenge for all domains
docker run --rm \
-p 80:80 \
-v "${LETSENCRYPT_PATH}/etc:/etc/letsencrypt" \
-v "${LETSENCRYPT_PATH}/lib:/var/lib/letsencrypt" \
-v "${LETSENCRYPT_PATH}/log:/var/log/letsencrypt" \
certbot/certbot \
certonly \
--standalone \
--non-interactive \
--agree-tos \
--email "admin@${PRIMARY_DOMAIN}" \
--key-type rsa \
--keep-until-expiring \
--expand \
$DOMAIN_ARGS

echo ""
echo "========================================="
echo "βœ… Certificate request completed!"
echo "πŸŽ‰ All certificate operations completed!"
echo "========================================="
echo ""
echo "Certificate files located at:"
echo " ${LETSENCRYPT_PATH}/etc/live/${PRIMARY_DOMAIN}/"
echo "Certificates stored in:"
echo "${LETSENCRYPT_PATH}/etc/live/"
Loading
Loading