-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·291 lines (247 loc) · 8.72 KB
/
setup.sh
File metadata and controls
executable file
·291 lines (247 loc) · 8.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/bin/bash
#
# Core Cast Server - Universal Host Setup Script v4.0
# Guarantees HTTPS for DuckDNS, Custom Domains, and Raw IPs.
#
# --- Colors ---
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
RED='\033[1;31m'
BLUE='\033[1;34m'
NC='\033[0m'
# --- Global Variables ---
MODE="" # "duckdns", "domain", "ip"
HOST_ADDR="" # The Domain or IP
EMAIL=""
SSL_CERT_PATH=""
SSL_KEY_PATH=""
# --- Helper Functions ---
log_step() { echo -e "\n${YELLOW}=====================================================${NC}\n${YELLOW} $1 ${NC}\n${YELLOW}=====================================================${NC}"; }
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
_check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "Please run this script as root (use sudo)."
exit 1
fi
}
_get_user_input() {
log_step "1. Select Connection Type"
echo "Select how you will connect to this server:"
echo " 1) DuckDNS (Dynamic IP) -> Uses Let's Encrypt (Trusted)"
echo " 2) Custom Domain Name -> Uses Let's Encrypt (Trusted)"
echo " 3) Raw IP Address -> Uses Self-Signed Cert (Encrypted but browser warns)"
echo ""
read -p "Enter Choice [1-3]: " CHOICE
case $CHOICE in
1)
MODE="duckdns"
log_info "Selected: DuckDNS"
while [ -z "$HOST_ADDR" ]; do
read -p "$(echo -e ${BLUE}"Enter DuckDNS domain (e.g., my-sdr.duckdns.org): "${NC})" HOST_ADDR
done
while [ -z "$DUCKDNS_TOKEN" ]; do
read -p "$(echo -e ${BLUE}"Enter DuckDNS Token: "${NC})" DUCKDNS_TOKEN
done
_ask_email
;;
2)
MODE="domain"
log_info "Selected: Custom Domain"
while [ -z "$HOST_ADDR" ]; do
read -p "$(echo -e ${BLUE}"Enter Domain (e.g., sdr.example.com): "${NC})" HOST_ADDR
done
_ask_email
;;
3)
MODE="ip"
log_info "Selected: Raw IP Address"
DETECTED_IP=$(curl -s https://api.ipify.org)
read -p "$(echo -e ${BLUE}"Use detected Public IP ($DETECTED_IP)? [Y/n]: "${NC})" USE_DETECT
if [[ $USE_DETECT =~ ^[Nn]$ ]]; then
read -p "$(echo -e ${BLUE}"Enter IP Address: "${NC})" HOST_ADDR
else
HOST_ADDR=$DETECTED_IP
fi
log_info "Using IP: $HOST_ADDR"
log_info "NOTE: Let's Encrypt does not support IPs. Using Self-Signed Cert."
;;
*)
log_error "Invalid option."
exit 1
;;
esac
}
_ask_email() {
while [ -z "$EMAIL" ]; do
read -p "$(echo -e ${BLUE}"Enter Email (for SSL registration): "${NC})" EMAIL
done
}
_check_deps() {
log_step "2. Checking Dependencies"
EXE_DEPS="curl nginx openssl"
# We only need Certbot if we are using a Domain Name
if [ "$MODE" != "ip" ]; then
EXE_DEPS="$EXE_DEPS certbot"
fi
apt-get update >/dev/null
for dep in $EXE_DEPS; do
if ! command -v $dep &> /dev/null; then
log_info "Installing $dep..."
apt-get install -y $dep
fi
done
# Install Nginx plugin for Certbot (only for domains)
if [ "$MODE" != "ip" ]; then
if ! dpkg-query -W python3-certbot-nginx >/dev/null 2>&1; then
log_info "Installing python3-certbot-nginx..."
apt-get install -y python3-certbot-nginx
fi
fi
}
_setup_certificates() {
log_step "3. Setting up SSL Certificates"
# ==========================================
# PATH A: Domains (Let's Encrypt)
# ==========================================
if [ "$MODE" != "ip" ]; then
# 1. Handle DuckDNS specific updater
if [ "$MODE" == "duckdns" ]; then
DUCK_DOM=$(echo $HOST_ADDR | sed 's/\.duckdns\.org$//')
# Force update now
curl -s "https://www.duckdns.org/update?domains=${DUCK_DOM}&token=${DUCKDNS_TOKEN}" >/dev/null
# Install Cron Job
(crontab -l 2>/dev/null | grep -v "duckdns.org/update") | crontab -
(crontab -l 2>/dev/null; echo "*/5 * * * * curl -s \"https://www.duckdns.org/update?domains=${DUCK_DOM}&token=${DUCKDNS_TOKEN}\" >/dev/null 2>&1") | crontab -
log_success "DuckDNS cron job configured."
fi
# 2. Create a temporary Nginx config so Certbot can verify us
log_info "Bootstrapping Nginx for verification..."
cat <<EOF > "/etc/nginx/sites-available/$HOST_ADDR"
server {
listen 80;
server_name $HOST_ADDR;
location / { return 200 'SSL Bootstrap'; }
}
EOF
rm -f /etc/nginx/sites-enabled/default
ln -sf "/etc/nginx/sites-available/$HOST_ADDR" "/etc/nginx/sites-enabled/$HOST_ADDR"
systemctl reload nginx
# 3. Run Certbot
log_info "Requesting Let's Encrypt Certificate..."
certbot certonly --nginx -d "$HOST_ADDR" --email "$EMAIL" --agree-tos -n
if [ $? -ne 0 ]; then
log_error "Certbot Failed. Please check that Port 80 is forwarded to this server."
exit 1
fi
# 4. Set paths for final config
SSL_CERT_PATH="/etc/letsencrypt/live/$HOST_ADDR/fullchain.pem"
SSL_KEY_PATH="/etc/letsencrypt/live/$HOST_ADDR/privkey.pem"
log_success "Let's Encrypt Certificate obtained!"
# ==========================================
# PATH B: IP Address (Self-Signed)
# ==========================================
else
log_info "Generating Self-Signed Certificate for IP $HOST_ADDR..."
mkdir -p /etc/nginx/ssl
SSL_CERT_PATH="/etc/nginx/ssl/corecast_selfsigned.crt"
SSL_KEY_PATH="/etc/nginx/ssl/corecast_selfsigned.key"
# Use OpenSSL to create the cert
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout "$SSL_KEY_PATH" \
-out "$SSL_CERT_PATH" \
-subj "/C=US/ST=Global/L=Internet/O=CoreCast/CN=$HOST_ADDR" \
2>/dev/null
log_success "Self-signed certificate generated."
fi
}
_write_final_config() {
log_step "4. Applying Nginx Configuration"
CONFIG_FILE="/etc/nginx/sites-available/$HOST_ADDR"
# This writes the EXACT config you provided, but injects the correct SSL paths
cat <<EOF > "$CONFIG_FILE"
# BLOCK 1: Redirect HTTP -> HTTPS
server {
listen 80;
listen [::]:80;
server_name $HOST_ADDR;
return 301 https://\$host\$request_uri;
}
# BLOCK 2: SECURE HTTPS (Port 443)
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name $HOST_ADDR;
# --- SSL Certs (Auto-Selected) ---
ssl_certificate $SSL_CERT_PATH;
ssl_certificate_key $SSL_KEY_PATH;
# --- Standard SSL Settings ---
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'HIGH:!aNULL:!MD5';
# --- WebSocket / Audio ---
location /audio {
proxy_pass http://127.0.0.1:5050/audio;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
add_header 'Access-Control-Allow-Origin' 'https://corecastsdr.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
if (\$request_method = 'OPTIONS') { return 204; }
}
# --- WebSocket / Waterfall ---
location /waterfall {
proxy_pass http://127.0.0.1:5050/waterfall;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
add_header 'Access-Control-Allow-Origin' 'https://corecastsdr.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
if (\$request_method = 'OPTIONS') { return 204; }
}
# --- Metrics API ---
location /metrics {
proxy_pass http://127.0.0.1:8001/metrics;
add_header 'Access-Control-Allow-Origin' 'https://corecastsdr.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
if (\$request_method = 'OPTIONS') { return 204; }
}
}
EOF
# Enable the new site
ln -sf "$CONFIG_FILE" "/etc/nginx/sites-enabled/$HOST_ADDR"
# Test and Reload
if nginx -t; then
systemctl reload nginx
log_success "Nginx Configured Successfully!"
else
log_error "Nginx configuration failed verification."
exit 1
fi
}
main() {
_check_root
_get_user_input
_check_deps
_setup_certificates
_write_final_config
log_step "Setup Complete!"
echo -e "Server is live at: ${GREEN}https://$HOST_ADDR${NC}"
if [ "$MODE" == "ip" ]; then
echo -e "${YELLOW}IMPORTANT: You are using a Self-Signed Certificate (IP Mode)."
echo -e "You MUST manually visit https://$HOST_ADDR in your browser and accept"
echo -e "the 'Not Secure' warning before the connection will work.${NC}"
fi
}
main