Setting Up an Nginx FastDL Host for CS 1.6

July 2, 2025 Daemon666 8 min read 235 visualizações

Without a FastDL host, every client that lacks your custom maps downloads them over the ancient in-game UDP channel at a few KB/s — a 20 MB map empties the server on rotation. FastDL points clients at a normal web server instead. Nginx is the ideal front end for it: fast, tiny, and trivial to configure for static files. This sets one up correctly, including the path structure that trips everyone up.

1. Install Nginx

apt update
apt install -y nginx

Confirm it serves by opening the server IP in a browser; you should get the Nginx welcome page.

2. Create a web root that mirrors cstrike

The single most important rule of FastDL: the engine appends the game-relative path including the cstrike/ folder. A client that needs maps/de_rats.bsp requests <downloadurl>/cstrike/maps/de_rats.bsp. So your web root must contain a cstrike/ directory that mirrors the server's:

mkdir -p /var/www/fastdl/cstrike/{maps,models,sound,sprites,gfx}

Copy only the downloadable content there — custom maps/*.bsp, their .res files, custom models/, sound/ and sprites/. Never copy config files, logs, or your .cfg secrets into a public web root.

3. Pre-compress with bzip2

The engine can fetch .bz2 versions of files, which cut transfer size dramatically. Compress every asset and keep the .bz2 alongside the original:

cd /var/www/fastdl/cstrike
find maps models sound sprites -type f ! -name "*.bz2" -exec bzip2 -kf {} \;

The -k flag keeps the source file. Clients request de_rats.bsp.bz2, download it, and decompress locally. Full detail is in FastDL bzip2 compression.

4. Write the Nginx server block

Create /etc/nginx/sites-available/fastdl:

server {
    listen 80;
    server_name dl.example.com;
    root /var/www/fastdl;

    location / {
        autoindex off;
        # serve .bz2 and .bsp as raw binary
        types { }
        default_type application/octet-stream;
        add_header Cache-Control "public, max-age=604800";
    }

    # never expose config or list directories
    location ~* \.(cfg|ini|log|res)$ {
        deny all;
    }
}

Setting default_type application/octet-stream matters: if Nginx returns a .bz2 with a wrong or text MIME type, some clients mishandle it. Enable the site and reload:

ln -s /etc/nginx/sites-available/fastdl /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

5. Point the server at the mirror

In server.cfg, set the download cvars. The URL points at the web root above the cstrike/ folder, because the engine adds cstrike/ itself:

sv_allowdownload 1
sv_downloadurl "http://dl.example.com"

The interaction between these cvars is explained in sv_allowdownload settings. Change the map after editing so the new value takes effect.

6. Keep the mirror in sync

Every time you add a map or model to the server, copy it to the mirror and re-run the bzip2 command, or clients 404 on the new content. Many admins automate this with a nightly rsync from the game's cstrike/maps into the web root followed by the compress step. For a global audience, front the host with a CDN as in FastDL behind Cloudflare.

7. Why HTTP beats the in-game transfer

It is worth understanding what you are actually fixing. The GoldSrc engine has its own file-transfer protocol layered over the game's UDP connection, and it is throttled hard — historically a handful of KB per second per client — because it was never meant to move megabyte-scale custom content. When ten players connect to a map they lack, the server spends its bandwidth dribbling files to them instead of running the game, and the round stalls. Moving those transfers to Nginx offloads them entirely: the game socket carries only gameplay, while a real web server — built to serve thousands of static files at once — handles the downloads at full line speed. That separation is the whole point of FastDL, and it is why a busy custom-content server is essentially unrunnable without it.

8. Serve it on the right host

The FastDL host does not have to be the game box, and often should not be. A separate small web server, or a static bucket behind a CDN, keeps download traffic off the machine running HLDS so a rush of connecting players never competes with the tick loop for CPU or bandwidth. If you do co-host, at least bind Nginx to a sensible worker count and let the OS cache the hot files; the assets are immutable, so aggressive caching is safe and the Cache-Control header above tells intermediaries so.

Troubleshooting

  • Every file 404s — the cstrike/ level is missing or doubled in the web root. Open the exact URL a client requests, e.g. http://dl.example.com/cstrike/maps/de_dust2.bsp, in a browser. See FastDL not working.
  • The .bz2 404s but the raw file works — you did not compress that file, or only kept the .bz2 for some. See the 404 on .bz2 fix.
  • Downloads still crawlsv_downloadurl is empty or unreachable, so the server fell back to the UDP channel. Test the URL in a browser from another network.
  • Config files exposed — you copied .cfg into the web root and omitted the deny block. Remove them and keep the deny rule.

Verification

Delete a custom map from a test client, connect to the server, and watch the download bar — it should complete in seconds over HTTP rather than crawling. Cross-check the Nginx access log: you should see 200 responses for /cstrike/maps/<map>.bsp.bz2. A 404 there is a sync or path problem; a slow in-game transfer means the client never reached the mirror at all. The complete conceptual model is in the FastDL setup guide.

Colaboradores: Daemon666 ✦
Compartilhar: