Create New Document

The title of your document (will be displayed as H1)
URL-friendly name (no spaces, use dashes)
Path where to create document (optional, use forward slashes to create subdirectories)

Move/Rename Document

Current location of the document
New path for the document (including the slug)
This only changes the document's path. It does not modify the document's title (H1 heading).

Delete Document

Are you sure you want to delete this document? This action cannot be undone.

Warning: If this is a folder, all contents including subfolders and documents will be deleted.

Message

Message content goes here.

Confirm Action

Are you sure?

Attachments

Allowed file types: jpg, jpeg, png, gif, svg, webp, txt, log, csv, sfd, zip, pdf, docx, xlsx, pptx, mp4 (Max: 10MB)

Document Files

Loading attached files...

Document History

Previous Versions

Loading versions...

Preview

Select a version to preview

Wiki Settings

Language for the user interface
Number of versions to keep per document. Set to 0 to disable versioning.
Maximum allowed file size for uploads in MB.

User Management

Add New User

Leave empty to keep current password
Users with these groups can access restricted sections.

Define path-based access rules for sections of your wiki, then assign users to groups in the Users tab. Rules are evaluated in order. First match wins.

Active Rules

Import markdown files from a ZIP archive. Files will be processed and stored in the appropriate document structure. Directory structure in the ZIP (category/subcategory) will be preserved in the wiki.

Upload a ZIP file containing markdown (.md) files to import.

Create and manage backups of your wiki data. Backups include all documents, images, and configuration files.

Available Backups

Loading backups...

Add/Edit Access Rule

Selected: /

Add Column

Certificate Renewal Script Improvements

Comparison: Original vs Improved

Security Improvements

Issue Original Improved
Command injection ❌ Uses os.system() with string formatting ✅ Uses subprocess.run() with list arguments
Root check ❌ No check ✅ Verifies running as root
Path validation ❌ No validation ✅ Validates webroot exists and is writable
Error exposure ❌ Generic error messages ✅ Detailed logging without exposing sensitive data
Timeouts ❌ No timeout (can hang indefinitely) ✅ 5-minute timeout for certbot, 30s for service restarts

Reliability Improvements

Feature Original Improved
Error handling ❌ Minimal, catches only subprocess errors ✅ Comprehensive try/except blocks
Logging ❌ Print statements only ✅ Proper logging to file + stdout
Exit codes ❌ No meaningful exit codes ✅ Returns 0 on success, 1 on failure
File existence checks ❌ Will crash if cert missing ✅ Validates all paths before operations
Service restart ❌ Uses deprecated /usr/sbin/service ✅ Uses systemctl (modern systemd)
Capture output ❌ No output capture ✅ Captures stdout/stderr for debugging
Dependency check ❌ No check ✅ Checks for pyOpenSSL on startup

Code Quality Improvements

Aspect Original Improved
Type hints ❌ None ✅ Full type annotations
Documentation ❌ One comment line ✅ Docstrings for all functions
Function decomposition ❌ Monolithic code ✅ 9 small, testable functions
Configuration ❌ Hardcoded values ✅ Constants at top of file
Code organization ❌ Sequential script ✅ Proper main() function
PEP 8 compliance ⚠️ Partial ✅ Fully compliant
Path handling ❌ String concatenation ✅ Uses pathlib.Path

Operational Improvements

Feature Original Improved
Log file ❌ No persistent logging ✅ Logs to /var/log/mail-cert-renewal.log
Summary report ❌ No summary ✅ Lists all failures at end
Webroot validation ❌ Assumes webroot works ✅ Tests ACME challenge directory writability
Rate limiting awareness ✅ 60s delay between renewals ✅ Same, but logged
Debugging ❌ Difficult to troubleshoot ✅ DEBUG level logging available

Key Security Fixes

1. Command Injection Prevention

Original (vulnerable):

os.system("/usr/sbin/service {} restart".format(svc))

If svc contained postfix; rm -rf /, it would execute both commands.

Improved (safe):

subprocess.run(["systemctl", "restart", service_name], check=True)

Arguments are passed as list, preventing shell injection.

2. Timeout Protection

Original: No timeout - could hang forever if certbot stalls.

Improved:

subprocess.run(cmd, timeout=300)  # 5 minute max

3. Root Permission Validation

Improved:

if os.geteuid() != 0:
    logger.error("This script must be run as root")
    sys.exit(1)

