콘텐츠로 이동

보안 구성

일반적인 웹 취약성으로부터 XOOPS 설치를 보호하기 위한 종합 가이드입니다.

사이트를 시작하기 전에 다음 보안 조치를 구현하세요.

  • 파일 권한이 올바르게 설정됨(644/755)
  • 설치 폴더가 제거되거나 보호됨
  • 수정으로부터 보호되는 mainfile.php
  • 모든 페이지에서 SSL/HTTPS가 활성화되었습니다.
  • 관리 폴더 이름이 바뀌거나 보호됨
  • 웹에서 액세스할 수 없는 민감한 파일
  • [ ].htaccess 제한이 적용됨
  • 정기 백업 자동화
  • 보안 헤더가 구성됨
  • CSRF 보호 활성화됨
  • SQL 주입 보호가 활성화되었습니다.
  • 모듈/확장 업데이트됨

보안을 위해서는 적절한 파일 권한이 중요합니다.

경로권한소유자이유
메인파일.php644루트DB 자격 증명 포함
*.php 파일644루트무단수정 방지
디렉토리755루트읽기 허용, 쓰기 금지
캐시/777www-데이터웹 서버는
template_c/777www-데이터컴파일된 템플릿
업로드/777www-데이터사용자 업로드
var/777www-데이터가변 데이터
설치/제거-설치 후 삭제
구성/755루트읽기 가능, 쓰기 불가능
/usr/local/bin/xoops-secure.sh
#!/bin/bash
XOOPS_PATH="/var/www/html/xoops"
WEB_USER="www-data"
# Set ownership
echo "Setting ownership..."
chown -R $WEB_USER:$WEB_USER $XOOPS_PATH
# Set restrictive default permissions
echo "Setting base permissions..."
find $XOOPS_PATH -type d -exec chmod 755 {} \;
find $XOOPS_PATH -type f -exec chmod 644 {} \;
# Make specific directories writable
echo "Setting writable directories..."
chmod 777 $XOOPS_PATH/cache
chmod 777 $XOOPS_PATH/templates_c
chmod 777 $XOOPS_PATH/uploads
chmod 777 $XOOPS_PATH/var
# Protect sensitive files
echo "Protecting sensitive files..."
chmod 644 $XOOPS_PATH/mainfile.php
chmod 444 $XOOPS_PATH/mainfile.php.dist # If it exists (read-only)
# Verify permissions
echo "Verifying permissions..."
ls -la $XOOPS_PATH | grep -E "mainfile|cache|uploads|var|templates_c"
echo "Security hardening completed!"

스크립트를 실행합니다:

Terminal window
chmod +x /usr/local/bin/xoops-secure.sh
/usr/local/bin/xoops-secure.sh

중요: 설치 후 설치 폴더를 제거해야 합니다!

Terminal window
# Option 1: Delete completely
rm -rf /var/www/html/xoops/install/
# Option 2: Rename and keep for reference
mv /var/www/html/xoops/install/ /var/www/html/xoops/install.bak/
# Verify removal
ls -la /var/www/html/xoops/ | grep install

민감한 폴더에 대한 웹 액세스를 차단하려면.htaccess 파일을 만드세요.

파일: /var/www/html/xoops/var/.htaccess

<FilesMatch "\.(php|phtml|php3|php4|php5|php6|php7|phps|pht|phar)$">
Deny from all
</FilesMatch>
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>

파일: /var/www/html/xoops/templates_c/.htaccess

<FilesMatch "\.(php|phtml|php3|php4|php5|php6|php7|phps|pht|phar)$">
Deny from all
</FilesMatch>
Options -Indexes

파일: /var/www/html/xoops/cache/.htaccess

Options -Indexes
<FilesMatch "\.(php|phtml|php3|php4|php5|php6|php7)$">
Deny from all
</FilesMatch>

업로드 시 스크립트 실행을 방지합니다.

파일: /var/www/html/xoops/uploads/.htaccess

# Prevent script execution
<FilesMatch "\.(php|phtml|php3|php4|php5|php6|php7|phps|pht|phar|pl|py|jsp|asp|aspx|cgi|sh|bat|exe)$">
Deny from all
</FilesMatch>
# Prevent directory listing
Options -Indexes
# Additional protection
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /xoops/uploads/
# Block suspicious files
RewriteCond %{REQUEST_URI} \.(php|phtml|php3|php4|php5|php6|php7)$ [NC]
RewriteRule ^.*$ - [F,L]
</IfModule>

사용자와 서버 사이의 모든 트래픽을 암호화합니다.

옵션 1: Let’s Encrypt의 무료 인증서

Terminal window
# Install Certbot
apt-get install certbot python3-certbot-apache
# Obtain certificate (auto-configures Apache)
certbot certonly --apache -d your-domain.com -d www.your-domain.com
# Verify certificate installed
ls /etc/letsencrypt/live/your-domain.com/

