iTranslated by AI
#1 [Caching] Does Forward Proxy Cache Cause Outdated CSS? (Chrome, Squid, Nginx)
Background
Recently, I heard that "even though a website has been updated, an old screen may be displayed due to the forward proxy's cache." While I thought that such a thing might be possible, I also wondered, "Is it really true? Could it be that just the browser cache was being displayed?" So, the theme of this project is to actually verify this.
Configuration
I will prepare the following four machines. Note that the servers and the proxy will be built on Rocky Linux 8.8 deployed on Proxmox.
-
Web Origin Server : 192.168.12.55
Stores HTML and CSS content. (Nginx 1.14.1) -
Web Cache Server : 192.168.12.56
Caches content from the origin server and accepts access from clients. The content expiration is set to 1 minute, and it is basically configured to fetch the latest content. (Nginx 1.14.1) -
Forward Proxy : 192.168.12.57
Relays HTTP access from clients and holds once-downloaded (accessed) content in the cache for 60 minutes. (Squid 4.15) -
Client PC : 192.168.12.X (DHCP)
Performs HTTP access. The browser used is Chrome Ver. 134.

Setup
I will build the environment according to the requirements.
1. Web Origin Server
- Installation & Folder Creation
dnf install nginx -y
mkdir -p /var/www/html
chown -R nginx:nginx /var/www/html
chmod -R 755 /var/www/html
- Creating HTML & CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Test</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>CSS Test</h1>
<p>After modifying the CSS, this part should be displayed in red.</p>
</body>
</html>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
text-align: center;
padding: 50px;
}
h1 {
color: black;
}
p {
font-weight: bold;
font-size: 1.2em;
color: black; /* Black */
}
- Editing the Configuration File
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# root /usr/share/nginx/html;
root /var/www/html;
index index.html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
- Firewall and Startup
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
firewall-cmd --list-all
systemctl enable --now nginx
systemctl status nginx
- SELinux Countermeasures
If left as is, accessing it will result in a 403 error, so we will rebuild the SELinux policy.
# From confirmation to creation and application of the new policy
cat /var/log/audit/audit.log | grep denied | tail -5
cat /var/log/audit/audit.log | grep denied | audit2allow
cat /var/log/audit/audit.log | grep denied | audit2allow -M nginxpolicy_20250323_01
semodule -i nginxpolicy_20250323_01.pp
# Re-confirm. If HTTP access is still blocked after applying the new policy, recreate the policy several times.
# In this case, it was completed in two attempts. The final allowed policy is as follows.
cat /var/log/audit/audit.log | grep denied | audit2allow
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t var_t:file { getattr open read };
Access h++p://192.168.12.55/, and if the content of index.html is displayed, you're all set.
Web Cache Server
- Installation & Folder Creation
dnf install nginx -y
mkdir -p /var/cache/nginx
chown -R nginx:nginx /var/cache/nginx
chmod -R 755 /var/cache/nginx
- Editing the Configuration File
Theproxy_set_headersettings are a bit of a mystery.add_headerseemed to be reflected correctly.
Well, I'm not entirely sure, but I'll ignore it for now as it's not the main point.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:10m max_size=1g inactive=60m use_temp_path=off;
server {
listen 80;
server_name 192.168.12.56; # Frontend domain or IP
location / {
proxy_pass http://192.168.12.55; # Backend web server
proxy_set_header Host $host; # Host requested by the client
proxy_set_header X-Real-IP $remote_addr; # Client's real IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Add XFF header
proxy_cache cache_zone;
proxy_cache_valid any 1m; # Cache expiration is 1 minute (keeping the front end up to date)
# proxy_cache_bypass $http_cache_control; # Bypass the cache if the client sends a Cache-Control header
add_header X-Cache-Status $upstream_cache_status; # Add cache status (HIT, MISS, BYPASS, etc.) to the response header
}
}
- Firewall and Startup
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
firewall-cmd --list-all
systemctl enable --now nginx
systemctl status nginx
- SELinux Countermeasures
The process is the same as for the origin server.
# From confirmation to creation and application of the new policy
cat /var/log/audit/audit.log | grep denied | tail -5
cat /var/log/audit/audit.log | grep denied | audit2allow
cat /var/log/audit/audit.log | grep denied | audit2allow -M nginxpolicy_20250323_01
semodule -i nginxpolicy_20250323_01.pp
# Re-confirm. If HTTP access is still blocked after applying the new policy, recreate the policy several times.
# In this case, it was completed in one attempt. The final allowed policy is as follows.
cat /var/log/audit/audit.log | grep denied | audit2allow
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t http_port_t:tcp_socket name_connect;
Access h++p://192.168.12.56/, and if the index.html from the Web Origin Server is displayed, you're all set.
Forward Proxy
- Installation
dnf install squid -y
- Editing the Configuration File
# Safe ports
acl Safe_ports port 80 # http
acl Safe_ports port 8080 # http
http_access deny !Safe_ports
# Network ACL
acl localnet src 192.168.12.0/24
http_access allow localnet
http_access allow localhost
http_access deny all
# Squid's listening port
http_port 8080
# Cache settings
cache_dir ufs /var/spool/squid 1000 16 256 # Cache directory (1000MB)
# Cache expiration (60 minutes)
refresh_pattern . 60 100% 60
- Creating the Cache Directory
ll /var/spool/squid/
squid -z
ll /var/spool/squid/
- Firewall and Startup
firewall-cmd --add-port=8080/tcp --zone=public --permanent
firewall-cmd --reload
firewall-cmd --list-all
systemctl enable --now squid
systemctl status squid
Connection
Configure the proxy settings on the client PC side and confirm that you can access h++p://192.168.12.56/.

If the access is successful, it will be displayed as follows.
Since the Remote Address is the proxy's IP:8080, it seems to be correctly accessing via the forward proxy.

I didn't pay much attention when building the forward proxy, but X-Cache and X-Cache-Lookup are added to the response headers. Since I want to know "whether the proxy responded from the cache," I probably only need to look at X-Cache.
Since this is the first access, it's naturally a MISS. HIT would mean a cache response.

That's it for this time.
Next time, I will actually check the behavior of the proxy and browser cache.
Discussion