New Features

1. Comprehensive Logging

# View logs
tail -f /var/log/mail-cert-renewal.log

# Enable debug mode
# Edit script, change:
level=logging.DEBUG

2. Webroot Validation

Tests that ACME challenge directory is writable before attempting renewal:

validate_webroot(webroot_path)  # Creates test file, then removes it

3. Better Error Reporting

# Original: generic "error renewing certificates"
# Improved: specific errors with context
logger.error(f"Certbot failed for {csr_path}: {e.returncode}")
logger.error(f"Certbot error: {e.stderr}")

4. Exit Codes

sys.exit(0)  # Success
sys.exit(1)  # One or more renewals failed

Useful for monitoring systems and cron job alerts.

Migration Guide

1. Backup Original Script

sudo cp /path/to/renew-mail-certs.py /path/to/renew-mail-certs.py.backup

2. Install Improved Script

sudo cp renew-mail-certs-improved.py /usr/local/bin/renew-mail-certs.py
sudo chmod 755 /usr/local/bin/renew-mail-certs.py
sudo chown root:root /usr/local/bin/renew-mail-certs.py

3. Create Log Directory

sudo touch /var/log/mail-cert-renewal.log
sudo chmod 644 /var/log/mail-cert-renewal.log

4. Test Run

# Dry run (check syntax)
python3 /usr/local/bin/renew-mail-certs.py --help

# Actual test (as root)
sudo /usr/local/bin/renew-mail-certs.py

5. Update Cron Job

sudo crontab -e

# Change from:
# 0 3 * * * /path/to/renew-mail-certs.py

# To:
0 3 * * * /usr/local/bin/renew-mail-certs.py 2>&1 | logger -t mail-cert-renewal

# Or with email notification on failure:
0 3 * * * /usr/local/bin/renew-mail-certs.py || echo "Certificate renewal failed!" | mail -s "Alert: Mail Cert Renewal Failed" admin@xaos.it

6. Log Rotation

Create /etc/logrotate.d/mail-cert-renewal:

/var/log/mail-cert-renewal.log {
    weekly
    rotate 12
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}

Testing the Improved Script

Test 1: Syntax Check

python3 -m py_compile renew-mail-certs-improved.py

Test 2: Dependency Check

python3 -c "from OpenSSL import crypto; print('pyOpenSSL OK')"

Test 3: Permissions Check

# Should fail (not root)
python3 renew-mail-certs-improved.py

# Should work
sudo python3 renew-mail-certs-improved.py

Test 4: Check Logs

tail -100 /var/log/mail-cert-renewal.log

Test 5: Verify Exit Codes

sudo python3 renew-mail-certs-improved.py
echo "Exit code: $?"
# 0 = success, 1 = failure

Monitoring Integration

Nagios/Icinga Check

#!/bin/bash
# Check last log entry age
LOG_FILE="/var/log/mail-cert-renewal.log"
MAX_AGE_HOURS=48

if [ ! -f "$LOG_FILE" ]; then
    echo "CRITICAL: Log file not found"
    exit 2
fi

LAST_LOG=$(stat -c %Y "$LOG_FILE")
NOW=$(date +%s)
AGE=$(( ($NOW - $LAST_LOG) / 3600 ))

if [ $AGE -gt $MAX_AGE_HOURS ]; then
    echo "WARNING: Last renewal check was $AGE hours ago"
    exit 1
fi

if grep -q "ERROR" "$LOG_FILE" | tail -100; then
    echo "CRITICAL: Errors found in recent logs"
    exit 2
fi

echo "OK: Certificate renewal running normally"
exit 0

Prometheus/Grafana

Export metrics:

# Add to cron after renewal script:
grep -c "Certificate renewed successfully" /var/log/mail-cert-renewal.log > /var/lib/node_exporter/textfile_collector/cert_renewals.prom

Backwards Compatibility

The improved script maintains compatibility with:

Performance Impact

  1. ✅ Use improved script in production
  2. ⚠️ Keep original script as backup for 1 month
  3. 📊 Monitor logs for any issues
  4. 🔔 Set up email alerts on renewal failures
  5. 🔒 Consider adding Slack/Discord notifications
  6. 📈 Add certificate expiration monitoring (Prometheus)

Attached Files

Loading attached files...

Comments

No comments yet. Be the first to comment!

Search Results