Guide10 min readMay 2, 2025

FreeScout Security Hardening: Production Setup (2025)

Complete security hardening guide for FreeScout. Covers firewall, fail2ban, SSH security, PHP hardening, backups, and compliance best practices.

A fresh FreeScout installation is functional but not secure for production. This guide hardens your FreeScout server against common attacks: brute-force login attempts, SQL injection, XSS, DDoS, unauthorized access, and data loss.

Following this guide brings your FreeScout installation to production-grade security.

The Three Layers of Security

  1. Network Security — Firewall, rate limiting, fail2ban
  2. Application Security — PHP hardening, input validation, headers
  3. Data Security — Backups, encryption, access control

Layer 1: Network Security

Step 1: Configure Firewall (UFW)

sudo ufw enable
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (critical!)
sudo ufw allow 22/tcp

# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Verify rules
sudo ufw status

Output should show:

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443/tcp                     ALLOW       Anywhere

Step 2: Configure Fail2Ban (Brute-Force Protection)

Fail2Ban blocks IP addresses that repeatedly fail login attempts.

sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Create a custom jail for FreeScout:

sudo nano /etc/fail2ban/jail.local

Add:

[DEFAULT]
bantime = 3600
maxretry = 5
findtime = 600

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log

[recidive]
enabled = true
filter = recidive
action = iptables-multiport[name=recidive, port="http,https"]
logpath = /var/log/fail2ban.log
bantime = 604800
findtime = 86400
maxretry = 5

Restart fail2ban:

sudo systemctl restart fail2ban

Verify it's working:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Step 3: Disable Root SSH Login

sudo nano /etc/ssh/sshd_config

Change:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding no

Reload SSH:

sudo systemctl reload sshd

From now on, SSH only via key-based auth and non-root user.

Step 4: Rate Limiting on NGINX

Edit your NGINX config:

limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

server {
    location / {
        limit_req zone=general burst=20;
        # ... rest of config
    }
    
    location ~ ^/login {
        limit_req zone=login burst=5;
        # ... rest of config
    }
}

This limits login attempts to 5 per minute per IP.

Reload NGINX:

sudo nginx -t
sudo systemctl reload nginx

Layer 2: Application Security

Step 5: PHP Security Hardening

Edit /etc/php/8.2/fpm/php.ini:

sudo nano /etc/php/8.2/fpm/php.ini

Set:

# Hide PHP version
expose_php = Off

# Disable dangerous functions
disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source

# Strict error reporting (don't expose errors to users)
display_errors = Off
log_errors = On
error_log = /var/www/freescout/storage/logs/php-error.log

# Session security
session.cookie_httponly = On
session.cookie_secure = On
session.use_only_cookies = On
session.cookie_samesite = Strict

# File upload limits
upload_max_filesize = 100M
post_max_size = 100M

# Memory limits
memory_limit = 256M
max_execution_time = 300

Restart PHP-FPM:

sudo systemctl restart php8.2-fpm

Step 6: NGINX Security Headers

Add to your NGINX config:

