Untitled
unknown
batchfile
7 days ago
8.2 kB
31
No Index
#!/bin/bash # --- Configuration Variables (USER MUST EDIT THESE) --- # !!! WARNING: HARDCODED PASSWORD! CHANGE THIS! !!! # It's MUCH better to use SSH key-based authentication and remove # the --password option from pct create. See instructions below. LXC_ID="123" # Choose a unique container ID LXC_TEMPLATE="local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst" # Path to your Ubuntu template LXC_STORAGE="local-lvm" # Your Proxmox storage name (e.g., local-lvm, local, etc.) LXC_DISK_SIZE="8" # Root filesystem size in GB LXC_BRIDGE="vmbr0" # Your Proxmox network bridge LXC_IP="10.0.50.166/24" # Static IP address for the container LXC_GATEWAY="10.0.50.1" # Gateway IP address LXC_HOSTNAME="dns1" # Hostname for the container LXC_MEMORY="2048" # RAM in MB LXC_SWAP="512" # Swap space in MB LXC_CORES="4" # Number of CPU cores USERNAME="daniel" # Non-root username USERPASS="daniel" # Non-root user password (CHANGE THIS!!!) PIHOLE_IP="10.0.50.166" #Pi-hole static IP address. Must match LXC_IP TAILSCALE_AUTHKEY="YOUR_TAILSCALE_AUTH_KEY" # Your Tailscale auth key (reusable, tagged) CLOUDFLARE_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN" # Your Cloudflare API token DOH_DOMAIN="doh.example.com" # Your DoH subdomain (e.g., doh.example.com) EMAIL="your_email@example.com" # Your email address for Let's Encrypt UNBOUND_PORT="5335" # --- End of User Configuration --- # --- Input Validation --- if [[ -z "$LXC_IP" ]]; then echo "ERROR: LXC_IP is not set." exit 1 fi if ! [[ "$LXC_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then echo "ERROR: Invalid LXC_IP format" exit 1 fi if [[ -z "$LXC_GATEWAY" ]]; then echo "ERROR: LXC_GATEWAY is not set." exit 1 fi if ! [[ "$LXC_GATEWAY" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then echo "ERROR: Invalid LXC_GATEWAY format" exit 1 fi # --- Exit on Error --- set -e # --- Proxmox LXC Creation --- pct create "$LXC_ID" "$LXC_TEMPLATE" \ --rootfs "$LXC_STORAGE:$LXC_DISK_SIZE" \ --net0 name=eth0,bridge="$LXC_BRIDGE",ip="$LXC_IP",gw="$LXC_GATEWAY",ip6=auto \ --hostname "$LXC_HOSTNAME" \ --memory "$LXC_MEMORY" \ --swap "$LXC_SWAP" \ --cores "$LXC_CORES" \ --unprivileged 1 \ --password "$USERPASS" if [[ $? -ne 0 ]]; then echo "ERROR: pct create failed." exit 1 fi pct start "$LXC_ID" # --- Install expect (needed for automating Pi-hole install) --- apt-get update apt-get install -y expect # --- Helper Function to Run Commands Inside the Container --- run_in_lxc() { pct exec "$LXC_ID" -- bash -c "$@" if [[ $? -ne 0 ]]; then echo "ERROR: Command failed inside LXC: $@" exit 1 fi } # --- Base System Setup (Inside the Container) --- run_in_lxc "apt update && apt upgrade -y" run_in_lxc "apt install -y curl wget nano git sudo apt-transport-https ca-certificates" # Create Non-Root User run_in_lxc "adduser --disabled-password --gecos '' $USERNAME" run_in_lxc "echo '$USERNAME:$USERPASS' | chpasswd" run_in_lxc "usermod -aG sudo $USERNAME" # Configure SSH (Key-Based Authentication - you still need to copy your key manually) run_in_lxc "mkdir -p /home/$USERNAME/.ssh" run_in_lxc "chmod 700 /home/$USERNAME/.ssh" run_in_lxc "touch /home/$USERNAME/.ssh/authorized_keys" run_in_lxc "chmod 600 /home/$USERNAME/.ssh/authorized_keys" run_in_lxc "chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh" # SSH Configuration (disable password auth) run_in_lxc "sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config" run_in_lxc "sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config" run_in_lxc "sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config" run_in_lxc "systemctl restart sshd" # --- Pi-hole Installation (Automated with expect) --- run_in_lxc "curl -sSL https://install.pi-hole.net | bash" sleep 5 run_in_lxc << EOF set timeout 10 expect "Do you want to continue? \[y/N] " { send "y\r" } expect "Transform your device into a network-wide ad blocker!" { send "\r" } expect "*static IP address*" { send "\r" } expect "*Press any key*" { send "\r" } expect "Choose an upstream DNS provider" { send "\r" } expect "*Custom*" {send "6\r"} expect "IPv4 Custom DNS Server*" {send "127.0.0.1#$UNBOUND_PORT\r"} expect "IPv6 Custom DNS Server*" {send "\r"} expect "Select Protocols" { send "\r" } expect "Do you wish to install the web admin interface" {send "\r"} expect "Do you wish to install the web server" {send "\r"} expect "Do you want to log queries" {send "\r"} expect "Select a privacy mode" {send "\r"} expect "::: Done!" EOF sleep 5 # --- Unbound Installation and Configuration --- run_in_lxc "apt install -y unbound" run_in_lxc "wget https://www.internic.net/domain/named.root -O /usr/share/dns/root.hints" run_in_lxc "cat <<EOF | tee /etc/unbound/unbound.conf.d/pi-hole.conf server: verbosity: 1 interface: 127.0.0.1 interface: $PIHOLE_IP port: $UNBOUND_PORT do-ip4: yes do-ip6: no access-control: 127.0.0.0/8 allow access-control: ${LXC_IP%.*}.0/24 allow access-control: 0.0.0.0/0 refuse root-hints: \"/usr/share/dns/root.hints\" harden-glue: yes harden-dnssec-stripped: yes private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 prefetch: yes num-threads: 2 so-rcvbuf: 1m EOF" run_in_lxc "unbound-checkconf" run_in_lxc "systemctl start unbound" run_in_lxc "systemctl enable unbound" # --- DNSDist Installation and Configuration --- run_in_lxc "apt install -y dnsdist" run_in_lxc "cat <<EOF | tee /etc/dnsdist/dnsdist.conf addLocal('0.0.0.0:53') addLocal('[::]:53') addTLSLocal('0.0.0.0:853', '/etc/letsencrypt/live/$DOH_DOMAIN/fullchain.pem', '/etc/letsencrypt/live/$DOH_DOMAIN/privkey.pem') addDOHLocal('0.0.0.0:443', '/etc/letsencrypt/live/$DOH_DOMAIN/fullchain.pem', '/etc/letsencrypt/live/$DOH_DOMAIN/privkey.pem', '/dns-query') addConsole('127.0.0.1:5199', 'strongconsolepassword') newServer({address='127.0.0.1:$UNBOUND_PORT', name='unbound'}) setACL({'0.0.0.0/0', '::/0'}) EOF" run_in_lxc "systemctl enable dnsdist" run_in_lxc "systemctl start dnsdist" # --- Tailscale Installation and Configuration --- run_in_lxc "curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null" run_in_lxc "curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list" run_in_lxc "apt update" run_in_lxc "apt install -y tailscale" run_in_lxc "tailscale up --authkey=$TAILSCALE_AUTHKEY --advertise-exit-node=false --advertise-routes= --accept-dns=false" # --- Let's Encrypt (dns01 Challenge with Cloudflare) --- run_in_lxc "apt install -y certbot python3-certbot-dns-cloudflare" # Create Cloudflare credentials file run_in_lxc "mkdir -p /etc/cloudflare" run_in_lxc "cat <<EOF | tee /etc/cloudflare/cloudflare.ini dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN EOF" run_in_lxc "chmod 600 /etc/cloudflare/cloudflare.ini" # Obtain Certificate run_in_lxc "certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /etc/cloudflare/cloudflare.ini \ -d $DOH_DOMAIN \ --agree-tos \ -m $EMAIL \ --non-interactive" # --- Firewall (UFW) --- run_in_lxc "apt install -y ufw" run_in_lxc "ufw default deny incoming" run_in_lxc "ufw default allow outgoing" run_in_lxc "ufw allow ssh" run_in_lxc "ufw allow 53/udp" run_in_lxc "ufw allow 53/tcp" run_in_lxc "ufw allow 443/tcp" run_in_lxc "ufw allow 853/tcp" run_in_lxc "ufw allow from ${LXC_IP%.*}.0/24" # Get Tailscale port (dynamically) and allow it TAILSCALE_PORT=$(run_in_lxc "tailscale status | grep -oP ':[0-9]+' | cut -d':' -f2") run_in_lxc "ufw allow $TAILSCALE_PORT/udp" run_in_lxc "ufw enable" run_in_lxc "ufw status verbose" echo "Setup complete! Don't forget to:" echo "1. Copy your SSH public key to /home/$USERNAME/.ssh/authorized_keys inside the container." echo "2. Access Pi-hole web interface at http://$PIHOLE_IP/admin or via Tailscale IP." echo "3. Test DoH/DoT with curl/dog." echo "4. Check certificate expiry with openssl."
Editor is loading...
Leave a Comment