옵션 2: 상업용 SSL 인증서

SSL 제공업체 또는 등록기관에 문의하세요.

  1. SSL 인증서 구매
  2. 도메인 소유권 확인
  3. 서버에 인증서 파일 설치
  4. 웹 서버 구성

HTTPS 가상 호스트를 생성합니다:

파일: /etc/apache2/sites-available/xoops-ssl.conf

<VirtualHost *:443>
ServerName your-domain.com
ServerAlias www.your-domain.com
DocumentRoot /var/www/html/xoops
# SSL Configuration
SSLEngine on
SSLProtocol TLSv1.2 TLSv1.3
SSLCipherSuite HIGH:!aNULL:!MD5
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/your-domain.com/chain.pem
# Security Headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
<Directory /var/www/html/xoops>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Restrict install folder
<Directory /var/www/html/xoops/install>
Deny from all
</Directory>
# Logging
ErrorLog ${APACHE_LOG_DIR}/xoops_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/xoops_ssl_access.log combined
</VirtualHost>
# Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName your-domain.com
ServerAlias www.your-domain.com
Redirect 301 / https://your-domain.com/
</VirtualHost>

구성을 활성화합니다.

Terminal window
# Enable SSL module
a2enmod ssl
# Enable site
a2ensite xoops-ssl
# Disable non-SSL site if exists
a2dissite 000-default
# Test configuration
apache2ctl configtest
# Should output: Syntax OK
# Restart Apache
systemctl restart apache2

파일: /etc/nginx/sites-available/xoops

# HTTP to HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your-domain.com www.your-domain.com;
root /var/www/html/xoops;
index index.php index.html;
# SSL Certificate Configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Modern SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS Header
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Security Headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'" always;
# Restrict install folder
location ~ ^/(install|upgrade)/ {
deny all;
}
# Deny access to sensitive files
location ~ /\. {
deny all;
}
# PHP-FPM backend
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Static files caching
location ~* \.(js|css|png|jpg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# URL rewriting
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Logging
access_log /var/log/nginx/xoops_access.log;
error_log /var/log/nginx/xoops_error.log;
}

구성을 활성화합니다.

Terminal window
ln -s /etc/nginx/sites-available/xoops /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
Terminal window
# Test SSL configuration
openssl s_client -connect your-domain.com:443 -tls1_2
# Check certificate validity
openssl x509 -in /etc/letsencrypt/live/your-domain.com/cert.pem -noout -text
# SSL/TLS test online
# https://www.ssllabs.com/ssltest/
# https://www.testssl.sh/
Terminal window
# Enable auto-renewal
systemctl enable certbot.timer
systemctl start certbot.timer
# Test renewal process
certbot renew --dry-run
# Manual renewal if needed
certbot renew --force-renewal

XOOPS는 매개변수화된 쿼리(기본적으로 안전함)를 사용하지만 항상 다음을 수행합니다.

// UNSAFE - Never do this!
$query = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'";
// SAFE - Use prepared statements
$database = XoopsDatabaseFactory::getDatabaseConnection();
$sql = "SELECT * FROM " . $database->prefix('users') . " WHERE name = ?";
$result = $database->query($sql, array($_GET['name']));

항상 사용자 입력을 삭제합니다.

// UNSAFE
echo $_GET['user_input'];
// SAFE - Use XOOPS sanitization functions
echo htmlspecialchars($_GET['user_input'], ENT_QUOTES, 'UTF-8');
// Or use XOOPS functions
$text_sanitizer = new xoops_text_sanitizer();
echo $text_sanitizer->stripSlashesGPC($_GET['user_input']);

XOOPS에는 CSRF 토큰 보호가 포함되어 있습니다. 항상 토큰을 포함하십시오:

<!-- In forms -->
<form method="post">
{xoops_token form=update}
<input type="text" name="field">
<input type="submit">
</form>

업로드 폴더에서 PHP 실행 비활성화

섹션 제목: “업로드 폴더에서 PHP 실행 비활성화”

공격자가 PHP를 업로드하고 실행하지 못하도록 방지합니다.

Terminal window
# Create .htaccess in uploads folder
cat > /var/www/html/xoops/uploads/.htaccess << 'EOF'
<FilesMatch "\.(php|phtml|php3|php4|php5|php6|php7)$">
Deny from all
</FilesMatch>
php_flag engine off
EOF
# Alternative: Disable execution globally in uploads
chmod 444 /var/www/html/xoops/uploads/ # Read-only

중요한 HTTP 보안 헤더를 구성합니다.

# Strict-Transport-Security (HSTS)
# Forces HTTPS for 1 year
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# X-Content-Type-Options
# Prevents MIME type sniffing
Header always set X-Content-Type-Options "nosniff"
# X-Frame-Options
# Prevents clickjacking attacks
Header always set X-Frame-Options "SAMEORIGIN"
# X-XSS-Protection
# Browser XSS protection
Header always set X-XSS-Protection "1; mode=block"
# Referrer-Policy
# Controls referrer information
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Content-Security-Policy
# Controls resource loading
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'"

