• Please be aware: Kaspersky Anti-Virus has been deprecated
    With the upgrade to Plesk Obsidian 18.0.64, "Kaspersky Anti-Virus for Servers" will be automatically removed from the servers it is installed on. We recommend that you migrate to Sophos Anti-Virus for Servers.
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Resolved Server header

Seba

Basic Pleskian
how can I remove the Server header from the HTTP requests?

I don't have any info about the version of Apache or Nginx but still it say which web server I'm using, can I get rid of that header?

I found out that this:
Code:
Header unset Server
seems to work at half, it still say Server and then unset Server but seems to work just on domains, how can I solve it server-wide?

I would like to know for both Apache and Nginx.
 
Apache does not permit you to remove the server header. You can limit information with the ServerTokens and ServerSignature directives.

Nginx also does not permit removal of the header. You can set tokens off in Nginx as well to minimize the information.

There are 3rd party modules, including ModSecurity, that can remove the header but I would be careful about implementing 3rd party modules on Plesk. Using ModSec may work but you would not be able to use the Nginx proxy. Since Nginx sits in front of Apache, Nginx will re-add any header string removed.

The Nginx modules to remove headers is the headers more module.
 
ModSecurity it comes directly with Plesk I don't know if I would consider it a 3rd party software, BTW ServerTokens and ServerSignature seems to be already disabled in Plesk by default so in the HTTP header you have just the name of the web server.

What about to give it a name like "my web server" ? I noticed that some company use it E.g. github
 
ModSecurity it comes directly with Plesk I don't know if I would consider it a 3rd party software, BTW ServerTokens and ServerSignature seems to be already disabled in Plesk by default so in the HTTP header you have just the name of the web server.

What about to give it a name like "my web server" ? I noticed that some company use it E.g. github

@Seba,

The essence here is that Plesk by default adds the header containing "X-Powered-By PleskLin", if using Nginx as a reverse proxy for Apache.

Naturally, the Nginx directive add_header is being used in the default Nginx config templates - this directive is added on a per-domain basis.

One would be tempted to think : well, simply overriding this add_header directive would do the trick.

And that certainly is not the case.

The default Nginx templates, as shipped with Plesk, are not very flexible and any custom configuration will not remove the "X-Powered-By PleskLin".

The only solution at the time being is to use custom Nginx templates - which are fairly easy to create.

In short, it is possible but not easy to change or remove the default header, identifying a domain as hosted with a Plesk instance.

I hope the above helps a (tiny) bit.

Kind regards..........
 
@trialotto

I've already change some security issue and removed the "X-Powered-By PleskLin"

Code:
•    Remove Plesk from Server Fingerprint

Removing the X-Powered-By header
1.    Connect to a Plesk server via SSH.
2.    Create a directory for custom templates:
mkdir -p /usr/local/psa/admin/conf/templates/custom/domain
3.    Copy default templates to the created directory:
cp /usr/local/psa/admin/conf/templates/default/server.php /usr/local/psa/admin/conf/templates/custom
cp /usr/local/psa/admin/conf/templates/default/domain/nginxDomainVirtualHost.php /usr/local/psa/admin/conf/templates/custom/domain
cp /usr/local/psa/admin/conf/templates/default/domain/nginxForwarding.php /usr/local/psa/admin/conf/templates/custom/domain
4.    Modify the server.php file:
Open the file /usr/local/psa/admin/conf/templates/custom/server.php and remove the following row:
Header add X-Powered-By PleskLin
Save the changes and close the file.
5.    Modify the file nginxDomainVirtualHost.php:
Open the file /usr/local/psa/admin/conf/templates/custom/domain/nginxDomainVirtualHost.php and remove the following row:
add_header X-Powered-By PleskLin;
Save the changes and close the file.
6.    Modify the file nginxForwarding.php:
Open the file /usr/local/psa/admin/conf/templates/custom/domain/nginxForwarding.php in a text editor and remove the following row:
add_header X-Powered-By PleskLin;
Save the changes and close the file.
7.    Rebuild configuration files of all domains:
Note: If there are 300+ domains on the server, run this command during the maintenance hours.

PHP

Code:
2.    Create a new .ini configuration file in the appropriate PHP directory:
echo 'expose_php = off' > /opt/plesk/php/X.X/etc/php.d/hideheader.ini
Where X.X - a PHP version, e.g. 5.6, 7.0, 7.1, etc
3.    Reload the Plesk PHP service configuration:
service plesk-phpXX-fpm reload  
Where phpXX - a PHP version, e.g. php56, php70, php71, etc.
4.    Verify that the header is not shown anymore:
curl -sIL example.com/index.php | grep -c PHP

