137 lines
3.5 KiB
Bash
137 lines
3.5 KiB
Bash
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
# Variables
|
|
WEBROOT="/var/www/html/markdown"
|
|
CGI_DIR="$WEBROOT/cgi-bin"
|
|
MD_DIR="$WEBROOT/md"
|
|
APACHE_CONF="/etc/apache2/sites-available/markdown.conf"
|
|
SCRIPT_NAME="render.py"
|
|
SCRIPT_PATH="$CGI_DIR/$SCRIPT_NAME"
|
|
UPLOAD_USER="anon"
|
|
|
|
echo "==> Installing dependencies..."
|
|
sudo apt update
|
|
sudo apt install -y apache2 python3 python3-markdown
|
|
|
|
echo "==> Enabling CGI module..."
|
|
sudo a2enmod cgi
|
|
|
|
echo "==> Creating directory structure..."
|
|
sudo mkdir -p "$CGI_DIR"
|
|
sudo mkdir -p "$MD_DIR/docs"
|
|
|
|
echo "==> Writing secure CGI Python script with nested directory support..."
|
|
sudo tee "$SCRIPT_PATH" > /dev/null << 'EOF'
|
|
#!/usr/bin/env python3
|
|
import cgi
|
|
import os
|
|
import markdown
|
|
import html
|
|
|
|
print("Content-Type: text/html\n")
|
|
|
|
form = cgi.FieldStorage()
|
|
filename = form.getvalue("file", "index.md")
|
|
|
|
# Reject malicious input
|
|
if not filename or ".." in filename or filename.startswith("/"):
|
|
print("Status: 400 Bad Request\n")
|
|
print("<h1>400 Bad Request</h1><p>Invalid filename.</p>")
|
|
exit()
|
|
|
|
# Resolve safe absolute path
|
|
basedir = os.path.abspath("../md")
|
|
requested_path = os.path.normpath(os.path.join(basedir, filename))
|
|
if not requested_path.startswith(basedir):
|
|
print("Status: 403 Forbidden\n")
|
|
print("<h1>403 Forbidden</h1><p>Access denied.</p>")
|
|
exit()
|
|
|
|
# Check existence
|
|
if not os.path.isfile(requested_path):
|
|
print("Status: 404 Not Found\n")
|
|
print(f"<h1>404 Not Found</h1><p>{html.escape(filename)} not found.</p>")
|
|
exit()
|
|
|
|
# Read and convert
|
|
with open(requested_path, 'r') as f:
|
|
md_text = f.read()
|
|
|
|
html_content = markdown.markdown(md_text)
|
|
|
|
print(f"""
|
|
<html>
|
|
<head>
|
|
<meta charset='UTF-8'>
|
|
<title>{html.escape(filename)}</title>
|
|
<style>
|
|
body {{ max-width: 800px; margin: auto; font-family: sans-serif; padding: 2em; }}
|
|
code {{ background: #eee; padding: 2px 4px; border-radius: 4px; }}
|
|
pre {{ background: #eee; padding: 1em; overflow-x: auto; }}
|
|
a {{ color: blue; text-decoration: none; }}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>{html.escape(filename)}</h1>
|
|
{html_content}
|
|
</body>
|
|
</html>
|
|
""")
|
|
EOF
|
|
|
|
echo "==> Making script executable..."
|
|
sudo chmod +x "$SCRIPT_PATH"
|
|
|
|
echo "==> Creating example markdown files..."
|
|
sudo tee "$MD_DIR/index.md" > /dev/null << EOF
|
|
# Welcome
|
|
|
|
This is the **root index** page.
|
|
EOF
|
|
|
|
sudo tee "$MD_DIR/docs/tutorial.md" > /dev/null << EOF
|
|
# Tutorial Page
|
|
|
|
This is a **nested Markdown file** inside \`docs/\`.
|
|
EOF
|
|
|
|
echo "==> Creating Apache virtual host config..."
|
|
sudo tee "$APACHE_CONF" > /dev/null << EOF
|
|
<VirtualHost *:80>
|
|
ServerAdmin webmaster@localhost
|
|
DocumentRoot $WEBROOT
|
|
|
|
<Directory $CGI_DIR>
|
|
Options +ExecCGI
|
|
AddHandler cgi-script .py
|
|
Require all granted
|
|
</Directory>
|
|
|
|
<Directory $MD_DIR>
|
|
Options +Indexes
|
|
Require all granted
|
|
</Directory>
|
|
|
|
Alias /markdown/ $WEBROOT/
|
|
</VirtualHost>
|
|
EOF
|
|
|
|
echo "==> Enabling site and restarting Apache..."
|
|
sudo a2ensite markdown
|
|
sudo systemctl reload apache2
|
|
|
|
echo "==> Granting FileZilla user 'anon' permission to upload to md/ folder..."
|
|
sudo usermod -aG www-data $UPLOAD_USER
|
|
sudo chown -R www-data:www-data "$MD_DIR"
|
|
sudo chmod -R 775 "$MD_DIR"
|
|
|
|
echo ""
|
|
echo "✅ Setup Complete!"
|
|
echo "📁 Upload Markdown files to: /var/www/html/markdown/md/"
|
|
echo "🖥️ View raw directory listing: http://localhost/markdown/md/"
|
|
echo "🖥️ View root file: http://localhost/cgi-bin/render.py?file=index.md"
|
|
echo "📄 View nested file: http://localhost/cgi-bin/render.py?file=docs/tutorial.md"
|
|
echo "🧑 Log out and back in as '$UPLOAD_USER' to apply group changes if needed."
|