- setup-host.sh: add SILO_DB_HOST and SILO_MINIO_HOST env var overrides, update Go version from 1.23 to 1.24, expand generated silod.env template with session secret and admin password fields - deploy.sh: add SILO_DEPLOY_TARGET and SILO_DB_HOST env var overrides for target host and database host - setup-ipa-nginx.sh: replace hardcoded hostname with SILO_HOSTNAME env var (default: silo.example.internal), parameterize SILO_PORT, use variable substitution in nginx config template All scripts retain backward-compatible defaults.
359 lines
9.6 KiB
Bash
Executable File
359 lines
9.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Silo IPA Enrollment and Nginx Setup Script
|
|
# Enrolls host in FreeIPA, obtains certificates, and configures nginx reverse proxy
|
|
#
|
|
# Usage:
|
|
# sudo ./scripts/setup-ipa-nginx.sh
|
|
#
|
|
# Prerequisites:
|
|
# - FreeIPA server at ipa.example.internal
|
|
# - DNS configured for the silo host (set SILO_HOSTNAME to override default)
|
|
# - Admin credentials for IPA enrollment
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# Configuration
|
|
IPA_SERVER="${IPA_SERVER:-ipa.example.internal}"
|
|
IPA_DOMAIN="${IPA_DOMAIN:-example.internal}"
|
|
IPA_REALM="${IPA_REALM:-KINDRED.INTERNAL}"
|
|
SILO_HOSTNAME="${SILO_HOSTNAME:-silo.example.internal}"
|
|
CERT_DIR="/etc/ssl/silo"
|
|
SILO_PORT="${SILO_PORT:-8080}"
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
|
log_success() { echo -e "${GREEN}[OK]${NC} $*"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
|
die() { log_error "$*"; exit 1; }
|
|
|
|
# Check root
|
|
if [[ $EUID -ne 0 ]]; then
|
|
die "This script must be run as root (use sudo)"
|
|
fi
|
|
|
|
log_info "============================================"
|
|
log_info "Silo IPA Enrollment and Nginx Setup"
|
|
log_info "============================================"
|
|
echo ""
|
|
|
|
# Detect package manager
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
PKG_MANAGER="apt"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
PKG_MANAGER="dnf"
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
PKG_MANAGER="yum"
|
|
else
|
|
die "Unsupported package manager"
|
|
fi
|
|
|
|
log_info "Detected package manager: ${PKG_MANAGER}"
|
|
|
|
#
|
|
# Step 1: Install IPA client and nginx
|
|
#
|
|
log_info "Installing packages..."
|
|
|
|
case ${PKG_MANAGER} in
|
|
apt)
|
|
apt-get update -qq
|
|
apt-get install -y -qq freeipa-client nginx certmonger
|
|
;;
|
|
dnf|yum)
|
|
${PKG_MANAGER} install -y -q freeipa-client nginx certmonger
|
|
;;
|
|
esac
|
|
|
|
log_success "Packages installed"
|
|
|
|
#
|
|
# Step 2: Set hostname
|
|
#
|
|
log_info "Setting hostname to ${SILO_HOSTNAME}..."
|
|
hostnamectl set-hostname "${SILO_HOSTNAME}"
|
|
log_success "Hostname set"
|
|
|
|
#
|
|
# Step 3: Enroll in FreeIPA
|
|
#
|
|
if ipa-client-install --version >/dev/null 2>&1 && klist -k /etc/krb5.keytab >/dev/null 2>&1; then
|
|
log_info "Host appears to already be enrolled in IPA"
|
|
else
|
|
log_info "Enrolling in FreeIPA domain..."
|
|
log_warn "You will be prompted for IPA admin credentials"
|
|
echo ""
|
|
|
|
ipa-client-install \
|
|
--server="${IPA_SERVER}" \
|
|
--domain="${IPA_DOMAIN}" \
|
|
--realm="${IPA_REALM}" \
|
|
--hostname="${SILO_HOSTNAME}" \
|
|
--mkhomedir \
|
|
--enable-dns-updates \
|
|
--unattended \
|
|
--force-join || {
|
|
log_warn "Unattended enrollment failed, trying interactive mode..."
|
|
ipa-client-install \
|
|
--server="${IPA_SERVER}" \
|
|
--domain="${IPA_DOMAIN}" \
|
|
--realm="${IPA_REALM}" \
|
|
--hostname="${SILO_HOSTNAME}" \
|
|
--mkhomedir \
|
|
--enable-dns-updates
|
|
}
|
|
|
|
log_success "Enrolled in FreeIPA"
|
|
fi
|
|
|
|
#
|
|
# Step 4: Create certificate directory
|
|
#
|
|
log_info "Setting up certificate directory..."
|
|
mkdir -p "${CERT_DIR}"
|
|
chmod 750 "${CERT_DIR}"
|
|
chown root:nginx "${CERT_DIR}" 2>/dev/null || chown root:www-data "${CERT_DIR}"
|
|
log_success "Certificate directory created: ${CERT_DIR}"
|
|
|
|
#
|
|
# Step 5: Request certificate from IPA CA
|
|
#
|
|
log_info "Requesting SSL certificate from IPA CA..."
|
|
|
|
# Check if certificate already exists and is managed by certmonger
|
|
if getcert list | grep -q "${CERT_DIR}/silo.crt"; then
|
|
log_info "Certificate already managed by certmonger"
|
|
else
|
|
# Request new certificate
|
|
ipa-getcert request \
|
|
-f "${CERT_DIR}/silo.crt" \
|
|
-k "${CERT_DIR}/silo.key" \
|
|
-K "HTTP/${SILO_HOSTNAME}" \
|
|
-D "${SILO_HOSTNAME}" \
|
|
-N "CN=${SILO_HOSTNAME}" \
|
|
-C "systemctl reload nginx"
|
|
|
|
log_info "Waiting for certificate to be issued..."
|
|
|
|
# Wait for certificate (up to 60 seconds)
|
|
for i in {1..12}; do
|
|
if [[ -f "${CERT_DIR}/silo.crt" ]] && [[ -s "${CERT_DIR}/silo.crt" ]]; then
|
|
log_success "Certificate issued"
|
|
break
|
|
fi
|
|
sleep 5
|
|
echo -n "."
|
|
done
|
|
echo ""
|
|
|
|
if [[ ! -f "${CERT_DIR}/silo.crt" ]]; then
|
|
log_warn "Certificate not yet issued. Check with: getcert list"
|
|
fi
|
|
fi
|
|
|
|
# Set certificate permissions
|
|
if [[ -f "${CERT_DIR}/silo.key" ]]; then
|
|
chmod 640 "${CERT_DIR}/silo.key"
|
|
chown root:nginx "${CERT_DIR}/silo.key" 2>/dev/null || chown root:www-data "${CERT_DIR}/silo.key"
|
|
fi
|
|
|
|
#
|
|
# Step 6: Get IPA CA certificate for trust
|
|
#
|
|
log_info "Installing IPA CA certificate..."
|
|
if [[ -f /etc/ipa/ca.crt ]]; then
|
|
cp /etc/ipa/ca.crt "${CERT_DIR}/ca.crt"
|
|
log_success "CA certificate installed"
|
|
else
|
|
log_warn "IPA CA certificate not found at /etc/ipa/ca.crt"
|
|
fi
|
|
|
|
#
|
|
# Step 7: Configure nginx
|
|
#
|
|
log_info "Configuring nginx..."
|
|
|
|
# Backup existing config
|
|
if [[ -f /etc/nginx/sites-enabled/default ]]; then
|
|
mv /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default.bak 2>/dev/null || true
|
|
fi
|
|
|
|
# Create silo nginx config
|
|
cat > /etc/nginx/sites-available/silo << NGINX_EOF
|
|
# Silo API Server - Nginx Reverse Proxy Configuration
|
|
|
|
# Redirect HTTP to HTTPS
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name ${SILO_HOSTNAME};
|
|
|
|
# Allow certmonger/ACME challenges
|
|
location /.well-known/ {
|
|
root /var/www/html;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://\\$server_name\\$request_uri;
|
|
}
|
|
}
|
|
|
|
# HTTPS server
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${SILO_HOSTNAME};
|
|
|
|
# SSL certificates (managed by certmonger/IPA)
|
|
ssl_certificate ${CERT_DIR}/silo.crt;
|
|
ssl_certificate_key ${CERT_DIR}/silo.key;
|
|
|
|
# SSL configuration
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
ssl_prefer_server_ciphers off;
|
|
ssl_session_timeout 1d;
|
|
ssl_session_cache shared:SSL:50m;
|
|
ssl_session_tickets off;
|
|
|
|
# OCSP stapling
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
ssl_trusted_certificate ${CERT_DIR}/ca.crt;
|
|
|
|
# Security headers
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
|
|
# Logging
|
|
access_log /var/log/nginx/silo_access.log;
|
|
error_log /var/log/nginx/silo_error.log;
|
|
|
|
# Proxy settings
|
|
location / {
|
|
proxy_pass http://127.0.0.1:${SILO_PORT};
|
|
proxy_http_version 1.1;
|
|
|
|
# Headers
|
|
proxy_set_header Host \\$host;
|
|
proxy_set_header X-Real-IP \\$remote_addr;
|
|
proxy_set_header X-Forwarded-For \\$proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto \\$scheme;
|
|
proxy_set_header X-Forwarded-Host \\$host;
|
|
proxy_set_header X-Forwarded-Port \\$server_port;
|
|
|
|
# WebSocket support (for future use)
|
|
proxy_set_header Upgrade \\$http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
# Timeouts
|
|
proxy_connect_timeout 60s;
|
|
proxy_send_timeout 60s;
|
|
proxy_read_timeout 60s;
|
|
|
|
# Buffering
|
|
proxy_buffering on;
|
|
proxy_buffer_size 4k;
|
|
proxy_buffers 8 4k;
|
|
|
|
# File uploads (for CAD files)
|
|
client_max_body_size 100M;
|
|
}
|
|
|
|
# Health check endpoint (bypass proxy for monitoring)
|
|
location /nginx-health {
|
|
access_log off;
|
|
return 200 "OK\n";
|
|
add_header Content-Type text/plain;
|
|
}
|
|
}
|
|
NGINX_EOF
|
|
|
|
# Enable the site
|
|
ln -sf /etc/nginx/sites-available/silo /etc/nginx/sites-enabled/silo
|
|
|
|
# Test nginx configuration
|
|
log_info "Testing nginx configuration..."
|
|
if nginx -t; then
|
|
log_success "Nginx configuration valid"
|
|
else
|
|
die "Nginx configuration test failed"
|
|
fi
|
|
|
|
#
|
|
# Step 8: Start/restart services
|
|
#
|
|
log_info "Starting services..."
|
|
|
|
# Enable and start certmonger
|
|
systemctl enable certmonger
|
|
systemctl start certmonger
|
|
|
|
# Enable and restart nginx
|
|
systemctl enable nginx
|
|
systemctl restart nginx
|
|
|
|
log_success "Services started"
|
|
|
|
#
|
|
# Step 9: Configure firewall
|
|
#
|
|
log_info "Configuring firewall..."
|
|
|
|
if command -v ufw >/dev/null 2>&1; then
|
|
ufw allow 80/tcp
|
|
ufw allow 443/tcp
|
|
log_success "UFW rules added"
|
|
elif command -v firewall-cmd >/dev/null 2>&1; then
|
|
firewall-cmd --permanent --add-service=http
|
|
firewall-cmd --permanent --add-service=https
|
|
firewall-cmd --reload
|
|
log_success "Firewalld rules added"
|
|
else
|
|
log_warn "No firewall detected. Manually open ports 80 and 443"
|
|
fi
|
|
|
|
#
|
|
# Summary
|
|
#
|
|
echo ""
|
|
log_info "============================================"
|
|
log_info "Setup Complete!"
|
|
log_info "============================================"
|
|
echo ""
|
|
echo "Certificate status:"
|
|
getcert list -f "${CERT_DIR}/silo.crt" 2>/dev/null || echo " Check with: getcert list"
|
|
echo ""
|
|
echo "Nginx status:"
|
|
systemctl status nginx --no-pager -l | head -5
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo ""
|
|
echo "1. Verify certificate was issued:"
|
|
echo " getcert list"
|
|
echo ""
|
|
echo "2. Update silo config to use correct base URL:"
|
|
echo " sudo nano /etc/silo/config.yaml"
|
|
echo " # Change base_url to: https://${SILO_HOSTNAME}"
|
|
echo ""
|
|
echo "3. Restart silo service:"
|
|
echo " sudo systemctl restart silod"
|
|
echo ""
|
|
echo "4. Test the setup:"
|
|
echo " curl -k https://${SILO_HOSTNAME}/health"
|
|
echo " curl https://${SILO_HOSTNAME}/health # after trusting IPA CA"
|
|
echo ""
|
|
echo "5. Trust IPA CA on client machines:"
|
|
echo " # The CA cert is at: ${CERT_DIR}/ca.crt"
|
|
echo " # Or fetch from: https://${IPA_SERVER}/ipa/config/ca.crt"
|
|
echo ""
|