Remove apache details

Code:
This seems to be already implemented on Plesk
1.    Go to /etc/httpd/conf/
2.    Add or Edit httpd.conf
3.    Add the following lines:
a.    ServerSignature Off
b.    ServerTokens Prod
4.    Restart Apache

OLD TLS Versions

Code:
Here are two ways to manage TLS version via command line: you can either use plesk bin server_pref or PCI compliance utility with the same effect.
1.    Connect to the server via SSH
2.    To enable TLSv1.1 TLSv1.2 server-wide using plesk bin server_pref utility run:
# plesk bin server_pref -u -ssl-protocols 'TLSv1.1 TLSv1.2'

To enable particular ciphers apply –ssl-chipers option to the command and specify required ciphers. For example:
# plesk bin server_pref -u -ssl-ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'
3.    To enable TLS1.1 and TLS1.2 server-wide using PCI compliance utility run the following:
# plesk sbin pci_compliance_resolver --enable all
For additional options of PCI compliance utility refer to the Plesk Documentation.

SYN-flood attack

Code:
To optimize Plesk for Linux for protection against a SYN-Flood attack:

1.    Log in to Plesk server via SSH
2.    Optimize kernel parameters for DDoS protection by adding the following parameters to /etc/sysctl.conf:

# Enable TCP SYN cookie protection
net.ipv4.tcp_syncookies = 1
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 3
# Turn off the tcp_window_scaling
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack
net.ipv4.tcp_sack = 0

1.    Apply the new settings:

sysctl -p

and lastly installed modSecurity and fail2ban and added the security header in Apache or Nginx, asked on here last week.

though I would like to remove or change the Server header if possible
 
Last edited:
@Seba

I am not sure what the question now is - you still do see the PleskLin part after all those steps or you are talking about some other header that you want to remove?

Please note that I quickly inspected your post - I saw an Apache restart, but not a Nginx reload.

I briefly did a second inspection and saw some other stuff - but that is not relevant yet - can you answer the question above?
 
I've removed yes the PleskLin part but still in the responde header I can still see what I'm using as a web server (Apache/Nginx)

this is a header that I have back from a request

Code:
accept-ranges: bytes
content-length: 1102054
content-security-policy: default-src https: 'unsafe-inline'; object-src https:; img-src 'self' data: https:;
content-type: application/javascript
date: Thu, 12 Sep 2019 12:04:05 GMT
etag: XXXX
last-modified: Tue, 03 Sep 2019 08:42:27 GMT
server: nginx
status: 200
strict-transport-security: max-age=2592000; includeSubDomains; preload
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block

as you can see I still know that I'm using nginx, can I remove that? github in that header they have github for example
 
Last edited:
@Seba

Well, you can't hide the part

server: nginx

since that is hard-coded into source, I am not mistaken.

The "headers more" module can be used to suppress that "server" header, but then you should have your own custom Nginx binary - that is a hell of a job and certainly not recommended, since future Plesk updates of Nginx can cause severe problems.

Moreover, you should be aware of the fact that you can (almost) never fully prevent Apache or Nginx showing server or OS information - for instance, bad SSL requests of a specific kind can still allow security sensitive information to become visible.

