Install the CSF firewall on a Linux server without a control panel
Step by step: install CSF (Core Shield Firewall) 2.3 on a Linux server with no control panel, turn on protection safely, create your web interface login with two-factor authentication, and open the firewall web interface through an SSH tunnel or your own HTTPS reverse proxy.
On this page
CSF (Core Shield Firewall, formerly cPanel Shield Firewall) is UnderHost's free, open-source firewall and intrusion-prevention system, part of UnderShield. Since version 2.2 it also runs on Linux servers that have no control panel: the same nftables firewall, LFD 2.0 brute-force protection and Threat Intelligence feeds, with its own secure web interface instead of WHM. This guide takes you from a fresh server to a working, protected setup.
No-panel support is part of the stable CSF 2.3.2, tested on Debian 12 / 13, Ubuntu 22.04 / 24.04 / 26.04, AlmaLinux 8 / 9 / 10, Rocky Linux 9 and CloudLinux 9. CSF 2.3 can also scan uploaded website files for malware: run csf --scan-setup. Using CloudPanel? Follow Install CSF on CloudPanel instead.
Before you start
- Root access over SSH. Keep that SSH session open during the whole setup.
- A recent Linux: AlmaLinux, Rocky, RHEL or CloudLinux 8/9/10, or Ubuntu 22.04/24.04.
- nftables and Perl. Most servers have both. If the installer says nftables is missing, install it with
dnf install -y nftables(AlmaLinux and Rocky) orapt-get install -y nftables(Ubuntu). - The SSH port you use. The installer reads it from your SSH configuration, so a custom port is kept open.
1. Download and install
Run these commands as root. The checksum step makes sure the file was not changed on the way.
cd /root
curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz
curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz.sha256
sha256sum -c csf-2.3.2.tar.gz.sha256
tar xzf csf-2.3.2.tar.gz
cd csf2 && sh install.sh
sha256sum must answer OK. The installer then detects that the server has no control panel and:
- opens TCP 22 (or your SSH port), 80 and 443, and nothing else;
- installs the firewall in TESTING mode: the rules are built and checked but not enforced yet, so a mistake cannot lock you out;
- installs the web interface service
csf2-ui, which listens on127.0.0.1:6789only.
If you run another firewall (ufw or firewalld), the installer may warn you. Leave it running for now; you will turn it off in step 3.
2. Check the ports
csf --platform
grep -E '^(TCP_IN|UDP_IN|MGMT_PORTS) ' /etc/csf/csf.conf
The platform should show Linux (no control panel). If the server runs other services that must be reachable from the internet, such as a mail server, a game server or a database used by another server, add their ports to TCP_IN (or UDP_IN) in /etc/csf/csf.conf now, separated by commas. For example:
TCP_IN = "22,80,443,25,587,993"
Do not add 6789: the web interface is reached through a tunnel or a reverse proxy, never directly.
3. Turn protection on safely
Edit /etc/csf/csf.conf and change TESTING = "1" to TESTING = "0". Then apply the rules with the safety net:
csf --safe-reload
Now open a second SSH session to the server. If it connects, confirm in either session:
csf --confirm
systemctl enable --now csf.service lfd.service
The second line starts LFD (brute-force detection) and makes everything start again after a reboot. Check that the server is really protected:
csf -l
csf --selftest
If you cannot open the second session, do nothing: --safe-reload puts the previous rules back after 30 seconds unless you run csf --confirm. Then check your ports and try again.
Once CSF is enforcing, turn off the old firewall so the two do not fight: ufw disable on Ubuntu, or systemctl disable --now firewalld on AlmaLinux and Rocky.
4. Create your web interface login
Nobody can sign in to the web interface until you create an account. Pick any user name:
csf --ui-user add admin
- Type a password of at least 12 characters, then repeat it.
- CSF prints a Secret and a URI (starting with
otpauth://). This is your two-factor authentication setup. - Open your authenticator app (Google Authenticator, Microsoft Authenticator, 1Password, Authy…), choose Enter a setup key, and type the Secret. Use time-based, 6 digits.
Prefer to scan a QR code? Install qrencode (apt-get install -y qrencode on Ubuntu, dnf install -y qrencode on AlmaLinux and Rocky, from EPEL if it is not found) and show the URI as a QR code right in your terminal:
qrencode -t ansiutf8 'PASTE-THE-otpauth://-URI-HERE'
Keep the secret private: anyone who has it can generate your login codes. Clear your screen afterwards with clear.
5. Open the web interface
For security, the web interface only listens on the server itself (127.0.0.1:6789) and is never published on the internet directly. You reach it in one of two ways.
Option A: SSH tunnel (quickest, nothing to set up)
An SSH tunnel carries the web interface through your existing SSH connection, so it stays encrypted and only you can use it.
macOS, Linux or Windows 10/11 (PowerShell):
ssh -L 6789:127.0.0.1:6789 root@YOUR-SERVER-IP
Add -p 2222 if your SSH port is not 22. Leave that window open and visit http://127.0.0.1:6789 in your browser.
Windows with PuTTY:
- Enter your server in Session as usual.
- Go to Connection → SSH → Tunnels. Source port:
6789. Destination:127.0.0.1:6789. Click Add. - Click Open and log in. While the PuTTY window is open, visit
http://127.0.0.1:6789.
Sign in with your user name, password and the 6-digit code from your authenticator app.
Option B: your own HTTPS domain
To open the interface from anywhere, publish it behind a web server with HTTPS on a domain you own, for example fw.example.com. Point the domain's DNS at the server first. The interface keeps its own login and two-factor check behind the proxy.
nginx (with a Let's Encrypt certificate already issued for the domain):
server {
listen 443 ssl http2;
server_name fw.example.com;
ssl_certificate /etc/letsencrypt/live/fw.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fw.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:6789;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
Caddy (gets the certificate by itself):
fw.example.com {
reverse_proxy 127.0.0.1:6789
}
The X-Real-IP and X-Forwarded-Proto headers matter: they let the interface see the visitor's real IP (for lockouts and logs) and mark its session cookie as HTTPS-only. Caddy sends them automatically.
Managing logins and access
| Task | Command or setting |
|---|---|
| List users | csf --ui-user list |
| New password (also issues a new 2FA secret and signs the user out) | csf --ui-user passwd admin |
| Remove a user | csf --ui-user del admin |
| Only allow some IPs to reach the interface | UI_ALLOW = "203.0.113.10,198.51.100.0/24" in /etc/csf/csf.conf, then systemctl restart csf2-ui |
| Change the port | UI_PORT in /etc/csf/csf.conf, then systemctl restart csf2-ui |
| Sign-in log | /var/log/csf2-ui.log (also watched by LFD) |
Sessions end after 30 minutes without activity and after 12 hours at most. After 5 wrong sign-ins in 15 minutes, the interface refuses that IP address for 15 minutes.
Troubleshooting
| Problem | What to do |
|---|---|
| The tunnel page does not load | Check the service with systemctl status csf2-ui and start it with systemctl start csf2-ui. Make sure your SSH tunnel window is still open. |
| Wrong user name, password or code | Check the clock: two-factor codes need the right time on both your phone and the server (timedatectl). If you lost the code, run csf --ui-user passwd admin and add the new secret to your app. |
| Too many failed attempts | Wait 15 minutes, or sign in through the SSH tunnel from another IP. |
| Locked out of SSH after turning protection on | If you used --safe-reload, the old rules return within 30 seconds. Otherwise, open the server console (VNC or IPMI) and run csf --flush to remove the firewall rules, then fix TCP_IN and reload. |
| A website or service stopped working | Its port is not in TCP_IN. Add it, then run csf --safe-reload and csf --confirm. |
| Sign-in works but you are sent back to the login page (proxy) | Your proxy must send X-Forwarded-Proto https and serve the site over HTTPS. |
FAQ
csf -a IP to allow, csf -d IP to block, csf -g IP to check an address, csf -r to reload. If you never use the interface, you can stop it with systemctl disable --now csf2-ui.csf --self-update. It downloads the release, checks its SHA-256 checksum and installs it while keeping your configuration, allow and deny lists.Related: Install CSF on CloudPanel | Full CSF documentation | SSH key authentication | UnderShield monitoring
Need security-focused hosting?
UnderHost services include DDoS-aware infrastructure, SSL support, account isolation, backups, and security guidance.





















