diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/setup/balancer.sh b/setup/balancer.sh new file mode 100644 index 0000000..daa24c9 --- /dev/null +++ b/setup/balancer.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Author: Martijn de Boer + +if [[ $EUID -ne 0 ]]; then + echo "You must be a root user" 2>&1 + exit 1 +fi + +if [[ ! -f /etc/debian_version ]]; then + echo "This script only works on Debian" + exit 1 +fi + +apt update && apt upgrade -y && apt install -y \ + caddy \ + wireguard \ + jq \ + openssh-server \ + ufw + +ufw default deny incoming +ufw default allow outgoing +ufw allow http +ufw allow https +ufw enable + +mkdir -p /root/tunnel-manager /etc/tunnel-manager/domains.d + +read -p "Reboot the system now? " -n 1 -r REPLY_REBOOT +case "$REPLY_REBOOT" in + y|Y ) echo "yes";; + n|N ) echo "no";; + * ) echo "invalid";; +esac + +if [[ $REPLY_REBOOT =~ ^[Yy]$ ]] +then + reboot +fi \ No newline at end of file diff --git a/setup/controlplane.sh b/setup/controlplane.sh new file mode 100644 index 0000000..f5f261d --- /dev/null +++ b/setup/controlplane.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Author: Martijn de Boer + +if [[ $EUID -ne 0 ]]; then + echo "You must be a root user" 2>&1 + exit 1 +fi + +if [[ ! -f /etc/debian_version ]]; then + echo "This script only works on Debian" + exit 1 +fi + +apt update && apt upgrade -y && apt install -y \ + caddy \ + wireguard \ + jq \ + openssh-server \ + ufw + +ufw default deny incoming +ufw default allow outgoing +ufw allow http +ufw allow https +ufw allow 51820/udp +ufw enable + +mkdir -p /root/tunnel-manager /etc/tunnel-manager/domains.d + +cd ../tunnel-manager +cp add-domain.sh update-tunnels.sh generate-wireguard.sh /root/tunnel-manager/ +chmod +x /root/tunnel-manager/*.sh + +echo '{"domains":{}}' > /etc/tunnel-manager/domains.json + +read -p "Reboot the system now? " -n 1 -r REPLY_REBOOT +case "$REPLY_REBOOT" in + y|Y ) echo "yes";; + n|N ) echo "no";; + * ) echo "invalid";; +esac + +if [[ $REPLY_REBOOT =~ ^[Yy]$ ]] +then + reboot +fi \ No newline at end of file diff --git a/tunnel-manager/Caddyfile b/tunnel-manager/Caddyfile new file mode 100644 index 0000000..9b17bff --- /dev/null +++ b/tunnel-manager/Caddyfile @@ -0,0 +1,40 @@ +{ + email abuse@habalancer.tld + + log { + output file /var/log/caddy/access.log + format json + } + + servers { + timeouts { + read_body 10s + read_header 5s + write 10s + idle 2m + } + } +} + +import /etc/tunnel-manager/domains.d/*.conf + +(proxy_settings) { + header { + Cache-Control "public, max-age=3600, stale-while-revalidate=86400" + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + X-Content-Type-Options "nosniff" + Referrer-Policy "strict-origin-when-cross-origin" + } + + @cached_routes { + path /static/* /assets/* /images/* /css/* /js/* + } + + handle @cached_routes { + cache { + ttl 1h + stale 24h + storage file /tmp/caddy-cache + } + } +} \ No newline at end of file diff --git a/tunnel-manager/add-domain.sh b/tunnel-manager/add-domain.sh new file mode 100644 index 0000000..23d22c7 --- /dev/null +++ b/tunnel-manager/add-domain.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Author: Martijn de Boer + +if [[ $EUID -ne 0 ]]; then + echo "You must be a root user" 2>&1 + exit 1 +fi + +if [[ ! -f /etc/debian_version ]]; then + echo "This script only works on Debian" + exit 1 +fi + +set -e + +DOMAINS_CONFIG="/etc/tunnel-manager/domains.json" + +add_domain() { + local domain="$1" + local target_ips=("${@:2}") + + [[ -z "$domain" ]] && { echo "Error: Domain required"; exit 1; } + [[ ${#target_ips[@]} -eq 0 ]] && { echo "Error: At least one target IP required"; exit 1; } + + jq --arg domain "$domain" \ + --arg ipv4 "${target_ips[0]}" \ + --arg ipv6 "${target_ips[1]:-}" \ + '.domains[$domain] = { + "ipv4": $ipv4, + "ipv6": $ipv6, + "added_at": now + }' "$DOMAINS_CONFIG" > tmp.json && mv tmp.json "$DOMAINS_CONFIG" + + /root/tunnel-manager/update-tunnels.sh +} + +list_domains() { + jq '.' "$DOMAINS_CONFIG" +} + +remove_domain() { + local domain="$1" + jq "del(.domains[\"$domain\"])" "$DOMAINS_CONFIG" > tmp.json && mv tmp.json "$DOMAINS_CONFIG" + /root/tunnel-manager/update-tunnels.sh +} + +case "$1" in + add) add_domain "${@:2}" ;; + list) list_domains ;; + remove) remove_domain "$2" ;; + *) + echo "Usage: $0 {add|list|remove} [domain] [ipv4] [ipv6]" + exit 1 + ;; +esac \ No newline at end of file diff --git a/tunnel-manager/domains.d/.gitignore b/tunnel-manager/domains.d/.gitignore new file mode 100644 index 0000000..804911a --- /dev/null +++ b/tunnel-manager/domains.d/.gitignore @@ -0,0 +1 @@ +*.conf \ No newline at end of file diff --git a/tunnel-manager/generate-wireguard.sh b/tunnel-manager/generate-wireguard.sh new file mode 100644 index 0000000..38bfa5a --- /dev/null +++ b/tunnel-manager/generate-wireguard.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Author: Martijn de Boer + +if [[ $EUID -ne 0 ]]; then + echo "You must be a root user" 2>&1 + exit 1 +fi + +if [[ ! -f /etc/debian_version ]]; then + echo "This script only works on Debian" + exit 1 +fi + +set -e + +generate_wireguard_config() { + local server_index="$1" + local private_key=$(wg genkey) + local public_key=$(echo "$private_key" | wg pubkey) + + cat > "/etc/wireguard/wg0-$server_index.conf" <&1 + exit 1 +fi + +if [[ ! -f /etc/debian_version ]]; then + echo "This script only works on Debian" + exit 1 +fi + +set -e + +TUNNEL_SERVERS=("10.0.0.2" "10.0.0.3" "10.0.0.4") +SSH_KEY="/root/.ssh/tunnel_key" + +update_tunnel_configs() { + local server="$1" + + scp -i "$SSH_KEY" /etc/tunnel-manager/Caddyfile root@"$server":/etc/caddy/Caddyfile + + ssh -i "$SSH_KEY" root@"$server" "systemctl reload caddy" +} + +for server in "${TUNNEL_SERVERS[@]}"; do + update_tunnel_configs "$server" +done \ No newline at end of file