HEX
Server: Apache/2.4.65 (Debian)
System: Linux kubikelcreative 5.10.0-35-amd64 #1 SMP Debian 5.10.237-1 (2025-05-19) x86_64
User: www-data (33)
PHP: 8.4.13
Disabled: NONE
Upload Files
File: /var/www/indoadvisory_new/web2/webapp/apache.conf
# Apache Virtual Host Configuration for Indo Advisory
# Indonesian Private Equity Firm - Enterprise VPS Deployment
# Location: /etc/apache2/sites-available/indo-advisory.conf

<VirtualHost *:80>
    ServerName indoadvisory.com
    ServerAlias www.indoadvisory.com
    DocumentRoot /var/www/indo-advisory/public
    
    # Logging
    ErrorLog ${APACHE_LOG_DIR}/indo-advisory-error.log
    CustomLog ${APACHE_LOG_DIR}/indo-advisory-access.log combined
    
    # Security Headers
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "no-referrer-when-downgrade"
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    
    # Hide Apache version
    ServerTokens Prod
    ServerSignature Off
    
    # Enable compression
    <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        
        # Don't compress images
        SetEnvIfNoCase Request_URI \
            \.(?:gif|jpe?g|png|ico|svg)$ no-gzip dont-vary
        
        # Don't compress archives
        SetEnvIfNoCase Request_URI \
            \.(?:exe|t?gz|zip|bz2|sit|rar|pdf)$ no-gzip dont-vary
        
        # Compress text, html, javascript, css, xml
        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript
        AddOutputFilterByType DEFLATE application/json
    </IfModule>
    
    # Cache static assets
    <IfModule mod_expires.c>
        ExpiresActive On
        
        # Images
        ExpiresByType image/jpg "access plus 1 month"
        ExpiresByType image/jpeg "access plus 1 month"
        ExpiresByType image/gif "access plus 1 month"
        ExpiresByType image/png "access plus 1 month"
        ExpiresByType image/svg+xml "access plus 1 month"
        ExpiresByType image/x-icon "access plus 1 year"
        
        # CSS and JavaScript
        ExpiresByType text/css "access plus 1 month"
        ExpiresByType application/javascript "access plus 1 month"
        ExpiresByType application/x-javascript "access plus 1 month"
        
        # Fonts
        ExpiresByType font/woff "access plus 1 year"
        ExpiresByType font/woff2 "access plus 1 year"
        ExpiresByType application/font-woff "access plus 1 year"
        ExpiresByType application/font-woff2 "access plus 1 year"
        
        # HTML and other dynamic content
        ExpiresByType text/html "access plus 1 hour"
        ExpiresByType application/json "access plus 1 hour"
    </IfModule>
    
    # Static files directory
    <Directory "/var/www/indo-advisory/public">
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
        
        # Security for static files
        <FilesMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|pdf|doc|docx)$">
            # Add cache headers
            Header set Cache-Control "public, max-age=2592000"
        </FilesMatch>
        
        # Prevent access to sensitive files
        <FilesMatch "\.(env|config|sql|log|git)$">
            Require all denied
        </FilesMatch>
    </Directory>
    
    # Uploads directory (protected - proxy to Node.js for authentication)
    <LocationMatch "^/uploads/">
        ProxyPass http://127.0.0.1:3000/uploads/
        ProxyPassReverse http://127.0.0.1:3000/uploads/
        
        # Additional security headers
        Header set X-Content-Type-Options "nosniff"
        Header set X-Frame-Options "DENY"
    </LocationMatch>
    
    # API routes (proxy to Node.js with rate limiting)
    <LocationMatch "^/api/">
        ProxyPass http://127.0.0.1:3000/api/
        ProxyPassReverse http://127.0.0.1:3000/api/
        
        # Set proxy headers
        ProxyPreserveHost On
        ProxyPassReverse http://127.0.0.1:3000/api/
        
        # Rate limiting (requires mod_evasive)
        <IfModule mod_evasive24.c>
            DOSPageCount 100
            DOSPageInterval 1
            DOSSiteCount 50
            DOSSiteInterval 1
            DOSBlockingPeriod 300
        </IfModule>
    </LocationMatch>
    
    # Admin routes (proxy to Node.js with stricter security)
    <LocationMatch "^/admin">
        ProxyPass http://127.0.0.1:3000/admin
        ProxyPassReverse http://127.0.0.1:3000/admin
        
        # Stricter rate limiting for admin
        <IfModule mod_evasive24.c>
            DOSPageCount 10
            DOSPageInterval 1
            DOSSiteCount 20
            DOSSiteInterval 1
            DOSBlockingPeriod 600
        </IfModule>
        
        # IP whitelist (uncomment and configure for production)
        # Require ip 192.168.1.0/24
        # Require ip 203.0.113.0/24
    </LocationMatch>
    
    # Authentication routes (proxy to Node.js with rate limiting)
    <LocationMatch "^/auth/">
        ProxyPass http://127.0.0.1:3000/auth/
        ProxyPassReverse http://127.0.0.1:3000/auth/
        
        # Very strict rate limiting for auth
        <IfModule mod_evasive24.c>
            DOSPageCount 5
            DOSPageInterval 60
            DOSSiteCount 10
            DOSSiteInterval 60
            DOSBlockingPeriod 900
        </IfModule>
    </LocationMatch>
    
    # Language switcher
    <LocationMatch "^/lang/">
        ProxyPass http://127.0.0.1:3000/lang/
        ProxyPassReverse http://127.0.0.1:3000/lang/
    </LocationMatch>
    
    # All other requests (proxy to Node.js)
    ProxyPass /static/ !
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
    
    # Set proxy headers for all requests
    ProxyPreserveHost On
    ProxyPassReverse / http://127.0.0.1:3000/
    
    # Block access to sensitive files and directories
    <DirectoryMatch "^/var/www/indo-advisory/(\.git|node_modules|logs|migrations|scripts)">
        Require all denied
    </DirectoryMatch>
    
    <FilesMatch "^\.">
        Require all denied
    </FilesMatch>
    
    <FilesMatch "\.(env|config|sql|log)$">
        Require all denied
    </FilesMatch>
    
    # Block common exploit attempts
    RedirectMatch 404 ^/(wp-admin|wp-content|wp-includes|phpmyadmin|administrator|xmlrpc\.php)
    
    # Security rules
    <IfModule mod_rewrite.c>
        RewriteEngine On
        
        # Block suspicious requests
        RewriteCond %{QUERY_STRING} (eval\(|javascript:|vbscript:|onclick|onload) [NC,OR]
        RewriteCond %{QUERY_STRING} (<script|</script|<iframe|</iframe) [NC,OR]
        RewriteCond %{QUERY_STRING} (select.*from|union.*select|insert.*into|delete.*from) [NC]
        RewriteRule .* - [F,L]
        
        # Block file injection attempts
        RewriteCond %{REQUEST_URI} \.\./
        RewriteRule .* - [F,L]
        
        # Force HTTPS (uncomment after SSL setup)
        # RewriteCond %{HTTPS} off
        # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    </IfModule>
    
    # Additional security with mod_security (if available)
    <IfModule mod_security2.c>
        SecRuleEngine On
        SecDefaultAction "phase:2,deny,log,status:406"
        
        # Basic rules
        SecRule ARGS "@detectSQLi" \
            "id:1001,phase:2,block,msg:'SQL Injection Attack',logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}'"
        
        SecRule ARGS "@detectXSS" \
            "id:1002,phase:2,block,msg:'XSS Attack',logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}'"
    </IfModule>
</VirtualHost>

# SSL Configuration (uncomment after obtaining SSL certificate)
# <VirtualHost *:443>
#     ServerName indoadvisory.com
#     ServerAlias www.indoadvisory.com
#     DocumentRoot /var/www/indo-advisory/public
#     
#     # SSL Configuration
#     SSLEngine on
#     SSLCertificateFile /etc/letsencrypt/live/indoadvisory.com/fullchain.pem
#     SSLCertificateKeyFile /etc/letsencrypt/live/indoadvisory.com/privkey.pem
#     
#     # SSL Security Settings
#     SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
#     SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
#     SSLHonorCipherOrder on
#     SSLCompression off
#     
#     # HSTS Header
#     Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
#     
#     # Include all configurations from HTTP virtual host above
#     # (Copy all Directory, Location, and Proxy configurations)
#     
#     # Logging for HTTPS
#     ErrorLog ${APACHE_LOG_DIR}/indo-advisory-ssl-error.log
#     CustomLog ${APACHE_LOG_DIR}/indo-advisory-ssl-access.log combined
# </VirtualHost>

# Redirect HTTP to HTTPS (uncomment after SSL setup)
# <VirtualHost *:80>
#     ServerName indoadvisory.com
#     ServerAlias www.indoadvisory.com
#     
#     # Force redirect to HTTPS
#     RewriteEngine On
#     RewriteCond %{HTTPS} off
#     RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# </VirtualHost>