ดังนั้น ฉันมีเว็บไซต์ wordpress ที่ทำงานอยู่เบื้องหลัง nginx -> varnish -> httpd
กฎ htaccess สำหรับ wp-login.php ถูกตั้งค่าเป็น:
<Files wp-login.php>
allow from client ip
deny from all
</Files>
สิ่งนี้เคยทำงานได้ดีโดยไม่ต้องใช้วานิช แต่เมื่อฉันใส่วานิชตรงกลางระหว่าง nginx และ httpd ปัญหาการแคชหรือการส่งต่อ IP นี้เริ่มเกิดขึ้น
เนื่องจากฉันสามารถเปลี่ยนการกำหนดค่าเว็บเซิร์ฟเวอร์ได้อย่างง่ายดาย ฉันจึงสามารถปิด/เปิดใช้งานการเคลือบเงาสำหรับไซต์ได้อย่างง่ายดาย ในการทดสอบ ฉันเปลี่ยนกฎ htaccess เป็น:
<Files wp-login.php>
allow from Server Public IP
deny from all
</Files>
สิ่งนี้ทำให้ทุกคนสามารถเข้าถึง wp-login ได้ จากนั้นฉันปิดใช้งานการเคลือบเงาและเก็บ IP สาธารณะของเซิร์ฟเวอร์ไว้ใน htaccess และตอนนี้ไม่มีใครสามารถเข้าถึงหน้านี้ได้ (ซึ่งเป็นสิ่งที่ควรจะเกิดขึ้น)
ดังนั้นผู้ร้ายคือสารเคลือบเงา
ฉันมีการตั้งค่า mod_cloudflare บน apache ฉันได้ทดสอบด้วยการเปลี่ยนเป็น mod_remoteip เป็นไม่มีประโยชน์
นี่คือเทมเพลต nginx:443, varnish:82 และ apache:8181 vhost ของฉัน (IP 108.148.54.124 นี้เป็นตัวอย่างสำหรับ IP สาธารณะของเซิร์ฟเวอร์):
เซิร์ฟเวอร์ {
ฟัง 108.148.54.124:443 ssl http2;
ชื่อเซิร์ฟเวอร์ %domain_idn% %alias_idn%;
access_log /usr/local/apache/domlogs/%domain%.bytes ไบต์;
access_log /usr/local/apache/domlogs/%domain%.log เต็ม;
error_log /usr/local/apache/domlogs/%domain%.error.log ข้อผิดพลาด;
ssl_certificate %ssl_cert_path%/%domain%.bundle;
ssl_certificate_key %ssl_key_path%/%domain%.key;
ssl_protocols TLSv1.3;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA!RC4:EECDH:!RC4:!aNULL :!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
เปิด ssl_prefer_server_ciphers;
ssl_session_cache ที่ใช้ร่วมกัน: SSL:10m;
ssl_session_timeout 60m;
ที่ตั้ง / {
ตำแหน่ง ~.*\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt |js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso|woff|ttf|svg|eot|sh|webp)$ {
ราก %docroot%;
หมดอายุสูงสุด
try_files $uri $uri/ @แบ็คเอนด์;
}
error_page 405 = @แบ็กเอนด์;
error_page 500 = @กำหนดเอง;
add_header X-Cache "HIT จากแบ็กเอนด์";
add_header การขนส่งที่เข้มงวด - ความปลอดภัย "อายุสูงสุด = 31536000";
add_header X-XSS-Protection "1; mode=block" เสมอ;
add_header X-Content-Type-Options "nosniff" เสมอ;
proxy_pass %proxy_protocol%://108.148.54.124:82;
รวม proxy.inc;
}
ตำแหน่ง @แบ็กเอนด์ {
ภายใน;
proxy_pass %proxy_protocol%://108.148.54.124:82;
รวม proxy.inc;
}
ตำแหน่ง @กำหนดเอง {
ภายใน;
proxy_pass %proxy_protocol%://108.148.54.124:82;
รวม proxy.inc;
}
ตำแหน่ง ~ .*\.(php|jsp|cgi|pl|py)?$ {
proxy_pass %proxy_protocol%://108.148.54.124:82;
รวม proxy.inc;
}
ตำแหน่ง ~ /\.ht {ปฏิเสธทั้งหมด;}
ตำแหน่ง ~ /\.svn/ {ปฏิเสธทั้งหมด;}
ตำแหน่ง ~ /\.git/ {ปฏิเสธทั้งหมด;}
ตำแหน่ง ~ /\.hg/ {ปฏิเสธทั้งหมด;}
ตำแหน่ง ~ /\.bzr/ {ปฏิเสธทั้งหมด;}
ตำแหน่ง ~\.(ini|log|conf)$ {deny all;error_page 403 =404 / ;}
enable_symlinks if_not_owner จาก=%docroot%;
ที่ตั้ง /.well-known/acme-challenge {
default_type "ข้อความ/ธรรมดา";
นามแฝง /usr/local/apache/autossl_tmp/.well-known/acme-challenge;
}
สถานที่ /.well-known/pki-ตรวจสอบ {
default_type "ข้อความ/ธรรมดา";
นามแฝง /usr/local/apache/autossl_tmp/.well-known/acme-challenge;
}
}
.....
แบ็กเอนด์ %backend_domain% {
.host = "108.148.54.124";
.port = "8181";
}
ย่อย vcl_recv {
ถ้า (req.http.host ~ "%โดเมน%") {
ตั้ง req.backend_hint = %backend_domain%;
# แคชประเภทไฟล์ต่อไปนี้สำหรับผู้ใช้ทั้งหมดเสมอ
ถ้า (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$") {
ยกเลิกการตั้งค่า req.http.Cookie;
}
# ลบคุกกี้ที่ใช้ Google Analytics
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
# อย่าแคชคำขอ AJAX
ถ้า (req.http.X-Requested-With == "XMLHttpRequest") {
กลับ (ผ่าน);
}
# คำขอโพสต์จะไม่ถูกแคช
ถ้า (req.http.Authorization || req.method == "POST") {
กลับ (ผ่าน);
}
ถ้า (req.method != "GET" && req.method != "HEAD") {
กลับ (ผ่าน);
}
# อย่าแคชคำขอที่ได้รับอนุญาต
ถ้า (req.http.Authorization) {
กลับ (ผ่าน);
}
# LetsEncrypt Certbot ส่งผ่าน
ถ้า (req.url ~ "^/\.well-known/acme-challenge/") {
กลับ (ผ่าน);
}
ถ้า (req.url ~ "^/\.well-known/pki-validation/") {
กลับ (ผ่าน);
}
# ส่งต่อ IP ของลูกค้าไปยังแบ็กเอนด์
ถ้า (req.restarts == 0) {
ถ้า (req.http.X-Real-IP) {
ตั้ง req.http.X-Forwarded-For = req.http.X-Real-IP;
} อื่นถ้า (req.http.X-Forwarded-For) {
ตั้ง req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
} อื่น {
ตั้ง req.http.X-Forwarded-For = client.ip;
}
}
### เวิร์ดเพรส ###
ถ้า (req.url ~ "(wp-admin|post\.php|edit\.php|wp-login)") {
กลับ (ผ่าน);
}
ถ้า (req.url ~ "/wp-cron.php" || req.url ~ "preview=true") {
กลับ (ผ่าน);
}
# WP-Affiliate
ถ้า ( req.url ~ "\?ref=" ) {
กลับ (ผ่าน);
}
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
ตั้ง req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", "");
กลับ (แฮช);
}
}
<VirtualHost 108.148.54.124:8443>
ServerName %domain_idn%
%domain_aliases%
ServerAdmin webmaster@%domain%
DocumentRoot %docroot%
UseCanonicalName Off
ScriptAlias /cgi-bin/ %docroot%/cgi-bin/
CustomLog /usr/local/apache/domlogs/%domain%.bytes bytes
CustomLog /usr/local/apache/domlogs/%domain%.log combined
ErrorLog /usr/local/apache/domlogs/%domain%.error.log
## Custom settings are loaded below this line (if any exist)
# IncludeOptional "/usr/local/apache/conf/userdata/%user%/%domain%/*.conf"
SSLEngine on
SSLCertificateFile %ssl_cert_path%/%domain%.cert
SSLCertificateKeyFile %ssl_key_path%/%domain%.key
SSLCertificateChainFile %ssl_cert_path%/%domain%.bundle
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
<IfModule mod_userdir.c>
UserDir disabled
UserDir enabled %user%
</IfModule>
<IfModule mod_suexec.c>
SuexecUserGroup %user% %group%
</IfModule>
<IfModule mod_suphp.c>
suPHP_UserGroup %user% %group%
suPHP_ConfigPath %home%/%user%
</IfModule>
<IfModule mod_ruid2.c>
RMode config
RUidGid %user% %group%
</IfModule>
<IfModule itk.c>
AssignUserID %user% %group%
</IfModule>
<Directory "%docroot%">
AllowOverride All
SSLRequireSSL
Require all granted
</Directory>
<IfModule proxy_fcgi_module>
<FilesMatch \.php$>
SetHandler "proxy:%backend_fcgi%|fcgi://localhost"
</FilesMatch>
</IfModule>
</VirtualHost>
และนี่คือไฟล์ conf nginx หลัก:
ไม่มีใครใช้;
worker_processes อัตโนมัติ
#worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log วิกฤต;
pid /var/run/nginx.pid;
เหตุการณ์ {
worker_connections 1024;
ใช้ epol;
เปิด multi_accept;
}
http {
ส่งไฟล์บน;
tcp_nopush บน;
tcp_nodelay บน;
client_header_timeout 3 นาที;
client_body_timeout 3 นาที;
client_max_body_size 256m;
client_header_buffer_size 4k;
client_body_buffer_size 256k;
large_client_header_buffers 4 32k;
send_timeout 3m;
keepalive_timeout 60 60;
เปิด reset_timedout_connection;
server_names_hash_max_size 1024;
server_names_hash_bucket_size 1024;
forget_invalid_headers บน;
connection_pool_size 256;
request_pool_size 4k;
output_buffers 4 32k;
เลื่อน_output 1460;
รวม mime.types;
แอปพลิเคชัน default_type/octet-stream;
#การบีบอัด gzip
เปิด gzip;
gzip_vary บน;
gzip_disable "MSIE [1-6]\.";
gzip_proxyed ใด ๆ ;
gzip_min_length 512;
gzip_comp_level 6;
gzip_buffers 8 64k;
gzip_types ข้อความ/ข้อความธรรมดา/ข้อความ xml/ข้อความ css/แอปพลิเคชัน js/แอปพลิเคชัน x-javascript/รูปภาพ xml/รูปภาพ png/รูปภาพ x-icon/รูปภาพ gif/รูปภาพ jpeg/แอปพลิเคชัน svg+xml/xml+ข้อความ rss/แอปพลิเคชันจาวาสคริปต์/ แอปพลิเคชัน atom+xml/แอปพลิเคชันจาวาสคริปต์/แอปพลิเคชัน json/แบบอักษร x-font-ttf/opentype;
# การตั้งค่าพร็อกซี
ปิด proxy_redirect;
proxy_set_header โฮสต์ $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-ส่งต่อ-สำหรับ $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffers 32 4k;
proxy_cache_path /var/cache/nginx levels=2 keys_zone=cache:10m inactive=60m max_size=512m;
proxy_cache_key "$host$request_uri $cookie_user";
proxy_temp_path /var/cache/nginx/temp;
proxy_ignore_headers หมดอายุการควบคุมแคช;
ข้อผิดพลาด proxy_cache_use_stale หมดเวลา invalid_header http_502;
proxy_cache_valid 1d;
open_file_cache_valid 120 วินาที;
open_file_cache_min_uses 2;
ปิด open_file_cache_errors;
open_file_cache สูงสุด = 5,000 ไม่ใช้งาน = 30 วินาที;
open_log_file_cache สูงสุด=1024 ไม่ใช้งาน=30s min_uses=2;
# การตั้งค่า SSL
ssl_session_cache ที่ใช้ร่วมกัน: SSL:10m;
ssl_protocols TLSv1.3;
เปิด ssl_prefer_server_ciphers;
ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA!RC4:EECDH:!RC4:! aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS";
# บันทึก
log_format main '$remote_addr - $remote_user [$time_local] $request'
'"สถานะ $" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format full '[$time_local] $remote_addr $remote_user - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
log_format ไบต์ '$body_bytes_sent';
#access_log /var/log/nginx/access.log หลัก;
access_log off;
# บายพาสแคช
แผนที่ $http_cookie $no_cache {
เริ่มต้น 0;
~ ช่วงที่ 1;
~wordpress_logged_in 1;
}
# รวมการกำหนดค่าเพิ่มเติม
รวม /etc/nginx/cloudflare.inc;
รวม /etc/nginx/conf.d/*.conf;
}