Files
x-webui/setup.sh
T
xixu-me 53debacae9 Enhance setup.sh with improved automation and logging
Adds error handling, progress messages, and more robust certificate renewal logic to setup.sh. Improves web server configuration for ACME challenges, automates service checks, and provides clearer output for server initialization. Cron job for certificate renewal is now weekly with logging, and the script includes verification steps for certificates and services.
2025-07-15 19:27:00 +08:00

508 lines
15 KiB
Bash

#!/bin/bash
set -e # Exit on any error
# Check if all required parameters are provided
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <username> <domain> <id>"
exit 1
fi
# Assign parameters to variables
USERNAME="$1"
DOMAIN="$2"
ID="$3"
echo "Starting server initialization..."
echo "Username: $USERNAME"
echo "Domain: $DOMAIN"
echo "ID: $ID"
# Install required packages
echo "Installing required packages..."
sudo apt install cron nginx wget unzip openssl -y
# Configure web server permissions and files
echo "Configuring web server..."
sudo chown -R "$USERNAME:$USERNAME" /var/www
sudo mkdir -p /var/www/html/.well-known/acme-challenge
sudo chown -R www-data:www-data /var/www/html
sudo chmod 755 /var/www/html/.well-known/acme-challenge
rm -f /var/www/html/index.nginx-debian.html
# Create index.html
cat >/var/www/html/index.html <<'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>John Doe - Professional Portfolio</title>
<style>
:root {
--primary: #2c3e50;
--secondary: #3498db;
--background: #f8f9fa;
--text: #2c3e50;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: var(--text);
background-color: var(--background);
}
header {
background-color: var(--primary);
color: white;
padding: 2rem 0;
text-align: center;
}
nav {
background-color: var(--secondary);
padding: 1rem 0;
}
nav ul {
list-style: none;
display: flex;
justify-content: center;
gap: 2rem;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
}
nav a:hover {
text-decoration: underline;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.hero {
text-align: center;
padding: 4rem 0;
}
.projects {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 3rem 0;
}
.project-card {
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.skills {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin: 2rem 0;
}
.skill-tag {
background: var(--secondary);
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.9rem;
}
footer {
background-color: var(--primary);
color: white;
text-align: center;
padding: 2rem 0;
margin-top: 4rem;
}
.contact-form {
max-width: 600px;
margin: 0 auto;
}
.form-group {
margin-bottom: 1rem;
}
input,
textarea {
width: 100%;
padding: 0.5rem;
margin-top: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: var(--secondary);
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
opacity: 0.9;
}
</style>
</head>
<body>
<header>
<h1>John Doe</h1>
<p>Full Stack Developer</p>
</header>
<nav>
<ul>
<li><a href="#about">About</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
<main class="container">
<section id="about" class="hero">
<h2>About Me</h2>
<p>
Passionate full-stack developer with 5+ years of experience
building scalable web applications. I specialize in modern
JavaScript frameworks and cloud architecture.
</p>
</section>
<section id="projects">
<h2>Featured Projects</h2>
<div class="projects">
<div class="project-card">
<h3>E-commerce Platform</h3>
<p>
A full-featured e-commerce solution built with React
and Node.js, featuring real-time inventory
management and secure payment processing.
</p>
</div>
<div class="project-card">
<h3>Task Management App</h3>
<p>
A collaborative task management application using
Vue.js and Firebase, with real-time updates and team
collaboration features.
</p>
</div>
<div class="project-card">
<h3>Analytics Dashboard</h3>
<p>
A responsive analytics dashboard built with D3.js
and Express, providing real-time data visualization
and reporting capabilities.
</p>
</div>
</div>
</section>
<section id="skills">
<h2>Skills</h2>
<div class="skills">
<span class="skill-tag">JavaScript</span>
<span class="skill-tag">React</span>
<span class="skill-tag">Node.js</span>
<span class="skill-tag">Python</span>
<span class="skill-tag">SQL</span>
<span class="skill-tag">AWS</span>
<span class="skill-tag">Docker</span>
<span class="skill-tag">Git</span>
</div>
</section>
<section id="contact">
<h2>Contact Me</h2>
<form class="contact-form">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required />
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required />
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea
id="message"
name="message"
rows="5"
required
></textarea>
</div>
<button type="submit">Send Message</button>
</form>
</section>
</main>
<footer><p>&copy; 2025 John Doe. All rights reserved.</p></footer>
</body>
</html>
EOF
# Initial nginx configuration
sudo tee /etc/nginx/nginx.conf >/dev/null <<EOF
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
server {
listen 80;
server_name $DOMAIN;
root /var/www/html;
index index.html;
}
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
EOF
sudo systemctl reload nginx
# Install and configure acme.sh
echo "Installing and configuring acme.sh..."
curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --upgrade --auto-upgrade
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
echo "Issuing SSL certificate for $DOMAIN..."
~/.acme.sh/acme.sh --issue -d "$DOMAIN" -w /var/www/html --keylength ec-256 --force
# Install X
echo "Installing X..."
sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
# Setup certificates
echo "Setting up certificates..."
mkdir ~/cert
~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" --ecc --fullchain-file ~/cert/x.crt --key-file ~/cert/x.key
chmod +r ~/cert/x.key
# Create certificate renewal script
cat >~/cert/cert-renew.sh <<EOF
#!/bin/bash
# Certificate renewal script for $DOMAIN
# This script renews the certificate and installs it for x
echo "Starting certificate renewal for $DOMAIN..."
# Try to renew the certificate using acme.sh (will skip if not due for renewal)
RENEW_OUTPUT=\$(/home/$USERNAME/.acme.sh/acme.sh --renew -d $DOMAIN --ecc 2>&1)
RENEW_EXIT_CODE=\$?
echo "\$RENEW_OUTPUT"
# If renewal was successful (exit code 0) or skipped (exit code 2), proceed with installation
if [ \$RENEW_EXIT_CODE -eq 0 ] || [ \$RENEW_EXIT_CODE -eq 2 ]; then
# Install/reinstall the certificate
/home/$USERNAME/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \\
--fullchain-file /home/$USERNAME/cert/x.crt \\
--key-file /home/$USERNAME/cert/x.key
echo "X Certificates Renewed/Reinstalled"
# Set proper permissions for the private key
chmod +r /home/$USERNAME/cert/x.key
echo "Read Permission Granted for Private Key"
# Restart x service to use the certificate
sudo systemctl restart xray
echo "X Restarted"
# Verify the certificate
echo "Certificate details:"
openssl x509 -in /home/$USERNAME/cert/x.crt -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After)"
echo "Certificate renewal/installation completed successfully!"
else
echo "Certificate renewal failed with exit code \$RENEW_EXIT_CODE"
exit 1
fi
EOF
chmod +x ~/cert/cert-renew.sh
# Setup cron jobs
(crontab -l 2>/dev/null; echo "0 2 * * 0 /home/$USERNAME/cert/cert-renew.sh >> /home/$USERNAME/cert/renewal.log 2>&1") | crontab -
# Configure X
echo "Configuring X..."
sudo tee /usr/local/etc/xray/config.json >/dev/null <<EOF
{
"dns": {
"servers": ["https+local://1.1.1.1/dns-query", "localhost"]
},
"routing": {
"rules": [
{
"ip": ["geoip:private"],
"outboundTag": "block"
},
{
"ip": ["geoip:cn"],
"outboundTag": "block"
}
]
},
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "$ID",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none",
"fallbacks": [
{
"dest": 8888
}
]
},
"streamSettings": {
"security": "tls",
"tlsSettings": {
"rejectUnknownSni": true,
"alpn": "http/1.1",
"minVersion": "1.2",
"certificates": [
{
"certificateFile": "/home/$USERNAME/cert/x.crt",
"keyFile": "/home/$USERNAME/cert/x.key"
}
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"policy": {
"levels": {
"0": {
"handshake": 2,
"connIdle": 150
}
}
}
}
EOF
# Start and enable X
echo "Starting and enabling X service..."
sudo systemctl start xray
sudo systemctl enable xray
# Configure system settings
echo "Optimizing system settings..."
sudo tee /etc/sysctl.conf >/dev/null <<'EOF'
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
# Final nginx configuration with ACME challenge support
sudo tee /etc/nginx/nginx.conf >/dev/null <<EOF
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
server {
listen 80;
server_name $DOMAIN;
# Allow ACME challenge for certificate renewal
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
try_files \$uri =404;
}
# Redirect everything else to HTTPS
location / {
return 301 https://\$http_host\$request_uri;
}
}
server {
listen 8888;
root /var/www/html;
index index.html;
add_header Strict-Transport-Security "max-age=63072000" always;
}
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
EOF
# Restart services and system
echo "Restarting services..."
sudo systemctl restart nginx
# Verify certificate installation
echo "Verifying certificate installation..."
if [ -f ~/cert/x.crt ]; then
echo "Certificate details:"
openssl x509 -in ~/cert/x.crt -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After)"
else
echo "Warning: Certificate file not found"
fi
# Check service status
echo "Checking service status..."
sudo systemctl is-active --quiet nginx && echo "✓ Nginx is running" || echo "✗ Nginx is not running"
sudo systemctl is-active --quiet xray && echo "✓ X is running" || echo "✗ X is not running"
echo "Server initialization completed successfully!"
echo "=============================================="
echo "Domain: $DOMAIN"
echo "ID: $ID"
echo "Certificate location: ~/cert/"
echo "Nginx configuration: /etc/nginx/nginx.conf"
echo "X configuration: /usr/local/etc/xray/config.json"
echo "Certificate renewal script: ~/cert/cert-renew.sh"
echo "Automatic renewal: Configured via cron (weekly check)"
echo "=============================================="
echo "The system will reboot in 10 seconds..."
sleep 10
sudo reboot