In short: The most effective way to protect the admin area is to open it only to known networks: through an IP allowlist in the web server, through a VPN with a fixed exit address, or with a second, upstream login. What matters is a complete list of all administration addresses, correct handling of proxies and CDNs, and a test from outside. Shielding complements two-factor authentication and updates; it does not replace them.
Why Is the Backend Open at All?
In many companies, admins updated PHP and restarted workers last week. Anyone who then looks at the access logs often finds something else: the CMS login page, the database tool and the hosting panel are being called around the clock from all over the world. Yet they are needed only by a handful of people on your own team.
Each of these addresses is attack surface. Login forms are brute-forced, administration tools contain vulnerabilities of their own, and plugins for the backend are often less thoroughly reviewed than the core of a CMS. If outsiders cannot reach these areas at all, many attacks come to nothing before they begin.
To put it honestly: against PHP2Shell itself, this helps only a little. The vulnerabilities are in the interpreter and, according to php.net, can be triggered without logging in through public PHP pages. Shielding the backend is permanent hardening, not an emergency patch.
Protecting the Admin Area with IP, VPN or a Second Login
There is no single right method. What matters is how your team works and where the website runs.
| Method | Suitable for | Limit |
|---|---|---|
| IP allowlist in the web server | Office with a fixed address, small teams | changing addresses in home offices, maintaining the list |
| VPN with a fixed exit address | distributed teams, service providers | the VPN itself must be well secured and up to date |
| Upstream login (HTTP authentication) | Addition when no fixed address is possible | extra password, only sensible together with TLS |
| Client certificates | a few, centrally managed devices | issuing and revoking certificates requires discipline |
| Separate hostname only on the internal network | larger environments with internal DNS | rebuild of the application, not every CMS supports this |
In practice, a combination works well: allow only the VPN or the company network, plus a second login as a fallback. The actual login in the CMS remains in place with two-factor authentication, as described in the guide Two-Factor Authentication for Admin Access.
Which Addresses Actually Belong to the Backend?
The most common weakness is not the technology but an incomplete list. So proceed in this order:
- Record the login pages of the CMS or shop, including alternative login addresses that plugins create.
- Look for administration tools: database interfaces, file managers, installation scripts, status and monitoring pages.
- Include hosting and server panels, which often run on their own ports.
- Check test and staging instances, which often use the same credentials as the live site.
- Delimit interfaces: Some backend paths are also called by the public frontend, for example for Ajax requests. You must not block these blindly, or forms and shopping carts will break.
Point five is the reason why shielding must always be tested. In WordPress, for example, a file in the admin folder is also used for public functions.
Configuration: IP Allowlist Plus Second Login
In Nginx, both conditions can be combined. With satisfy all, a request must come from an allowed network and additionally pass the second login. Path, addresses and PHP hand-off are placeholders:
location ^~ /backend/ {
satisfy all;
allow 192.0.2.0/24; # company network (placeholder)
allow 198.51.100.10; # VPN exit (placeholder)
deny all;
auth_basic "Interner Bereich";
auth_basic_user_file /etc/nginx/htpasswd-backend;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
}
The nested PHP location is important: because of ^~, other rules for .php are no longer evaluated. In Apache, you achieve the same with a block in which both conditions must apply:
<Location "/backend">
AuthType Basic
AuthName "Interner Bereich"
AuthUserFile /etc/apache2/htpasswd-backend
<RequireAll>
Require ip 192.0.2.0/24 198.51.100.10
Require valid-user
</RequireAll>
</Location>
The password file belongs outside the web root. The second login transmits credentials with every request, so use it only over HTTPS.
Before every change, keep a second way into the server open, such as an existing SSH session. Anyone who locks themselves out will otherwise need the host.
The Pitfalls: CDN, Proxy, IPv6 and Home Office
If your website sits behind a CDN such as Cloudflare or a load balancer, the web server initially sees only its addresses. An IP allowlist would then either block everyone or let everyone through. The web server must take the real address from a header: in Nginx with set_real_ip_from and real_ip_header, in Apache with mod_remoteip.
The rule here: accept the header only from your own proxy addresses. Otherwise any visitor can fake an arbitrary origin. It is equally important that the origin server is not directly reachable, because otherwise the proxy and its rules can be bypassed. Notes on this can be found under Firewall for Web Servers.
Two further points are often overlooked. If the server is reachable via IPv6, your network's IPv6 addresses also need an entry, otherwise admins on IPv6 end up in front of a block. And private internet connections change their address regularly. For home offices and external service providers, a VPN is therefore usually the more stable solution.
How to Check Whether the Shielding Works
A rule that has not been tested does not count as implemented. Test from a connection outside the company network, for example over the mobile network:
# Expected: 403 (blocked) or 401 (second login required)
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/backend/
# Also test PHP files directly, not just the directory
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/backend/index.php
Then make the same requests from the company network or the VPN: the page must be reachable there. Afterwards, check the public frontend, that is, forms, search and shopping cart. In the logs of the following days, accesses to the admin addresses should appear almost only with status 401 or 403.
If the area has been open until now, it is worth looking at the existing accounts. How to find unknown administrators is described in Finding Unknown Admin Accounts in CMS and Server. Protection against mass guessing also helps, see Protecting Admin Logins Against Brute Force.
How does PHP SOS help?
- We record all administration addresses of your websites, panels and tools and separate them from paths needed publicly.
- Together with you, we choose the suitable method, depending on team size, home office and hosting.
- We implement the rules in the web server, take CDN, proxy and IPv6 into account, and keep a way back open while doing so.
- We test from outside and from inside and hand over brief documentation with the allowed networks.
Shielding admin areas is part of our server hardening for PHP web servers.
Frequently asked questions
Isn't a strong password for the CMS login enough?
A strong password and two-factor authentication are mandatory, but they only protect the login itself. Vulnerabilities in login pages, plugins or administration tools remain reachable by anyone. Shielding at network or web server level ensures that outsiders never get that far in the first place.
What do I do if my staff have changing IP addresses?
Then a VPN with a fixed exit address is usually the better solution than a list of individual addresses. All admins connect to the VPN first, and the web server allows only its address. Alternatively, a second upstream login is suitable.
Does an IP block also work behind Cloudflare or a load balancer?
Only if the web server takes the real visitor address from a trusted header and accepts this header exclusively from your own proxy. Otherwise it sees only the proxy's addresses or trusts forged values. In addition, the origin server should not be reachable directly from the internet.
Does a shielded admin area protect against PHP2Shell?
Only to a very limited extent. The PHP2Shell vulnerabilities are in the PHP interpreter and can be attacked without logging in through any public PHP page. What helps against PHP2Shell is the PHP update followed by a restart of all workers; shielding merely reduces the remaining attack surface.