Archived
Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c02440a9d | ||
|
|
5444493997 | ||
|
|
9907dd8a54 | ||
|
|
a5e297ef82 | ||
|
|
68d03bab49 | ||
|
|
1d14560e29 | ||
|
|
5b3be73f35 | ||
|
|
36b209e529 | ||
|
|
ddbf1c6999 | ||
|
|
999e6d75af | ||
|
|
2d9bbc9044 | ||
|
|
72cf84dc2f | ||
|
|
8c77b3a1a8 | ||
|
|
57c8367e2a | ||
|
|
76d71bb285 | ||
|
|
c25761f7fb | ||
|
|
ea2e544a76 | ||
|
|
ac3b422377 | ||
|
|
0d8e4d8ccb | ||
|
|
e27b0c57db | ||
|
|
564222d082 | ||
|
|
d0db901e65 | ||
|
|
6d785b4252 | ||
|
|
8f78abb808 | ||
|
|
c6550981a4 | ||
|
|
cccd9eedd0 | ||
|
|
4056d29124 |
@@ -1,24 +0,0 @@
|
||||
# Environment variables for OCF WordPress Hosting Platform
|
||||
# Copy this file to .env and customize as needed
|
||||
|
||||
# Database Configuration
|
||||
MYSQL_ROOT_PASSWORD=root_password_change_me
|
||||
MYSQL_DATABASE=wp_master
|
||||
MYSQL_USER=wp_user
|
||||
MYSQL_PASSWORD=wp_password_change_me
|
||||
|
||||
# Apache Configuration
|
||||
APACHE_HTTP_PORT=80
|
||||
APACHE_HTTPS_PORT=443
|
||||
|
||||
# phpMyAdmin Configuration
|
||||
PMA_PORT=8080
|
||||
|
||||
# WordPress Configuration (for user sites)
|
||||
WORDPRESS_DB_HOST=db:3306
|
||||
|
||||
# Development vs Production
|
||||
ENVIRONMENT=development
|
||||
|
||||
# Logging
|
||||
LOG_LEVEL=info
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
# Ignore environment files with secrets
|
||||
.env
|
||||
|
||||
# Docker volumes and user data
|
||||
volumes/
|
||||
|
||||
# Backups
|
||||
*.tar.gz
|
||||
*.sql
|
||||
db_backup_*.sql
|
||||
backup_data*.tar.gz
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.swp
|
||||
*~
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
@@ -1,152 +1,2 @@
|
||||
# Secure OCF-Style Multi-User WordPress Hosting Platform
|
||||
|
||||
A Docker-based hosting platform modeled after UC Berkeley's Open Computing Facility (OCF), enabling multiple users to host their own WordPress sites through a shared infrastructure with isolated volumes.
|
||||
|
||||
Each user volume contains:
|
||||
- `site_conf/` - Apache vhost configuration
|
||||
- `wordpress_content/` - WordPress files (themes, plugins, uploads)
|
||||
- `database/` - SQL dumps and backups
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Build and Start Services
|
||||
|
||||
```bash
|
||||
# Build and start all services
|
||||
docker-compose up -d --build
|
||||
|
||||
# Check service status
|
||||
docker-compose ps
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f apache
|
||||
```
|
||||
|
||||
### 2. Access Your Test Site
|
||||
|
||||
Add this entry to `/etc/hosts` (or `C:\Windows\System32\drivers\etc\hosts` on Windows):
|
||||
|
||||
```
|
||||
127.0.0.1 localhost testuser.local
|
||||
```
|
||||
|
||||
Then visit:
|
||||
- **Test Site**: http://localhost (shows PHP info)
|
||||
- **phpMyAdmin**: http://localhost:8080 (user: `wp_user`, password: `wp_password`)
|
||||
|
||||
### 3. Register a New User
|
||||
|
||||
```bash
|
||||
# Register a new user with their domain
|
||||
./register_user.sh alice alice.local
|
||||
|
||||
# The script will:
|
||||
# - Create volume structure
|
||||
# - Download WordPress
|
||||
# - Generate vhost configuration
|
||||
# - Provide next steps
|
||||
```
|
||||
|
||||
After running the script, you need to:
|
||||
|
||||
1. **Add the volume to `docker-compose.yml`**:
|
||||
```yaml
|
||||
volumes:
|
||||
- ./volumes/data2-volume:/var/www/data2
|
||||
```
|
||||
|
||||
2. **Restart Apache**:
|
||||
```bash
|
||||
docker-compose restart apache
|
||||
```
|
||||
|
||||
3. **Add DNS entry to `/etc/hosts`**:
|
||||
```
|
||||
127.0.0.1 alice.local
|
||||
```
|
||||
|
||||
4. **Visit the site**: http://alice.local
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
Secure-OCF-Web-Hosting/
|
||||
├── apache/
|
||||
│ ├── Dockerfile # PHP 8.2 + Apache image
|
||||
│ ├── conf/
|
||||
│ │ └── httpd.conf # Main Apache config
|
||||
│ └── vhost-templates/
|
||||
│ └── user_vhost.template # Template for user sites
|
||||
├── wordpress/
|
||||
│ ├── Dockerfile # (Legacy - now Apache handles PHP)
|
||||
│ └── wp-config.php # (Legacy)
|
||||
├── volumes/
|
||||
│ └── data1-volume/ # User volumes
|
||||
│ ├── site_conf/
|
||||
│ │ └── site.conf # User's Apache vhost
|
||||
│ ├── wordpress_content/ # WordPress installation
|
||||
│ └── database/ # SQL dumps
|
||||
├── docker-compose.yml # Service orchestration
|
||||
├── register_user.sh # User registration script
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## 🛠️ Management Commands
|
||||
|
||||
### Container Management
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
docker-compose down
|
||||
docker-compose restart apache
|
||||
docker-compose logs -f [service_name]
|
||||
docker-compose exec apache bash
|
||||
```
|
||||
|
||||
### Database Management
|
||||
|
||||
```bash
|
||||
docker-compose exec db mysql -u wp_user -p
|
||||
docker-compose exec db mysqldump -u wp_user -p wp_master > backup.sql
|
||||
docker-compose exec -T db mysql -u wp_user -p wp_master < backup.sql
|
||||
```
|
||||
|
||||
### User Site Management
|
||||
|
||||
```bash
|
||||
ls -la volumes/
|
||||
docker-compose exec apache apachectl configtest
|
||||
docker-compose exec apache apachectl graceful
|
||||
docker-compose exec apache php -v
|
||||
cat volumes/data1-volume/site_conf/error.log
|
||||
```
|
||||
|
||||
## 📝 Environment Variables
|
||||
|
||||
Create a `.env` file for customization:
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
MYSQL_ROOT_PASSWORD=your_secure_root_password
|
||||
MYSQL_DATABASE=wp_master
|
||||
MYSQL_USER=wp_user
|
||||
MYSQL_PASSWORD=your_secure_password
|
||||
|
||||
# Apache Configuration
|
||||
APACHE_HTTP_PORT=80
|
||||
APACHE_HTTPS_PORT=443
|
||||
|
||||
# phpMyAdmin
|
||||
PMA_PORT=8080
|
||||
```
|
||||
|
||||
Then update `docker-compose.yml` to use these variables.
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- [Docker Documentation](https://docs.docker.com/)
|
||||
- [WordPress Codex](https://codex.wordpress.org/)
|
||||
- [Apache HTTP Server Documentation](https://httpd.apache.org/docs/)
|
||||
- [OCF Documentation](https://www.ocf.berkeley.edu/docs/)
|
||||
|
||||
# Secure-OCF-Web-Hosting
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# WordPress Docker Setup
|
||||
|
||||
This repository provides a Dockerized environment for running WordPress locally using Docker Compose. It's designed for quick development and testing without complex installations.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Apache Server**: Single Apache container with `mod_userdir` enabled
|
||||
- **User Data**: Shared volume containing student org home directories
|
||||
- **WordPress**: Separate WordPress + MariaDB containers for testing
|
||||
- **Structure**: Each org has `/home/<orgname>/public_html/` served at `http://localhost:8080/~<orgname>`
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
1. **Clone the repository:**
|
||||
|
||||
```bash
|
||||
git clone https://git.1337.berkeley.edu/Committee/Secure-OCF-Web-Hosting.git
|
||||
cd Secure-OCF-Web-Hosting/WordPress-Docker
|
||||
```
|
||||
|
||||
2. **Install Docker Desktop:**
|
||||
- [macOS](https://docs.docker.com/desktop/setup/install/mac-install/)
|
||||
- [Windows](https://docs.docker.com/desktop/setup/install/windows-install/)
|
||||
|
||||
3. **Build and start the containers:**
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. **Access WordPress:**
|
||||
|
||||
Open your browser and navigate to:
|
||||
|
||||
```
|
||||
http://localhost:8081
|
||||
```
|
||||
|
||||
Follow the on-screen instructions to complete the WordPress setup.
|
||||
|
||||
### Access sites:
|
||||
- **Student org sites**:
|
||||
- http://localhost:8080/~studentorg1
|
||||
- http://localhost:8080/~studentorg2
|
||||
- http://localhost:8080/~studentorg3
|
||||
- **WordPress**: http://localhost:8081
|
||||
|
||||
### Add new student org:
|
||||
```bash
|
||||
docker exec -it ocf_apache_server bash
|
||||
mkdir -p /home/neworg/public_html
|
||||
echo "<h1>New Org</h1>" > /home/neworg/public_html/index.html
|
||||
chown -R www-data:www-data /home/neworg
|
||||
```
|
||||
|
||||
### View Apache logs:
|
||||
```bash
|
||||
docker logs ocf_apache_server
|
||||
```
|
||||
|
||||
## ⚙️ Managing Containers
|
||||
|
||||
* **Start containers:**
|
||||
|
||||
```bash
|
||||
docker-compose start
|
||||
```
|
||||
|
||||
* **Stop containers:**
|
||||
|
||||
```bash
|
||||
docker-compose stop
|
||||
```
|
||||
|
||||
* **Stop and remove containers:**
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
Add the `-v` flag to also remove volumes:
|
||||
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
## 🔐 Accessing phpMyAdmin
|
||||
|
||||
If phpMyAdmin is included in your setup:
|
||||
|
||||
* Open your browser and navigate to:
|
||||
|
||||
```
|
||||
http://localhost:8081
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
# Dockerfile (apache-static)
|
||||
FROM httpd:2.4
|
||||
|
||||
LABEL maintainer="random@gmail.com"
|
||||
|
||||
# Enable required Apache modules for user directories and PHP
|
||||
RUN sed -i \
|
||||
-e 's/#LoadModule userdir_module/LoadModule userdir_module/' \
|
||||
-e 's/#LoadModule vhost_alias_module/LoadModule vhost_alias_module/' \
|
||||
-e 's/#LoadModule rewrite_module/LoadModule rewrite_module/' \
|
||||
-e 's/#Include conf\/extra\/httpd-userdir.conf/Include conf\/extra\/httpd-userdir.conf/' \
|
||||
/usr/local/apache2/conf/httpd.conf
|
||||
|
||||
# Add custom configuration for user directories
|
||||
COPY httpd-userdir.conf /usr/local/apache2/conf/extra/httpd-userdir.conf
|
||||
|
||||
# Create example student org directories with basic content
|
||||
RUN mkdir -p /home/studentorg1/public_html && \
|
||||
echo "<h1>Welcome to Student Org 1's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg1/public_html/index.html && \
|
||||
mkdir -p /home/studentorg2/public_html && \
|
||||
echo "<h1>Welcome to Student Org 2's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg2/public_html/index.html && \
|
||||
mkdir -p /home/studentorg3/public_html && \
|
||||
echo "<h1>Welcome to Student Org 3's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg3/public_html/index.html
|
||||
|
||||
# Set proper ownership
|
||||
RUN chown -R www-data:www-data /home
|
||||
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,20 @@
|
||||
# Settings for user home directories
|
||||
#
|
||||
# Required module: mod_userdir
|
||||
|
||||
UserDir /home/*/public_html
|
||||
|
||||
#
|
||||
# Control access to UserDir directories.
|
||||
# Mimics OCF structure where user directories are in /home
|
||||
#
|
||||
<Directory "/home/*/public_html">
|
||||
AllowOverride All
|
||||
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
|
||||
Require all granted
|
||||
|
||||
# Allow .htaccess usage for student customization
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
</IfModule>
|
||||
</Directory>
|
||||
@@ -0,0 +1,54 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
apache:
|
||||
build:
|
||||
context: ./apache
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- userdata:/home
|
||||
depends_on:
|
||||
- userdata
|
||||
container_name: apache-static
|
||||
restart: unless-stopped
|
||||
|
||||
userdata:
|
||||
image: busybox
|
||||
volumes:
|
||||
- userdata:/home
|
||||
container_name: user_data
|
||||
command: /bin/true
|
||||
|
||||
db:
|
||||
image: mariadb:11
|
||||
container_name: wp_db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: wp_db
|
||||
MYSQL_USER: wp_user
|
||||
MYSQL_PASSWORD: wp_pass
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
wordpress:
|
||||
image: wordpress:latest
|
||||
container_name: wp_site
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
WORDPRESS_DB_HOST: db:3306
|
||||
WORDPRESS_DB_USER: wp_user
|
||||
WORDPRESS_DB_PASSWORD: wp_pass
|
||||
WORDPRESS_DB_NAME: wp_db
|
||||
ports:
|
||||
- "8081:80" # WordPress site -> http://localhost:8081
|
||||
volumes:
|
||||
- wp_data:/var/www/html
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
userdata:
|
||||
db_data:
|
||||
wp_data:
|
||||
@@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Local Apache Static Landing</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<style>
|
||||
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background:#0f172a; color:#e6eef8; text-align:center; padding-top:8vh; }
|
||||
h1 { color:#10b981; }
|
||||
p { color:#cbd5e1; }
|
||||
a { color:#93c5fd; text-decoration:none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Apache Static Host</h1>
|
||||
<p>This is the static landing page container.</p>
|
||||
<p><a href="http://localhost:8081/wp-admin" target="_blank">Open WordPress setup (wp-admin)</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
# Install required PHP extensions for WordPress
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libpng-dev \
|
||||
libjpeg-dev \
|
||||
libfreetype6-dev \
|
||||
libzip-dev \
|
||||
libicu-dev \
|
||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install -j$(nproc) \
|
||||
gd \
|
||||
mysqli \
|
||||
pdo_mysql \
|
||||
zip \
|
||||
intl \
|
||||
opcache \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enable Apache modules
|
||||
RUN a2enmod rewrite headers expires
|
||||
|
||||
# Copy custom Apache configuration
|
||||
COPY conf/httpd.conf /etc/apache2/sites-available/000-default.conf
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /var/www
|
||||
|
||||
EXPOSE 80
|
||||
@@ -1,22 +0,0 @@
|
||||
# Main Apache configuration for multi-user WordPress hosting
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin admin@localhost
|
||||
DocumentRoot /var/www
|
||||
|
||||
<Directory /var/www>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<FilesMatch \.php$>
|
||||
SetHandler application/x-httpd-php
|
||||
</FilesMatch>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# Include user site configs from each user volume
|
||||
IncludeOptional /var/www/*/site_conf/site.conf
|
||||
@@ -1,13 +0,0 @@
|
||||
<VirtualHost *:80>
|
||||
ServerName {USER_DOMAIN}
|
||||
ServerAlias www.{USER_DOMAIN}
|
||||
DocumentRoot /var/www/{USER_VOLUME}/wordpress_content
|
||||
|
||||
<Directory "/var/www/{USER_VOLUME}/wordpress_content">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog /var/www/{USER_VOLUME}/site_conf/error.log
|
||||
CustomLog /var/www/{USER_VOLUME}/site_conf/access.log combined
|
||||
</VirtualHost>
|
||||
@@ -1,58 +0,0 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
apache:
|
||||
build:
|
||||
context: ./apache
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- wordpress_master:/var/www/master
|
||||
# - ./volumes/data1-volume:/var/www/data1
|
||||
# - ./volumes/data2-volume:/var/www/data2
|
||||
environment:
|
||||
WORDPRESS_DB_HOST: db:3306
|
||||
WORDPRESS_DB_USER: wp_user
|
||||
WORDPRESS_DB_PASSWORD: wp_password
|
||||
WORDPRESS_DB_NAME: wp_master
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- wordpress_network
|
||||
|
||||
db:
|
||||
image: mariadb:latest
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root_password
|
||||
MYSQL_DATABASE: wp_master
|
||||
MYSQL_USER: wp_user
|
||||
MYSQL_PASSWORD: wp_password
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- wordpress_network
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin:latest
|
||||
ports:
|
||||
- "8080:80"
|
||||
environment:
|
||||
PMA_HOST: db
|
||||
MYSQL_ROOT_PASSWORD: root_password
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- wordpress_network
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
wordpress_master:
|
||||
|
||||
networks:
|
||||
wordpress_network:
|
||||
driver: bridge
|
||||
@@ -1,371 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Helper script for managing the OCF-style WordPress hosting platform
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}=========================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}=========================================${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗ $1${NC}"
|
||||
}
|
||||
|
||||
# Help function
|
||||
show_help() {
|
||||
cat << EOF
|
||||
OCF WordPress Hosting Manager
|
||||
|
||||
Usage: ./manage.sh [command]
|
||||
|
||||
Commands:
|
||||
start Build and start all services
|
||||
stop Stop all services
|
||||
restart Restart all services
|
||||
status Show status of all services
|
||||
logs [service] Show logs (optionally for specific service)
|
||||
|
||||
user-add Register a new user
|
||||
user-list List all registered users
|
||||
user-remove Remove a user (with backup)
|
||||
|
||||
db-backup Backup the database
|
||||
db-restore Restore database from backup
|
||||
db-shell Open database shell
|
||||
|
||||
test-php Test PHP functionality
|
||||
test-db Test database connectivity
|
||||
|
||||
clean Stop and remove all containers, volumes, and networks
|
||||
clean-all Clean everything including user data (DANGEROUS!)
|
||||
|
||||
help Show this help message
|
||||
|
||||
Examples:
|
||||
./manage.sh start
|
||||
./manage.sh user-add
|
||||
./manage.sh logs apache
|
||||
./manage.sh db-backup
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Start services
|
||||
cmd_start() {
|
||||
print_header "Starting Services"
|
||||
docker-compose up -d --build
|
||||
print_success "Services started"
|
||||
echo ""
|
||||
cmd_status
|
||||
}
|
||||
|
||||
# Stop services
|
||||
cmd_stop() {
|
||||
print_header "Stopping Services"
|
||||
docker-compose down
|
||||
print_success "Services stopped"
|
||||
}
|
||||
|
||||
# Restart services
|
||||
cmd_restart() {
|
||||
print_header "Restarting Services"
|
||||
docker-compose restart
|
||||
print_success "Services restarted"
|
||||
}
|
||||
|
||||
# Show status
|
||||
cmd_status() {
|
||||
print_header "Service Status"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
echo "Access URLs:"
|
||||
echo " • Test Site: http://localhost"
|
||||
echo " • phpMyAdmin: http://localhost:8080"
|
||||
}
|
||||
|
||||
# Show logs
|
||||
cmd_logs() {
|
||||
local service=${1:-""}
|
||||
if [ -n "$service" ]; then
|
||||
docker-compose logs -f "$service"
|
||||
else
|
||||
docker-compose logs -f
|
||||
fi
|
||||
}
|
||||
|
||||
# Add new user
|
||||
cmd_user_add() {
|
||||
print_header "Register New User"
|
||||
read -p "Enter username: " username
|
||||
read -p "Enter domain (e.g., alice.local): " domain
|
||||
|
||||
if [ -z "$username" ] || [ -z "$domain" ]; then
|
||||
print_error "Username and domain are required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./register_user.sh "$username" "$domain"
|
||||
|
||||
echo ""
|
||||
print_warning "Don't forget to:"
|
||||
echo " 1. Add volume to docker-compose.yml"
|
||||
echo " 2. Run: ./manage.sh restart"
|
||||
echo " 3. Add '$domain' to /etc/hosts pointing to 127.0.0.1"
|
||||
}
|
||||
|
||||
# List users
|
||||
cmd_user_list() {
|
||||
print_header "Registered Users"
|
||||
|
||||
if [ ! -d "./volumes" ] || [ -z "$(ls -A ./volumes 2>/dev/null)" ]; then
|
||||
print_warning "No users registered yet"
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Volume\t\t\tDomain${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
for vol_dir in ./volumes/*/; do
|
||||
if [ -d "$vol_dir" ]; then
|
||||
vol_name=$(basename "$vol_dir")
|
||||
conf_file="${vol_dir}site_conf/site.conf"
|
||||
|
||||
if [ -f "$conf_file" ]; then
|
||||
domain=$(grep "ServerName" "$conf_file" | awk '{print $2}')
|
||||
echo -e "${vol_name}\t\t${domain}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Remove user
|
||||
cmd_user_remove() {
|
||||
print_header "Remove User"
|
||||
cmd_user_list
|
||||
echo ""
|
||||
read -p "Enter volume name to remove (e.g., data1-volume): " vol_name
|
||||
|
||||
if [ -z "$vol_name" ]; then
|
||||
print_error "Volume name required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
vol_path="./volumes/${vol_name}"
|
||||
|
||||
if [ ! -d "$vol_path" ]; then
|
||||
print_error "Volume not found: $vol_path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_warning "This will backup and remove: $vol_path"
|
||||
read -p "Are you sure? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
print_warning "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create backup
|
||||
backup_name="backup_${vol_name}_$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
tar -czf "$backup_name" "$vol_path"
|
||||
print_success "Backup created: $backup_name"
|
||||
|
||||
# Remove volume
|
||||
rm -rf "$vol_path"
|
||||
print_success "Volume removed: $vol_path"
|
||||
|
||||
print_warning "Remember to remove the volume mount from docker-compose.yml"
|
||||
}
|
||||
|
||||
# Database backup
|
||||
cmd_db_backup() {
|
||||
print_header "Database Backup"
|
||||
backup_file="db_backup_$(date +%Y%m%d_%H%M%S).sql"
|
||||
|
||||
docker-compose exec -T db mysqldump -u wp_user -pwp_password wp_master > "$backup_file"
|
||||
print_success "Database backed up to: $backup_file"
|
||||
}
|
||||
|
||||
# Database restore
|
||||
cmd_db_restore() {
|
||||
print_header "Database Restore"
|
||||
|
||||
# List available backups
|
||||
echo "Available backups:"
|
||||
ls -1 db_backup_*.sql 2>/dev/null || print_warning "No backups found"
|
||||
echo ""
|
||||
|
||||
read -p "Enter backup file name: " backup_file
|
||||
|
||||
if [ ! -f "$backup_file" ]; then
|
||||
print_error "Backup file not found: $backup_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_warning "This will restore database from: $backup_file"
|
||||
read -p "Are you sure? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
print_warning "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker-compose exec -T db mysql -u wp_user -pwp_password wp_master < "$backup_file"
|
||||
print_success "Database restored from: $backup_file"
|
||||
}
|
||||
|
||||
# Database shell
|
||||
cmd_db_shell() {
|
||||
print_header "Database Shell"
|
||||
echo "Connecting to MariaDB..."
|
||||
docker-compose exec db mysql -u wp_user -pwp_password wp_master
|
||||
}
|
||||
|
||||
# Test PHP
|
||||
cmd_test_php() {
|
||||
print_header "Testing PHP"
|
||||
|
||||
if ! docker-compose ps | grep -q apache.*Up; then
|
||||
print_error "Apache container is not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Testing PHP version..."
|
||||
docker-compose exec apache php -v
|
||||
echo ""
|
||||
|
||||
echo "Testing PHP extensions..."
|
||||
docker-compose exec apache php -m | grep -E "(mysqli|gd|zip)"
|
||||
echo ""
|
||||
|
||||
print_success "PHP is working correctly"
|
||||
}
|
||||
|
||||
# Test database
|
||||
cmd_test_db() {
|
||||
print_header "Testing Database Connection"
|
||||
|
||||
if ! docker-compose ps | grep -q db.*Up; then
|
||||
print_error "Database container is not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
result=$(docker-compose exec -T apache php -r "echo mysqli_connect('db', 'wp_user', 'wp_password', 'wp_master') ? 'success' : 'failed';")
|
||||
|
||||
if [ "$result" = "success" ]; then
|
||||
print_success "Database connection successful"
|
||||
else
|
||||
print_error "Database connection failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Clean containers
|
||||
cmd_clean() {
|
||||
print_header "Cleaning Containers"
|
||||
print_warning "This will stop and remove containers, networks, and anonymous volumes"
|
||||
read -p "Are you sure? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
print_warning "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker-compose down -v
|
||||
print_success "Cleaned up containers and volumes"
|
||||
}
|
||||
|
||||
# Clean everything
|
||||
cmd_clean_all() {
|
||||
print_header "DANGER: Clean Everything"
|
||||
print_error "This will remove ALL containers, volumes, AND user data"
|
||||
print_error "This action CANNOT be undone!"
|
||||
read -p "Type 'DELETE EVERYTHING' to confirm: " confirm
|
||||
|
||||
if [ "$confirm" != "DELETE EVERYTHING" ]; then
|
||||
print_warning "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker-compose down -v
|
||||
rm -rf ./volumes/*
|
||||
print_success "Everything cleaned"
|
||||
}
|
||||
|
||||
# Main command router
|
||||
case "${1:-help}" in
|
||||
start)
|
||||
cmd_start
|
||||
;;
|
||||
stop)
|
||||
cmd_stop
|
||||
;;
|
||||
restart)
|
||||
cmd_restart
|
||||
;;
|
||||
status)
|
||||
cmd_status
|
||||
;;
|
||||
logs)
|
||||
cmd_logs "$2"
|
||||
;;
|
||||
user-add)
|
||||
cmd_user_add
|
||||
;;
|
||||
user-list)
|
||||
cmd_user_list
|
||||
;;
|
||||
user-remove)
|
||||
cmd_user_remove
|
||||
;;
|
||||
db-backup)
|
||||
cmd_db_backup
|
||||
;;
|
||||
db-restore)
|
||||
cmd_db_restore
|
||||
;;
|
||||
db-shell)
|
||||
cmd_db_shell
|
||||
;;
|
||||
test-php)
|
||||
cmd_test_php
|
||||
;;
|
||||
test-db)
|
||||
cmd_test_db
|
||||
;;
|
||||
clean)
|
||||
cmd_clean
|
||||
;;
|
||||
clean-all)
|
||||
cmd_clean_all
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown command: $1"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,40 @@
|
||||
import json
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
json_path = "wordfence_vulnerabilities.json"
|
||||
|
||||
def load_cvss_scores(path):
|
||||
"""Load JSON data and extract all CVSS scores into a list"""
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
scores = []
|
||||
for entry in data:
|
||||
|
||||
if "cvss_score" in entry and isinstance(entry["cvss_score"], (int, float)):
|
||||
scores.append(entry["cvss_score"])
|
||||
return scores
|
||||
|
||||
|
||||
def plot_hist(scores):
|
||||
"""Plot a histogram of CVSS scores"""
|
||||
plt.figure(figsize=(8, 5))
|
||||
plt.hist(scores, bins=10, edgecolor="black", color="skyblue")
|
||||
plt.title("Distribution of CVSS Scores in Vulnerability Data")
|
||||
plt.xlabel("CVSS Score")
|
||||
plt.ylabel("Number of Vulnerabilities")
|
||||
plt.grid(alpha=0.4)
|
||||
plt.savefig("cvss_distribution.png")
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
scores = load_cvss_scores(json_path)
|
||||
print(f"Loaded {len(scores)} CVSS scores.")
|
||||
print("Sample:", scores[:10])
|
||||
|
||||
if scores:
|
||||
plot_hist(scores)
|
||||
else:
|
||||
print("error")
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
from collections import Counter
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
path = "wordfence_vulnerabilities.json"
|
||||
|
||||
# Load JSON data
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
vuln_types = []
|
||||
|
||||
for entry in data:
|
||||
title = entry.get("title")
|
||||
if not isinstance(title, str):
|
||||
continue
|
||||
|
||||
# Split on the first dash (" - ") and take the right-hand side
|
||||
if " - " in title:
|
||||
vuln = title.split(" - ", 1)[1].strip()
|
||||
vuln_types.append(vuln)
|
||||
|
||||
# Count occurrences
|
||||
counts = Counter(vuln_types)
|
||||
top25 = counts.most_common(25)
|
||||
total = sum(counts.values())
|
||||
|
||||
if not vuln_types:
|
||||
print("error")
|
||||
exit()
|
||||
|
||||
# Print table of top 25
|
||||
print("\nTop 25 Vulnerability Types:\n")
|
||||
for name, count in top25:
|
||||
rel = (count / total) * 100
|
||||
print(f"{name:60} {count:5d} ({rel:5.2f}%)")
|
||||
|
||||
# Visualization
|
||||
labels, values = zip(*top25)
|
||||
plt.figure(figsize=(10, 6))
|
||||
plt.barh(labels[::-1], values[::-1], color="cornflowerblue")
|
||||
plt.title("Top 25 Most Common Vulnerability Types")
|
||||
plt.xlabel("Count")
|
||||
plt.ylabel("Vulnerability Type")
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage: ./register_user.sh USER_NAME USER_DOMAIN
|
||||
# Example: ./register_user.sh alice alice.example.com
|
||||
|
||||
set -e
|
||||
|
||||
USER_NAME="$1"
|
||||
USER_DOMAIN="$2"
|
||||
|
||||
if [ -z "$USER_NAME" ] || [ -z "$USER_DOMAIN" ]; then
|
||||
echo "Usage: $0 USER_NAME USER_DOMAIN"
|
||||
echo "Example: $0 alice alice.example.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Create volumes directory if it doesn't exist
|
||||
mkdir -p ./volumes
|
||||
|
||||
# Decide next data folder number
|
||||
if [ -d "./volumes" ] && [ "$(ls -A ./volumes)" ]; then
|
||||
NEXT_INDEX=$(ls -1d volumes/data* 2>/dev/null | wc -l)
|
||||
NEXT_INDEX=$((NEXT_INDEX + 1))
|
||||
else
|
||||
NEXT_INDEX=1
|
||||
fi
|
||||
|
||||
USER_VOLUME="data${NEXT_INDEX}"
|
||||
VOLUME_DIR="./volumes/${USER_VOLUME}-volume"
|
||||
|
||||
echo "========================================="
|
||||
echo "Creating new user site:"
|
||||
echo " User: ${USER_NAME}"
|
||||
echo " Domain: ${USER_DOMAIN}"
|
||||
echo " Volume: ${USER_VOLUME}"
|
||||
echo "========================================="
|
||||
|
||||
# Create volume directory structure
|
||||
mkdir -p "${VOLUME_DIR}/site_conf"
|
||||
mkdir -p "${VOLUME_DIR}/wordpress_content"
|
||||
mkdir -p "${VOLUME_DIR}/database"
|
||||
|
||||
# Copy vhost template and replace placeholders
|
||||
TEMPLATE_FILE="./apache/vhost-templates/user_vhost.template"
|
||||
TARGET_CONF="${VOLUME_DIR}/site_conf/site.conf"
|
||||
|
||||
if [ ! -f "$TEMPLATE_FILE" ]; then
|
||||
echo "ERROR: Template file not found: $TEMPLATE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed \
|
||||
-e "s/{USER_DOMAIN}/${USER_DOMAIN}/g" \
|
||||
-e "s/{USER_VOLUME}/${USER_VOLUME}/g" \
|
||||
"${TEMPLATE_FILE}" > "${TARGET_CONF}"
|
||||
|
||||
echo "✓ Created site configuration at ${TARGET_CONF}"
|
||||
|
||||
# Download WordPress into the user's content directory
|
||||
echo "Downloading WordPress..."
|
||||
cd "${VOLUME_DIR}/wordpress_content"
|
||||
curl -O https://wordpress.org/latest.tar.gz
|
||||
tar -xzf latest.tar.gz --strip-components=1
|
||||
rm latest.tar.gz
|
||||
|
||||
# Create wp-config.php with database connection
|
||||
cat > wp-config.php << 'EOF'
|
||||
<?php
|
||||
define('DB_NAME', getenv('WORDPRESS_DB_NAME') ?: 'wp_master');
|
||||
define('DB_USER', getenv('WORDPRESS_DB_USER') ?: 'wp_user');
|
||||
define('DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD') ?: 'wp_password');
|
||||
define('DB_HOST', getenv('WORDPRESS_DB_HOST') ?: 'db:3306');
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
define('DB_COLLATE', '');
|
||||
|
||||
// Unique keys and salts (generate from https://api.wordpress.org/secret-key/1.1/salt/)
|
||||
define('AUTH_KEY', 'put your unique phrase here');
|
||||
define('SECURE_AUTH_KEY', 'put your unique phrase here');
|
||||
define('LOGGED_IN_KEY', 'put your unique phrase here');
|
||||
define('NONCE_KEY', 'put your unique phrase here');
|
||||
define('AUTH_SALT', 'put your unique phrase here');
|
||||
define('SECURE_AUTH_SALT', 'put your unique phrase here');
|
||||
define('LOGGED_IN_SALT', 'put your unique phrase here');
|
||||
define('NONCE_SALT', 'put your unique phrase here');
|
||||
|
||||
$table_prefix = 'wp_';
|
||||
|
||||
define('WP_DEBUG', false);
|
||||
|
||||
if ( !defined('ABSPATH') )
|
||||
define('ABSPATH', dirname(__FILE__) . '/');
|
||||
|
||||
require_once(ABSPATH . 'wp-settings.php');
|
||||
EOF
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "✓ WordPress installed to ${VOLUME_DIR}/wordpress_content"
|
||||
|
||||
# Create initial database dump placeholder
|
||||
cat > "${VOLUME_DIR}/database/README.md" << EOF
|
||||
# Database Directory for ${USER_NAME}
|
||||
|
||||
This directory can contain:
|
||||
- SQL dump files for backup/restore
|
||||
- Database migration scripts
|
||||
- User-specific database notes
|
||||
|
||||
The WordPress installation uses the shared database defined in docker-compose.yml.
|
||||
Each user site should use a unique table prefix in wp-config.php.
|
||||
EOF
|
||||
|
||||
echo "✓ Created database directory with README"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "✓ User ${USER_NAME} registered successfully!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Add this volume mount to docker-compose.yml:"
|
||||
echo " - ./volumes/${USER_VOLUME}-volume:/var/www/${USER_VOLUME}"
|
||||
echo ""
|
||||
echo "2. Restart the Apache container:"
|
||||
echo " docker-compose restart apache"
|
||||
echo ""
|
||||
echo "3. Add DNS/hosts entry for ${USER_DOMAIN} pointing to your server"
|
||||
echo ""
|
||||
echo "4. Visit http://${USER_DOMAIN} to complete WordPress setup"
|
||||
echo ""
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
requests
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
|
||||
# vars
|
||||
JSON_FILE = "wordfence_vulnerabilities.json"
|
||||
BAD_LIST = []
|
||||
|
||||
JSON_OUT = "matches.json"
|
||||
|
||||
|
||||
def load_local(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def get_entries(data):
|
||||
# try to find the main list of vulnerabilities
|
||||
if isinstance(data, dict):
|
||||
if "vulnerabilities" in data:
|
||||
return data["vulnerabilities"]
|
||||
for value in data.values():
|
||||
if isinstance(value, list):
|
||||
return value
|
||||
return []
|
||||
elif isinstance(data, list):
|
||||
return data
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def main():
|
||||
if os.path.exists(JSON_FILE):
|
||||
print("Loading ...", JSON_FILE)
|
||||
data = load_local(JSON_FILE)
|
||||
else:
|
||||
print("Error: JSON file not found:", JSON_FILE)
|
||||
return
|
||||
|
||||
entries = get_entries(data)
|
||||
|
||||
bad_set = set(BAD_LIST)
|
||||
hits = []
|
||||
|
||||
for item in entries:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
|
||||
if item.get("type") != "plugin":
|
||||
continue
|
||||
|
||||
slug = (item.get("slug") or "").strip()
|
||||
if not slug:
|
||||
continue
|
||||
|
||||
if slug in bad_set:
|
||||
hit = {
|
||||
"slug": slug,
|
||||
"title": item.get("title"),
|
||||
"cve": item.get("cve"),
|
||||
"severity": item.get("severity"),
|
||||
"cvss_score": item.get("cvss_score"),
|
||||
"cve_link": item.get("cve_link"),
|
||||
"raw": item
|
||||
}
|
||||
hits.append(hit)
|
||||
|
||||
if not hits:
|
||||
print("No matches at all")
|
||||
else:
|
||||
print("Found", len(hits), "matches:")
|
||||
for h in hits:
|
||||
print(
|
||||
"-",
|
||||
h["slug"],
|
||||
"| CVE:", h.get("cve"),
|
||||
"| sev:", h.get("severity"),
|
||||
"| CVSS:", h.get("cvss_score")
|
||||
)
|
||||
print(" link:", h.get("cve_link"))
|
||||
|
||||
# save
|
||||
with open(JSON_OUT, "w", encoding="utf-8") as f:
|
||||
json.dump(hits, f, ensure_ascii=False, indent=2)
|
||||
print("Saved to", JSON_OUT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,2 @@
|
||||
get_CVE.py **MUST** be ran before cve_scanner_new1 can be ran since it runs using a list that is fetched daily.
|
||||
CVE_scanner.py runs on a static list called wordfence_vulnerabilities.json that is stored in the same directory, which is an old list of major vulnerabilities.
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
|
||||
JSON_FILE = "wordfence_CVE.json"
|
||||
JSON_OUT = "malware.json"
|
||||
BAD_PLUGINS = []
|
||||
|
||||
|
||||
def load_file(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def main():
|
||||
if not os.path.exists(JSON_FILE):
|
||||
print("json file not found:", JSON_FILE)
|
||||
return
|
||||
|
||||
data = load_file(JSON_FILE)
|
||||
|
||||
bad_set = set()
|
||||
for n in BAD_PLUGINS:
|
||||
if isinstance(n, str):
|
||||
n = n.strip()
|
||||
if n:
|
||||
bad_set.add(n)
|
||||
|
||||
hits = []
|
||||
|
||||
for key, item in data.items():
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
|
||||
software_list = item.get("software") or []
|
||||
for s in software_list:
|
||||
if not isinstance(s, dict):
|
||||
continue
|
||||
if s.get("type") != "plugin":
|
||||
continue
|
||||
|
||||
name = (s.get("name") or "").strip()
|
||||
if name not in bad_set:
|
||||
continue
|
||||
|
||||
affected = s.get("affected_versions") or {}
|
||||
if not affected:
|
||||
continue
|
||||
|
||||
refs = item.get("references") or []
|
||||
ref = refs[0] if refs else None
|
||||
|
||||
hit = {
|
||||
"id": item.get("id"),
|
||||
"title": item.get("title"),
|
||||
"name": name,
|
||||
"slug": s.get("slug"),
|
||||
"affected_versions": list(affected.keys()),
|
||||
"link": ref,
|
||||
"raw": item
|
||||
}
|
||||
hits.append(hit)
|
||||
|
||||
if not hits:
|
||||
print("no matches found")
|
||||
else:
|
||||
print("found", len(hits), "matches")
|
||||
for h in hits:
|
||||
print("-", h["name"], "|", ", ".join(h["affected_versions"]))
|
||||
|
||||
with open(JSON_OUT, "w", encoding="utf-8") as f:
|
||||
json.dump(hits, f, ensure_ascii=False, indent=2)
|
||||
print("saved json to", JSON_OUT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
import requests
|
||||
import os
|
||||
|
||||
URL = "https://www.wordfence.com/api/intelligence/v2/vulnerabilities/scanner"
|
||||
OUT_FILE = "wordfence_CVE.json"
|
||||
|
||||
def main():
|
||||
print("API request.....")
|
||||
r = requests.get(URL, timeout=60)
|
||||
r.raise_for_status()
|
||||
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
out_path = os.path.join(script_dir, OUT_FILE)
|
||||
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
f.write(r.text)
|
||||
|
||||
print("File Saved!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1165623
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+520306
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
FROM wordpress:latest
|
||||
# You can add themes/plugins or custom setup here
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
// Basic WordPress config example
|
||||
define('DB_NAME', getenv('WORDPRESS_DB_NAME'));
|
||||
define('DB_USER', getenv('WORDPRESS_DB_USER'));
|
||||
define('DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD'));
|
||||
define('DB_HOST', getenv('WORDPRESS_DB_HOST'));
|
||||
define('DB_CHARSET', 'utf8');
|
||||
define('DB_COLLATE', '');
|
||||
|
||||
$table_prefix = 'wp_';
|
||||
|
||||
define('WP_DEBUG', false);
|
||||
|
||||
if ( !defined('ABSPATH') )
|
||||
define('ABSPATH', dirname(__FILE__) . '/');
|
||||
|
||||
require_once(ABSPATH . 'wp-settings.php');
|
||||
|
||||
Reference in New Issue
Block a user