이름을 변경하여 관리 폴더를 보호하세요.

Terminal window
# Rename admin folder
mv /var/www/html/xoops/admin /var/www/html/xoops/myadmin123
# Update admin access URL
# Old: http://your-domain.com/xoops/admin/
# New: http://your-domain.com/xoops/myadmin123/

이름이 바뀐 폴더를 사용하도록 XOOPS를 구성합니다.

mainfile.php를 편집합니다:

// Change this line
define('XOOPS_ADMIN_PATH', '/var/www/html/xoops/myadmin123');

특정 IP에 대한 관리자 액세스를 제한합니다.

파일: /var/www/html/xoops/myadmin123/.htaccess

# Allow only specific IPs
<RequireAll>
Require ip 192.168.1.100 # Your office IP
Require ip 203.0.113.50 # Your home IP
Deny from all
</RequireAll>

또는 Apache 2.2의 경우:

Order Deny,Allow
Deny from all
Allow from 192.168.1.100 203.0.113.50

관리자에게 강력한 비밀번호를 적용하십시오.

  1. 최소 16자 이상을 사용하세요
  2. 대문자, 소문자, 숫자, 기호를 혼합하세요
  3. 정기적으로(90일마다) 비밀번호를 변경하세요.
  4. 비밀번호 관리자를 사용하세요
  5. 가능한 경우 이중 인증을 활성화합니다.

관리자 로그인 로깅 활성화:

관리자 패널 > 시스템 > 기본 설정 > 사용자 설정

Log Admin Logins: Yes
Log Failed Login Attempts: Yes
Alert Email on Admin Login: Yes

로그를 정기적으로 검토하세요.

Terminal window
# Check database for login attempts
mysql -u xoops_user -p xoops_db << EOF
SELECT uid, uname, DATE_FROM_UNIXTIME(user_lastlogin) as last_login
FROM xoops_users WHERE uid = 1;
EOF

XOOPS 및 모든 모듈을 최신 상태로 유지하십시오.

Terminal window
# Check for updates in admin panel
# Admin > Modules > Check for Updates
# Or via command line
cd /var/www/html/xoops
# Download and install latest version
# Follow upgrade guide
#!/bin/bash
# Security audit script
# Check file permissions
echo "Checking file permissions..."
find /var/www/html/xoops -type f ! -perm 644 ! -name "*.htaccess" | head -10
# Check for suspicious files
echo "Checking for suspicious files..."
find /var/www/html/xoops -type f -name "*.php" -newer /var/www/html/xoops/install/ 2>/dev/null
# Check database for suspicious activity
echo "Checking for failed login attempts..."
mysql -u xoops_user -p xoops_db << EOF
SELECT count(*) as attempts FROM xoops_audittrail WHERE action LIKE '%login%' AND status = 0;
EOF

일일 백업 자동화:

#!/bin/bash
# Daily backup script
BACKUP_DIR="/backups/xoops"
RETENTION=30 # Keep 30 days
# Backup database
mysqldump -u xoops_user -p xoops_db | gzip > $BACKUP_DIR/db_$(date +%Y%m%d).sql.gz
# Backup files
tar -czf $BACKUP_DIR/files_$(date +%Y%m%d).tar.gz /var/www/html/xoops --exclude=cache --exclude=templates_c
# Remove old backups
find $BACKUP_DIR -type f -mtime +$RETENTION -delete
echo "Backup completed at $(date)"

cron으로 예약:

Terminal window
# Edit crontab
crontab -e
# Add line (runs daily at 2 AM)
0 2 * * * /usr/local/bin/xoops-backup.sh >> /var/log/xoops_backup.log 2>&1

정기적인 보안 감사에 이 템플릿을 사용하십시오.

Weekly Security Checklist
========================
Date: ___________
Checked by: ___________
File System:
[ ] Permissions correct (644/755)
[ ] Install folder removed
[ ] No suspicious files
[ ] mainfile.php protected
Web Security:
[ ] HTTPS/SSL working
[ ] Security headers present
[ ] Admin panel restricted
[ ] File upload restrictions active
[ ] Login attempts logged
Application:
[ ] XOOPS version current
[ ] All modules updated
[ ] No error messages in logs
[ ] Database optimized
[ ] Cache cleared
Backups:
[ ] Database backed up
[ ] Files backed up
[ ] Backup tested
[ ] Offsite copy verified
Issues Found:
1. ___________
2. ___________
3. ___________
Actions Taken:
1. ___________
2. ___________

태그: #보안 #ssl #https #강화 #모범 사례

관련 기사: -../설치/설치 -../../06-Publisher-Module/User-Guide/Basic-Configuration

  • 시스템 설정 -../설치/업그레이드-XOOPS