{"id":23952,"date":"2021-09-28T10:46:28","date_gmt":"2021-09-28T10:46:28","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=23952"},"modified":"2022-04-13T15:56:34","modified_gmt":"2022-04-13T15:56:34","slug":"best-practices-to-secure-your-apache-web-server","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/best-practices-to-secure-your-apache-web-server\/","title":{"rendered":"Best practices to secure your Apache Web Server"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Server Version Banner should be removed.<\/h2>\n\n\n\n<p>I&#8217;d say this is one of the first things to think about, because you don&#8217;t want to reveal your web server version. By exposing the version, you are assisting the hacker in expediting the reconnaissance process.<\/p>\n\n\n\n<p>The Apache Version and OS Type will be exposed by default, as illustrated below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"181\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-unsecured.png\" alt=\"\" class=\"wp-image-23953\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-unsecured.png 666w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-unsecured-300x82.png 300w\" sizes=\"auto, (max-width: 666px) 100vw, 666px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Go to the $Web Server\/conf directory.<\/li><li>Using the vi editor, modify httpd.conf.<\/li><li>Save the httpd.conf file after adding the following directive.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ServerTokens <span class=\"hljs-string\">\"Prod\"<\/span>\nServerSignature <span class=\"hljs-string\">\"Off\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"181\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/server-signature.png\" alt=\"\" class=\"wp-image-23954\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/server-signature.png 666w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/server-signature-300x82.png 300w\" sizes=\"auto, (max-width: 666px) 100vw, 666px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Apache should be restarted<\/li><\/ul>\n\n\n\n<p>The version information in the page generated by Apache will be removed by ServerSignature.<\/p>\n\n\n\n<p>Header will be changed to production only by ServerTokens, i.e., Apache.<\/p>\n\n\n\n<p>As you can see in the screenshot below, the version and operating system information has vanished.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"826\" height=\"203\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-secured.png\" alt=\"\" class=\"wp-image-23955\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-secured.png 826w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-secured-300x74.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/response-header-secured-768x189.png 768w\" sizes=\"auto, (max-width: 826px) 100vw, 826px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Disable the directory browser&#8217;s display.<\/h2>\n\n\n\n<p>Disable directory listing in a browser to prevent visitors from seeing all of the files and folders under the root or subdirectory.<\/p>\n\n\n\n<p>Let&#8217;s see how it looks with the default settings.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Go to the $Web Server\/htdocs directory.<\/li><li>Make a folder with a few files inside it.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># mkdir test<\/span>\n<span class=\"hljs-comment\"># cd test<\/span>\n<span class=\"hljs-comment\"># touch hi<\/span>\n<span class=\"hljs-comment\"># touch hello<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, go to http:\/\/localhost\/test and try to connect to Apache.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"248\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-unsecured.png\" alt=\"\" class=\"wp-image-23956\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-unsecured.png 666w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-unsecured-300x112.png 300w\" sizes=\"auto, (max-width: 666px) 100vw, 666px\" \/><figcaption>As you can see, it shows all of your files and directories, which I am sure you don&#8217;t want to expose that.<\/figcaption><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Go to the $Web Server\/conf directory.<\/li><li>Using vi, open httpd.conf.<\/li><li>Change the Options directive to None or \u2013Indexes after you&#8217;ve added the Directory.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Directory<\/span> \/<span class=\"hljs-attr\">opt<\/span>\/<span class=\"hljs-attr\">lampp<\/span>\/<span class=\"hljs-attr\">htdocs<\/span>\/<span class=\"hljs-attr\">test<\/span>&gt;<\/span>\nOptions -Indexes\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Directory<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>or<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Directory<\/span> \/<span class=\"hljs-attr\">opt<\/span>\/<span class=\"hljs-attr\">lampp<\/span>\/<span class=\"hljs-attr\">htdocs<\/span>\/<span class=\"hljs-attr\">test<\/span>&gt;<\/span>\nOptions None\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Directory<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Note:<\/strong> If your environment contains multiple Directory directives, you should consider implementing the same thing for all of them.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Restart Apache<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Now, go to http:\/\/localhost\/test and try to connect to Apache.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"181\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-secured.png\" alt=\"\" class=\"wp-image-23957\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-secured.png 666w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/test-directory-secured-300x82.png 300w\" sizes=\"auto, (max-width: 666px) 100vw, 666px\" \/><\/figure>\n\n\n\n<p>Instead of displaying the test folder listing, it displays a forbidden error.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Use a non-privileged account to run Apache.<\/h2>\n\n\n\n<p>Nobody or daemon is the default user account for a default installation. It&#8217;s a good idea to provide Apache its own non-privileged user.<\/p>\n\n\n\n<p>The goal is to protect other services running in case of any security hole.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Create an apache user and group.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># groupadd apache<\/span>\n<span class=\"hljs-comment\"># useradd \u2013G apache apache<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\"><li>Change the ownership of the apache installation directory to a newly created non-privileged user.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># chown \u2013R apache:apache \/opt\/lampp<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\"><li>Go to the $Web Server\/conf directory.<\/li><li>Using vi, open httpd.conf<\/li><li>Change the User &amp; Group Directive to non-privileged account apache by searching for it.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">User apache \nGroup apache<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\"><li>Save the httpd.conf configuration file.<\/li><li>Restart Apache<\/li><li>grep for running http processes and make sure they&#8217;re all running with the apache user.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># ps \u2013ef |grep http<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"667\" height=\"181\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/http-grep.png\" alt=\"\" class=\"wp-image-23958\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/http-grep.png 667w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2021\/09\/http-grep-300x81.png 300w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>One process should be running as root, as you can see. This is due to the fact that Apache listens on port 80 and must be run as root.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Permissions on binary and configuration directories should be protected.<\/h2>\n\n\n\n<p>The binary and configuration permissions are set to 755 by default, which implies that any user on the server may see the settings. You can deny access to the conf and bin folders to another user.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Go to the $Web Server\/conf directory.<\/li><li>Bin and conf folder permissions should be changed.<\/li><\/ul>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">chmod \u2013R 750 bin conf\n\n\n\n\n\n<\/code><\/span><\/pre>\n\n\n<h4 class=\"wp-block-heading\"><\/h4>\n\n\n<div class=\"epyt-gallery\" data-currpage=\"1\" id=\"epyt_gallery_55189\"><iframe loading=\"lazy\"  id=\"_ytid_17610\"  width=\"760\" height=\"427\"  data-origwidth=\"760\" data-origheight=\"427\" src=\"https:\/\/www.youtube.com\/embed\/?enablejsapi=1&#038;autoplay=0&#038;cc_load_policy=0&#038;cc_lang_pref=&#038;iv_load_policy=1&#038;loop=0&#038;rel=1&#038;fs=1&#038;playsinline=0&#038;autohide=2&#038;theme=dark&#038;color=red&#038;controls=1&#038;disablekb=0&#038;\" class=\"__youtube_prefs__  no-lazyload\" title=\"YouTube player\"  data-epytgalleryid=\"epyt_gallery_55189\"  allow=\"fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><\/iframe><div class=\"epyt-gallery-list\"><div>Sorry, there was a YouTube error.<\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Server Version Banner should be removed. I&#8217;d say this is one of the first things to think about, because you don&#8217;t want to reveal your web server version. By exposing&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[4957],"tags":[5381],"class_list":["post-23952","post","type-post","status-publish","format-standard","hentry","category-linux","tag-tags"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23952","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=23952"}],"version-history":[{"count":3,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23952\/revisions"}],"predecessor-version":[{"id":24179,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23952\/revisions\/24179"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=23952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=23952"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=23952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}