From a security perspective, it is better to block ports or IP ranges, as opposed to hiding information - blocking is equal to denying access, hiding is equal to suppressing information that would otherwise be simply visible (and now isn't visible due to suppression of information) : blocking is simply better and less error-prone.

By the way, it is not a bad thing to have the "server" header "server : nginx" - this is an indication that the web server is behind Nginx and some security measures.

Hack attempts are generally aiming at well-know weak points ........ and Nginx is not one of them, at least not often.

In short, do not worry if the part "server : nginx" is visible.

Kind regards..........
 
Ok, thanks for the answer.

I've already implemented a quite strict firewall rules, basically just the port 80 and 443 are allow to be public while all the other ports are just limited to IP addresses (plesk, nagios, db, etc) and not visible to the outside world.

Regards,
 
Ok, thanks for the answer.

I've already implemented a quite strict firewall rules, basically just the port 80 and 443 are allow to be public while all the other ports are just limited to IP addresses (plesk, nagios, db, etc) and not visible to the outside world.

Regards,

Ehm, yes, eh, ports can be scanned - even through a properly configured firewall : there are multiple well-known methods.

Nevertheless, I must admit that I like the way and thoroughness in which you approach security related issues and topics - that is excellent.

One small tip : do not close the server too much, it is often valuable to see what is happening - otherwise, one tends to believe that everything is fine and secure at the front gate, whereas the backdoor is wide open and not shut at all : just keep some unused ports open to be able to detect malicious traffic and activities.

Another tip : tweak fail2ban in such a fashion that malicious IPs are permanently banned on the level of Nginx, the firewall and the entire server - configuring fail2ban actions, jails and filters can be tricky, but it is possible to allow fail2ban to create deny directives (Nginx), firewall ruleset (iptables) and deny rules for the server (e.g. /etc/hosts.deny).

But there is a lot more that can be done - always nice to investigate!

Kind regards.........
 
Thanks, well we are going to submit our system to a penetration test so better to be ready for it

even if you can see which ports are open how easy will be to emulate a connection from the specified IP that is allowed to connect to it?

for the moment I'm using just a standard configuration in fail2ban but I would like to configure it properly and tune it but I have so many things to do... step by step.
this will serve as a starting point for our new system so I will research more and more.

Regards...
 
@Seba,

I am not sure in which context I have to place the line

even if you can see which ports are open how easy will be to emulate a connection from the specified IP that is allowed to connect to it?

and it might be relevant to specify that context.

With respect to pentesting, you have to be aware that a full or thorough pentest of Plesk Panel is not really possible, for many obvious reasons - I will give some explanation.

For the sake of convenience, I will abbreviate penetration testing to something like "pentesting".

First, there is the issue of zero-days and/or server vulnerabilities that are not related to a Plesk instance - they are related to hardware, firmware and/or OS.

Second, every Plesk instance is a Nginx based server application - which application is unrelated to Apache web server, Nginx (stand-alone or as a reverse proxy) and any kind of other application hosted via the Plesk (hosting) Panel : it is good practice to perform pentests per application.

Third, even when "peeling the onion of applications that compose Plesk and the server it is hosted on", one still can get the tears in the eyes - any pentest can be causing a lot of related and unrelated problems, allowing succesful penetration : in this scenario, it is not the pentest that is succesful, it is just the combination of applications, server layers, configuration applied (and so on) that fails, with this failure resulting in succes for a pentest.

The last point must be clarified a bit and I will do so with two examples.

One simple example : if Nginx based security measures fail, that does not mean that Apache is insecure - it is just the combination of Nginx + Apache that fails (and without Nginx as a reverse proxy, it can be the case that an identical pentest will not succeed when only aiming at Apache).

Another important example : combining attacks, such as an DDoS or brute force attack with a separate attack on Apache or SSH, can be very valuable for hackers - due to the overload of the system, a lot of security measures will fail to work properly..... and one of the main culprits is Fail2Ban (and if Fail2Ban is not working properly, then the "overload attack" is creating circumstances that allow more easy access to other services or ports, which are attacked by the second type of attack).

Fourth, everything "in memory" is the most important vector of the attack surface - it is hard to detect and difficult to resolve : any "staged attack" that creates an entry that is cached or stored in memory can be used in a later stage to execute malicious code, without the sysadmin knowing it or being able to detect it properly.

In short, you should just pentest each server level (Apache, Nginx etc) separately, followed by a pentest for common applications on the server (WordPress and similar) and afterwards, one could do a pentest of the entire system, OS, memory and/or such alike.

At least, that is the most easy method, when taking into account that a full pentest is almost impossible.

I hope the above helps a tiny bit.

Kind regards.........

PS When doing a pentest, always create a separate machine containing all relevant hack tools that are there and freely available - that will cover 90% of the attacks. Please discard the machine with hacking tools installed, as soon as possible - it is not good to have such a machine on your name (read: reputation considerations) or not good to continue usage of this machine (read: any automated check could also result in the "hacking machine" ending up on a blocklist of some kind, hence making your pentests a bit biased - if the IP ends up by accident on a blocklist, then some tests would be invalidated) or not good to keep the machine open (read: any "hacking machine" with a lot of freely available hacking tools is vulnerable itself, implying that indirect access to the server that has been pentested can be easily obtained!).
 
with:

even if you can see which ports are open how easy will be to emulate a connection from the specified IP that is allowed to connect to it?

I was meaning how easy could be in first place to find the allowed IP that an open port allow E.g. port 22 just allow incoming from 110.110.110.20 and second how to emulate that your connection it come from that specified IP address.

The pentest we are going trough of course will test any vulnerability in the Application (website) itself in first place, and then any other vulnerability derived from using this new server configuration and design.

One of our main problem I think is the mapping that for CORS reason is asked through header access-control-allow-origin *, I know is not secure but with the current stack is the only way, in the future we will use different way maybe.

I understand your point about layers and I know that as everything is new, and we are new in this kind of thing, will not be configured as its best so will require a lot more of works to lock it down properly.

Regards...
 
Back
Top