server {
    # ... existing config ...
    
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

Step 7: FreeScout Application Security

In /var/www/freescout/.env:

APP_ENV=production
APP_DEBUG=false
FORCE_HTTPS=true

Never set APP_DEBUG=true in production — it exposes sensitive information.

Step 8: Database User Permissions

Restrict the database user to only what it needs:

sudo mysql -u root -p
-- Remove default access
GRANT USAGE ON *.* TO 'freescout'@'localhost' REQUIRE NONE;
GRANT ALL PRIVILEGES ON freescout.* TO 'freescout'@'localhost';
FLUSH PRIVILEGES;

-- No access from other hosts
DROP USER IF EXISTS 'freescout'@'%';

Layer 3: Data Security

Step 9: Automated Backups

Set up automatic daily backups:

mkdir -p /var/backups/freescout

Create backup script /usr/local/bin/backup-freescout.sh:

#!/bin/bash

BACKUP_DIR="/var/backups/freescout"
DATE=$(date +%Y-%m-%d_%H%M%S)
DB_NAME="freescout"

# Create backup directory if it doesn't exist
mkdir -p $BACKUP_DIR

# Backup database
mysqldump -u freescout -p$DB_PASSWORD $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Backup application files
tar -czf $BACKUP_DIR/app_$DATE.tar.gz /var/www/freescout

# Keep only last 30 days of backups
find $BACKUP_DIR -type f -mtime +30 -delete

echo "Backup completed: $DATE"

Make it executable:

sudo chmod +x /usr/local/bin/backup-freescout.sh

Add to crontab:

sudo crontab -e

Add:

0 2 * * * /usr/local/bin/backup-freescout.sh >> /var/log/freescout-backup.log 2>&1

This runs backup at 2 AM daily.

Step 10: Upload Backups to External Storage (Cloud)

For maximum safety, store backups off-server:

# Using AWS S3
sudo apt install -y awscli

# Configure AWS credentials
aws configure

# Add to backup script
aws s3 cp /var/backups/freescout/db_$DATE.sql.gz s3://your-bucket/freescout/

Or use a service like Backblaze, Google Cloud Storage, or DigitalOcean Spaces.

Step 11: File Permissions

Ensure proper file permissions:

cd /var/www/freescout

# Web server owns application
sudo chown -R www-data:www-data .

# Directories: 755, Files: 644
sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;

# Sensitive directories: 700
sudo chmod 700 storage bootstrap/cache

Step 12: Log Monitoring

Enable log monitoring to detect attacks:

# View access logs
sudo tail -f /var/log/nginx/access.log

# View error logs
sudo tail -f /var/log/nginx/error.log

# View FreeScout logs
sudo tail -f /var/www/freescout/storage/logs/laravel.log

Look for:

  • Suspicious IP addresses
  • SQL injection attempts (UNION, SELECT, DROP keywords)
  • Path traversal attempts (../)
  • High 404 or 403 rates

Layer 4: Compliance & Auditing

Step 13: GDPR Compliance Checklist

  • Data Storage: Verify data is stored on your server (not third-party clouds)
  • Encryption: Use HTTPS for all traffic
  • Backups: Store backups securely (encrypted, off-site)
  • Access Control: Limit who can access FreeScout
  • Data Retention: Delete old tickets per your retention policy
  • Privacy Policy: Display privacy policy on your website
  • Consent: Get user consent before storing data

Step 14: Security Audit Checklist

Run this monthly:

# Check SSL certificate validity
echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -dates

# Check for security updates
sudo apt list --upgradable

# Review firewall rules
sudo ufw status

# Check fail2ban status
sudo fail2ban-client status

# Review backup status
ls -lh /var/backups/freescout/

# Check disk space
df -h

# Check MySQL version and updates
mysql --version

Security Incident Response

If you suspect a breach:

Immediate Actions

  1. Disable compromised users: Settings → Users → disable agent
  2. Force password reset: Ask all users to reset passwords
  3. Review logs: Check /var/log/nginx/access.log for suspicious activity
  4. Restore from backup: If data is corrupted, restore from a known-good backup
  5. Update dependencies: Run composer update to patch vulnerabilities

Investigation

# Check for backdoors
find /var/www/freescout -name "*.php" -type f -exec grep -l "eval\|system\|shell_exec" {} \;

# Check file timestamps for recently modified files
find /var/www/freescout -type f -mtime -7 -ls

# Check for unauthorized SSH keys
cat /home/freescout/.ssh/authorized_keys

Security Tools

Lynis (Security Audit)

sudo apt install -y lynis
sudo lynis audit system

Generates a report of security issues.

Rkhunter (Rootkit Detection)

sudo apt install -y rkhunter
sudo rkhunter --check --skip-warnings

Detects rootkits and malware.

ClamAV (Antivirus)

sudo apt install -y clamav clamav-daemon
sudo freshclam
sudo clamscan -r /var/www/freescout

Security Checklist (Print & Save)

  • [ ] Firewall enabled (ufw)
  • [ ] Fail2Ban installed and running
  • [ ] SSH key-based auth only (no passwords)
  • [ ] Root SSH login disabled
  • [ ] PHP hardened (expose_php off, dangerous functions disabled)
  • [ ] NGINX security headers enabled
  • [ ] HTTPS/SSL configured (Let's Encrypt)
  • [ ] APP_DEBUG=false in production
  • [ ] Database user restricted to localhost
  • [ ] Automated daily backups running
  • [ ] Backups uploaded to external storage
  • [ ] File permissions set correctly (755 dirs, 644 files)
  • [ ] Log monitoring in place
  • [ ] Monthly security audit scheduled
  • [ ] GDPR compliance verified

Want expert security hardening and compliance review for FreeScout?

We handle the full FreeScout installation on your server — SSL, email, security hardening, and a 1-hour onboarding call. Done in 24 hours.

One-time fee · 30-day support · Money-back guarantee


What Not to Do

  • ❌ Don't disable the firewall
  • ❌ Don't set APP_DEBUG=true in production
  • ❌ Don't reuse passwords across services
  • ❌ Don't skip backup testing (verify backups actually work)
  • ❌ Don't ignore security updates
  • ❌ Don't use weak database passwords
  • ❌ Don't expose error messages to users

Next Steps

  1. Implement layers 1 & 2: Firewall, fail2ban, PHP hardening (today)
  2. Set up backups: Automated daily backups to cloud (this week)
  3. Enable monitoring: Log monitoring, security alerts (this week)
  4. Monthly audits: Run Lynis, review logs, check for updates (every month)
  5. Incident response plan: Document what to do if breached (now)

A hardened FreeScout is a reliable, secure helpdesk that keeps customer data safe.

Resources

Need FreeScout Installed Professionally?

Skip the complexity. We install and configure FreeScout on your server in 24 hours — SSL, email, security, and a full onboarding call included.

Get It Done for $100

One-time fee · 30-day support · Money-back guarantee

Related Articles