Webinoly implements multiple layers of security hardening to protect your web server and applications from common attacks and vulnerabilities.
Server hardening
Kernel optimization
Webinoly automatically applies kernel-level security optimizations:
Network stack protection:
# SYN flood protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
# IP spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
File system protection:
# Protect against hard/symbolic link attacks
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
# Restrict dmesg access
kernel.dmesg_restrict = 1
Kernel optimizations are applied automatically during installation. Disable with kernel-optim:false in the configuration file.
Automatic security updates
Webinoly disables Ubuntu’s automatic updates by default to prevent unexpected issues:
# Enable automatic updates (if desired)
sudo nano /opt/webinoly/webinoly.conf
# Set: auto-updates:true
sudo webinoly -server-reset
While automatic updates improve security, they may cause unexpected service disruptions. Test updates in a staging environment first.
Nginx security
Prevent server version disclosure:
server_tokens off; # Hides Nginx version
Removes version information from:
- HTTP headers (
Server: nginx)
- Error pages
- Response headers
Rate limiting
Protect against brute-force and DoS attacks:
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=wp:10m rate=5r/s;
Configured zones:
one: General rate limit (1 request/second)
wp: WordPress admin area (5 requests/second)
WP-Admin protection
Disable rate limiting
WordPress admin areas are automatically protected:location ~ ^/wp-admin/ {
limit_req zone=wp burst=10 nodelay;
# Additional rules...
}
Default limits:
- 5 requests per second
- Burst of 10 requests allowed
- Returns HTTP 429 (Too Many Requests) when exceeded
Disable WordPress admin rate limiting (not recommended):sudo nano /opt/webinoly/webinoly.conf
# Set: wp-admin-limited:false
sudo webinoly -server-reset
File access restrictions
Webinoly blocks access to sensitive files by default:
Blocked file extensions (default):
.7z .ai .alfa .backup .bak .bash .bat .bin .bz2 .c .cfg .cgi
.class .com .conf .cpp .dat .db .dll .dmg .env .exe .git .gz
.ini .iso .jar .log .old .orig .pdb .pem .phar .php~ .pkg .pl
.py .rar .rpm .sh .sql .swp .sys .tar .tmp .war .yml .zip
Blocked filenames (case-insensitive):
changelog, environment, install, license, readme, upgrade,
wp-config, composer.json, package.json
Blocked patterns (exact match):
/node_modules/, /fixtures/, /behat/, /.git/, /.env
Customize blocked files in /opt/webinoly/webinoly.conf using the locations-deny-* variables.
Hidden files protection
Dot files (hidden files) are blocked by default:
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
Protects:
.htaccess
.git/
.env
.config
.htpasswd
PHP security
Disabled functions
Webinoly disables dangerous PHP functions by default:
Default disabled functions:
// System execution
pcntl_exec, pcntl_fork, pcntl_alarm, pcntl_signal, posix_kill
// Shell access
system, exec, shell_exec, passthru, proc_open, popen
// File system
link, symlink, dl, highlight_file, show_source
// Network
socket_accept, socket_bind, socket_connect, socket_listen
// Other
putenv, escapeshellcmd, proc_terminate, diskfreespace
Some applications may require specific functions. Test thoroughly after enabling any disabled functions.
Re-enable specific functions:
# Edit PHP configuration
sudo nano /opt/webinoly/webinoly.conf
# Remove unwanted functions from the list
php-disable-functions:system,exec,shell_exec
# Apply changes
sudo webinoly -server-reset=php
URL fopen restriction
Prevents remote file inclusion attacks:
allow_url_fopen = Off // Default: disabled
Enable only if required:
sudo nano /opt/webinoly/webinoly.conf
php-allow-url-fopen:true
sudo webinoly -server-reset=php
Session security
PHP sessions are configured with security best practices:
session.use_strict_mode = 1 // Reject uninitialized session IDs
session.cookie_httponly = 1 // Prevent JavaScript access
session.cookie_secure = 1 // HTTPS-only transmission
session.cookie_samesite = Lax // CSRF protection
Prevent PHP version exposure:
expose_php = Off // Removes X-Powered-By header
SSL/TLS security
Modern protocols only
Webinoly enforces modern TLS protocols:
ssl_protocols TLSv1.2 TLSv1.3;
TLS 1.0 and 1.1 are deprecated and disabled for security.
Strong cipher suites
Secure cipher configuration:
ssl_prefer_server_ciphers off;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:
DHE-RSA-CHACHA20-POLY1305';
DH parameters
Webinoly generates 2048-bit Diffie-Hellman parameters for key exchange:
# Located at
/etc/ssl/dhparam.pem
Session management
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off; // Disabled for security
kTLS support
Hardware-accelerated TLS on Ubuntu 22.04+:
ssl_conf_command Options KTLS;
Webinoly configures security headers automatically:
HSTS (HTTP Strict Transport Security)
Force HTTPS connections:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Default: 1 year (31536000 seconds)
Modify HSTS max-age:sudo nano /opt/webinoly/webinoly.conf
header-hsts:63072000 # 2 years
sudo webinoly -server-reset
Enable HSTS preload (permanent HTTPS):sudo nano /opt/webinoly/webinoly.conf
header-hsts:preload # Sets max-age to 2 years + preload directive
sudo webinoly -server-reset
X-Frame-Options
Prevent clickjacking attacks:
X-Frame-Options: SAMEORIGIN // Default
Options:
SAMEORIGIN - Allow framing from same origin
DENY - Block all framing
ALLOW-FROM https://example.com - Allow specific origin
X-Content-Type-Options
Prevent MIME-type sniffing:
X-Content-Type-Options: nosniff
Referrer-Policy
Control referrer information:
Referrer-Policy: strict-origin-when-cross-origin // Default
Content-Security-Policy (CSP)
Not configured by default. Add custom CSP:
sudo nano /opt/webinoly/webinoly.conf
header-csp:default-src 'self'; script-src 'self' 'unsafe-inline'
sudo webinoly -server-reset
Permissions-Policy
Control browser features:
# Disable all features
header-permissions:accelerometer=(),camera=(),geolocation=(),microphone=()
# Or block FLoC specifically
header-permissions:floc
WordPress security
HTTP authentication
Webinoly adds HTTP Basic Authentication to wp-admin by default:
# Enabled automatically for new WordPress sites
sudo site example.com -wp
# Enable for existing site
sudo httpauth example.com -wp-admin=on
# Disable (not recommended)
sudo httpauth example.com -wp-admin=off
HTTP authentication adds an extra layer of security before the WordPress login page.
Authentication whitelist
Bypass HTTP authentication for trusted IPs:
# Whitelist single IP
sudo httpauth -whitelist=1.2.3.4
# Whitelist multiple IPs
sudo httpauth -whitelist=1.2.3.4,5.6.7.8
# Or edit configuration
sudo nano /opt/webinoly/webinoly.conf
auth-whitelist-ip:1.2.3.4,5.6.7.8
sudo webinoly -server-reset
XML-RPC blocking
XML-RPC is blocked by default to prevent brute-force attacks:
# Verify XML-RPC is blocked
curl -X POST https://example.com/xmlrpc.php
# Should return 403 Forbidden
# Enable XML-RPC (not recommended)
sudo nano /opt/webinoly/webinoly.conf
xmlrpc:open
sudo webinoly -server-reset
WP-CLI security
WP-CLI is installed with restricted permissions:
# Only accessible by www-data and root
sudo -u www-data wp --info
MySQL/MariaDB security
Secure installation
Webinoly runs mysql_secure_installation automatically:
- Root password set (randomly generated)
- Remote root login disabled
- Anonymous users removed
- Test database removed
- Privileges flushed
Admin user
Creates a separate admin user with full privileges:
-- Instead of using root, use the admin user
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'random_password';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
Credentials stored:
# Located in
/opt/webinoly/webinoly.conf
# Encrypted storage
mysql-admin:<encrypted_password>
Public access disabled
MySQL/MariaDB binds to localhost only:
bind-address = 127.0.0.1 # Default
Enable remote access (if needed):
sudo webinoly -mysql-public-access=on
# Or bind to specific IP
sudo webinoly -mysql-public-access=1.2.3.4
Opening MySQL to public access increases attack surface. Use firewall rules and strong passwords.
Firewall configuration
Webinoly doesn’t configure a firewall by default. Use UFW:
# Install and enable UFW
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow essential services
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 22222/tcp # Admin tools (optional)
# Enable firewall
sudo ufw enable
IP blocking
Block specific IPs or ranges:
# Block single IP
sudo webinoly -blockip=1.2.3.4
# Block multiple IPs
sudo webinoly -blockip=1.2.3.4,5.6.7.8
# Block IP range (CIDR)
sudo webinoly -blockip=1.2.3.0/24
# Unblock IP
sudo webinoly -unblock=1.2.3.4
Monitoring and logging
Access logs
Access logs are disabled globally by default (performance):
# Enable access logs globally
sudo log -access-log=on
# Enable for specific site
sudo site example.com -log=on
Error logs
Error logs are always enabled:
# View Nginx errors
sudo tail -f /var/log/nginx/error.log
# View PHP-FPM errors
sudo tail -f /var/log/php8.4-fpm.log
# View MySQL errors
sudo tail -f /var/log/mysql/error.log
Webinoly uses custom log format for security monitoring:
log_format we_log '$remote_addr $upstream_response_time $upstream_cache_status [$time_local] '
'$host "$request" $status $body_bytes_sent $request_time '
'"$http_referer" "$http_user_agent"';
Security best practices
Essential security measures:
- Keep Webinoly and all packages updated
- Use strong passwords for all accounts
- Enable HTTP authentication for WordPress admin
- Configure SSL/TLS for all production sites
- Regularly review access logs for suspicious activity
- Use fail2ban for automated IP blocking
- Implement regular backup schedule
- Limit SSH access to specific IPs
- Disable unnecessary services
- Test security configuration regularly
Security auditing
Verify security configuration:
# System-wide verification
sudo webinoly -verify
# Check specific configurations
sudo nginx -t
sudo php-fpm8.4 -t
# Review security headers
curl -I https://example.com
# Test SSL configuration
sslscan example.com
# or
testssl.sh example.com
Fail2Ban
Automate IP blocking for repeated failed attempts:
sudo apt install fail2ban
# Configure Nginx jail
sudo nano /etc/fail2ban/jail.local
ModSecurity
Web application firewall (not included):
# Install ModSecurity for Nginx
sudo apt install libnginx-mod-security
ClamAV
Antivirus scanning:
sudo apt install clamav clamav-daemon
sudo freshclam