diff --git a/deploy.sh b/deploy.sh index 3682621..19a088c 100644 --- a/deploy.sh +++ b/deploy.sh @@ -161,9 +161,39 @@ cyan='\033[0;36m' cyanbold='\033[1;36m' greenbold='\033[1;32m' nc='\033[0m' -underline='\033[4;0m' +underline='\033[4m' + +# Public IP (tries multiple services) +publicip="$(curl -fsS https://api.ipify.org || curl -fsS https://ifconfig.me || echo "UNKNOWN")" + +# Local IP (first non-loopback) +localip="$(hostname -I | awk '{print $1}')" # request all install parameters needed from user + +# Selection menu for external access method +echo "--------------------------------------------------------" +echo -e "${cyan}Select your external access method:${nc}" +echo "" +echo "1. Public DNS - You will need to purchase a domain name from a DNS provider and configure it." +echo "2. Local DNS, Local IP - All local devices must use $localip as their DNS. Remote devices must use WireGuard VPN." +echo "3. Local DNS, Public IP - All local devices must use $localip as their DNS. Remote devices must use $publicip as their DNS, you must forward port 53 to $localip" +echo "" + +while true; do + read -p "Enter your choice (1-3): " external_access_method + case "$external_access_method" in + 1|2|3) + echo "Selected option: $external_access_method" + break + ;; + *) + echo "Invalid choice. Please enter 1, 2, or 3." + ;; + esac +done + + # ---- User input ---- read -rp "Admin email: " adminemail < /dev/tty read -rsp "Admin password: " adminpass < /dev/tty @@ -171,6 +201,8 @@ echo read -rp "Timezone (e.g. Europe/Amsterdam): " timezone < /dev/tty read -rp "Domain (e.g. example.com): " domain < /dev/tty + + # Prompt the user to set the pause behavior (defaults to true) echo -e "${cyan}pause prompts${nc} will ask you to finish configuration for each application as the script goes." echo "disabling these means you'll have to do this after the script finishes, but allows you to run the script unattended." @@ -182,22 +214,66 @@ else SHOULD_PAUSE=true fi -# Public IP (tries multiple services) -publicip="$(curl -fsS https://api.ipify.org || curl -fsS https://ifconfig.me || echo "UNKNOWN")" -# Local IP (first non-loopback) -localip="$(hostname -I | awk '{print $1}')" -echo "--------------------------------------------------------" -echo -e "please double-check your ${cyan}DNS records${nc} to ensure they are set. the following dns records need to be set:" -echo "" -echo "|name |type |value " -echo "|@ |A |$publicip " -echo "|* |CNAME |@ " -echo "" -echo -e "once you've done this, press any key to ${underline}continue${nc}" -pause_if_enabled +if ["$external_access_method" -eq 1]; then + # Verify DNS records + echo -e "${cyan}Verifying DNS records...${nc}" + echo "" + + # Check A record + echo -e "${cyan}Checking A record for @...${nc}" + a_record_check=$(dig +short A "$domain" @8.8.8.8 | grep -c "^$publicip$") + if [ "$a_record_check" -eq 0 ]; then + echo -e "${cyan}⚠️ Warning: A record for @ is not set or not pointing to $publicip${nc}" + else + echo -e "${cyan}✅ A record for @ is correctly set to $publicip${nc}" + fi + + # Check CNAME record + echo -e "${cyan}Checking CNAME record for *...${nc}" + cname_record_check=$(dig +short CNAME "*.$domain" @8.8.8.8 | grep -c "$domain\.$") + if [ "$cname_record_check" -eq 0 ]; then + echo -e "${cyan}⚠️ Warning: CNAME record for * is not set or not pointing to @${nc}" + else + echo -e "${cyan}✅ CNAME record for * is correctly set to @${nc}" + fi + echo "--------------------------------------------------------" + echo -e "please double-check your ${cyan}DNS records${nc} to ensure they are set. the following dns records need to be set:" + echo "" + echo "|name |type |value " + echo "|@ |A |$publicip " + echo "|* |CNAME |@ " + echo "" + echo -e "once you've done this, press any key to ${underline}continue${nc}" + pause_if_enabled + +fi +# Ask about static public IP if using public DNS +if [ "$external_access_method" -eq 1 ]; then + + + while true; do + read -p "Do you have a static public IP address? (yes/no): " static_ip_answer + case "$static_ip_answer" in + ([yY]|[yY][eE][sS]) + static_public_ip="yes" + break + ;; + ([nN]|[nN][oO]) + static_public_ip="no" + break + ;; + (*) + echo "Please answer with 'yes' or 'no'." + ;; + esac + done + + # Store this information for later use + echo "Static public IP setting: $static_public_ip" +fi @@ -488,36 +564,600 @@ site.$domain Add any other subdomains you want to use. EOF -cat >/opt/stacks/pihole/dns/02-wildcard.conf </opt/stacks/pihole/dns/02-wildcard.conf <> 24) & 0xFF )).$(( (dec >> 16) & 0xFF )).$(( (dec >> 8) & 0xFF )).$(( dec & 0xFF ))" + } + docker exec pihole pihole-FTL --config dhcp.active true + docker exec pihole pihole-FTL --config dhcp.start $dhcp_start + docker exec pihole pihole-FTL --config dhcp.end $dhcp_end + docker exec pihole pihole-FTL --config dhcp.router $gateway + docker exec pihole pihole-FTL --config dhcp.netmask $netmask + + + # Apply the DHCP configuration + docker restart pihole + + echo "DHCP configuration applied:" + echo " Network: $network_address" + echo " Broadcast: $broadcast_address" + echo " Range: $dhcp_start to $dhcp_end" + echo " Router: $gateway" + echo " Netmask: $netmask" + echo " Domain: $domain" +fi + +# Generate post-install tasks file +echo "Generating post-install tasks file..." +tasks_file="/opt/files/post-install.txt" + +# Start with common header +cat > "$tasks_file" <> "$tasks_file" < DDNS +3. Select your DDNS provider (No-IP or ASUS DDNS) +4. Enter your DDNS hostname +5. Provide your DDNS credentials +6. Click Apply to save settings + +TP-LINK ROUTERS +--------------- +1. Log in to your router's admin panel at http://$gateway +2. Navigate to Advanced > Network > Dynamic DNS +3. Select your DDNS provider (No-IP or TP-Link DDNS) +4. Enter your DDNS hostname +5. Provide your DDNS credentials +6. Click Save to apply settings + +-------------------------------------------------------------------------------- +OPTION 2: CONFIGURING DDNS ON YOUR SERVER USING DDCLIENT +-------------------------------------------------------------------------------- + +1. INSTALL DDCLIENT +------------------- + sudo apt update && sudo apt install ddclient + +2. CONFIGURE DDCLIENT +---------------------- +Edit the configuration file: + sudo nano /etc/ddclient/ddclient.conf + +For DuckDNS: + protocol=duckdns + use=web + server=www.duckdns.org + login=your_duckdns_token + password= + yourDDNSdomain.duckdns.org + +For No-IP: + protocol=noip + use=web + server=dynupdate.no-ip.com + login=your_noip_username + password=your_noip_password + yourDDNSdomain.ddns.net + +3. RESTART DDCLIENT +------------------- + sudo systemctl restart ddclient + sudo systemctl enable ddclient + +4. VERIFY CONFIGURATION +----------------------- + sudo tail -n 20 /var/log/syslog | grep ddclient + +EOF + section=$((section + 1)) +fi + +# 2. PiHole Configuration (for local DNS methods) +if [ "$external_access_method" -eq 2 ] || [ "$external_access_method" -eq 3 ]; then + cat >> "$tasks_file" < DHCP Server +3. Set "Enable the DHCP Server" to "No" +4. Click "Apply" to save changes + +TP-LINK ROUTERS: +--------------- +1. Log in to router admin (http://$gateway) +2. Go to Advanced > Network > DHCP Server +3. Toggle DHCP Server to "Disable" +4. Click "Save" to apply + + +-------------------------------------------------------------------------------- +2. CONFIGURING STATIC IPS WITH CUSTOM DNS ($localip or $publicip) +-------------------------------------------------------------------------------- + +use $publicip if you are forwarding port 53, or $localip if not. +if you use $localip, the device will not have DNS outside of your local network. + +you only need to do this for devices that have a static ip address, devices that get their ip assigned via DHCP (which is default for most devices, especially wireless ones) get their DNS address from the router. + +WINDOWS: +-------- +1. Open Network Settings (Win+I > Network & Internet) +2. Select your connection (Wi-Fi/Ethernet) +3. Click "Hardware properties" > "Edit" next to DNS +4. Set manual DNS to $localip or $publicip +5. Save changes + +MACOS: +------ +1. Open System Preferences > Network +2. Select your connection +3. Click "Advanced" > DNS tab +4. Add $localip or $publicip to DNS servers +5. Click "OK" > "Apply" + +LINUX (NETWORK MANAGER): +------------------------ +1. Edit connection settings: + nm-connection-editor +2. Select your connection +3. Go to IPv4/IPv6 settings +4. Set DNS to $localip or $publicip +5. Save and restart connection + +ANDROID: +-------- +1. Open Wi-Fi settings +2. Long-press your network > Modify network +3. Enable "Advanced options" +4. Set IP to static +5. Enter DNS as $localip or $publicip + +IOS: +---- +1. Open Wi-Fi settings +2. Tap (i) next to your network +3. Configure DNS > Manual +4. Add $localip or $publicip +5. Save changes + +EOF + section=$((section + 1)) +fi + +# 5. Router Configuration (for public DNS) +if [ "$external_access_method" -eq 1 ]; then + cat >> "$tasks_file" < DHCP Server +3. Under "DNS Server", enter $localip +4. Click "Apply" to save + +TP-LINK ROUTERS: +--------------- +1. Log in to router admin (http://$gateway) +2. Go to Advanced > Network > DHCP Server +3. Set "Primary DNS" to $localip +4. Click "Save" to apply + +GENERAL NOTES: +-------------- +- Changes affect all DHCP clients +- Some routers allow multiple DNS servers (comma-separated) +- Restart devices to receive new DNS settings +- after waiting up to 4 hours for changes to propagate: Verify DNS propagation with: nslookup $domain + +EOF + section=$((section + 1)) +fi + +# 3. Nginx and Dockge Pre-Configuration +cat >> "$tasks_file" <> "$tasks_file" < Let's Encrypt via HTTP + +# Step 3: +copy the contents of the "npmcertlist.txt" file into the domain names field. +copy one line at a time if using ctrl+c/ctrl+v, be sure to press enter between each line. + +if you make use of clickpaste (or any tool that allows you to paste by simulating keyboard input), you can use that to paste the entire list in one go + +or you can type the entire list manually + +# Step 4: +hit "save" and wait. + +# Step 5: +go to the Hosts > proxy hosts tab and go through each of the hosts + +# Step 6: +repeat for each host: +>go to the SSL tab +>select your certificate +>enable force SSL +in the case of owncloud you may also want to enable HTTP/2 +then hit save. + +once you've done this for all your sites, your entire cloud is now running with SSL encryption. + +EOF +else + # Local DNS methods - Self-signed certs + cat >> "$tasks_file" < add certificate > custom + +fill in your main domain as the Name + +for the certificate key, use the wildcard.key file +for the certificate, use the wildcard.crt file +for the intermediate certificate, use the intermediate.crt file + + +because this certificate is not backed by a public certificate authority like letsencrypt, you have to manually trust the root cert on each device you want to use the cloud on, or deal with "certificate untrusted" warnings. + +below are guides for doing this: + + +windows: + +download and double-click rootCA.pfx +select "Local Machine" and click next, password is empty. +choose "place all certificates in the following store" and choose "Trusted Root Certification Authorities" +click finish and confirm with "yes" if prompted. + +macOS: + +download and double-click rootCA.pfx +if prompted for a password, leave it blank and click yes +open Keychain Access (applications/utilities/keychain access) +locate the imported rootCA.pfx certificate in the login or system keychains. +double-click the certificate, expand the "trust" section and set "When using this certificate" to "always trust" + +Linux: + +download the rootCA.crt file +copy rootCA.crt to /usr/local/share/ca-certificates/ using the following command from the directory rootCA.crt is in, or by using your file manager. +sudo cp rootCA.crt /usr/local/share/ca-certificates/ + +then update the CA store by rebooting or running the following command: +sudo update-ca-certificates + +android: + +download rootCA.crt to your device +open settings > security > encryption & credentials > install a certificate +select rootCA.crt and set a Name +reboot if prompted + +IOS: + +download rootCA.crt to your device +open the file in safari and tap "install" +go to settings > general > VPN & Device management > configuration profile and install the certificate +enable full trust in settings > general > about > certificate trust settings + + +now that you've set your DNS correctly and trusted the cert, you should be able to visit all of your sites via https://dash.$domain + +the certificate is valid for 10 years, after which you can generate a new one with gencerts.sh +EOF +fi +section=$((section + 1)) + + + +# 6. Service Configurations +cat >> "$tasks_file" < + +EOF +section=$((section + 1)) + +# 7. Uptime Kuma Configuration (last since it depends on DNS and HTTPS) +cat >> "$tasks_file" < + + +EOF + +# Add footer with additional information +cat >> "$tasks_file" < + +IMPORTANT NOTES: +- Your local network is: $network_address/$netmask +- Your broadcast address is: $broadcast_address + + +EOF + +# Output success message +echo "Post-install tasks file generated: $tasks_file" +echo "Please follow the tasks in order as some services depend on others!" +echo "if you are using public DNS with a static ip, you can also already access this from http://browser.$domain, if you are using local DNS, you will need to do additional configuration" +echo "you can open this file on this machine using the command 'sudo nano $tasks_file'" echo "" -echo "" -echo "" -echo -e "you can now access the dockge GUI interface at $localip:5001 and the proxy interface at $localip:81 once you start it from Dockge. be sure to forward ports 80, 443 and 51820 to $localip in your router settings" -echo -e "to use ${green}pihole${nc} as your DNS provider, set your DNS to $localip in your router for DHCP and on your device for any device with a static ip. Currently, the DNS is configured to use the joindns4.eu DNS, which also has built-in adblocking." -echo "" -echo -e "reminder, configure the following services if you have not done so already:" -echo "(this is only needed if you did not enable pause prompts or did not follow the pause prompts)" -echo -e "${cyan}uptime kuma${nc} has been launched from http://status.$domain, perform the initial setup, choosing embedded mariaDB" -echo -e "${cyan}jellyfin${nc} has launched from http://video.$domain, perform the initial setup" -echo -e "${cyan}filebrowser${nc} has been launched from http://browser.$domain, head to dockge (http://docker.$domain), open the filebrowser stack and check the logs for the initial admin password. make sure to change this in filebrowser's config" -echo -e "${cyan}bookstack${nc} has been launched from http://docs.$domain, log in with email 'admin@admin.com' and password 'password', then reset this account to use $adminemail and your password." -echo -e "${cyan}Nginx Proxy Manager${nc} has been installed and launched. go to http://proxy.$domain and configure your username and password" -echo -e "${cyan}Dockge${nc} has been installed and launched. go to http://docker.$domain and configure your username and password" -echo "" -echo "you may have to go to settings > additional in owncloud and click "save" for the onlyoffice server settings." -echo "" -echo "-------------------------------" -echo -e "the following set up steps must still be completed, you can find them in the "setup" folder at http://browser.$domain, this is required for vaultwarden to work" -echo -e "${cyan}Nginx Proxy Manager${nc}: lets-encrypt certificate needs to be set up" -echo -e "${cyan}Uptime Kuma${nc}: Monitoring and status page configuration" +echo "for your convenience, the tasks file will be copied to the current user's home directory" +cp $tasks_file ~/post-install.txt # Capture the end time (Unix timestamp) END_TIME=$(date +%s)