# 17.1 Website and FirewallD In this chapter we will configure and create a website on port **9500**, the main tool for Red Hat servers is the httpd service from apache. Be **root** during this excersize. To create the site on port **9500** and allow access from the outside world we must go through some simple steps: 1. Download and install httpd 2. Configure httpd settings 3. Create index.html file 4. Reset selinux permissions 5. Allow port through the firewall 6. Allow port through Selinux 7. Start the httpd server and check the result ## 1: Download and install httpd First we must install the httpd server. ```bash dnf install httpd ``` ## 2: Configure httpd settings Httpd has configuration is at the ```/etc/httpd/conf/httpd.conf``` When we look into it with a text editor we will find many options to configure the webserver, however the following are important: ``` # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the # directive. # # Change this to Listen on a specific IP address, but note that if # httpd.service is enabled to run at boot time, the address may not be # available when the service starts. See the httpd.service(8) man # page for more information. # #Listen 12.34.56.78:80 Listen 80 ``` ```Listen 80``` This make the webserver listen to the http port 80 which is standard. ```bash # DocumentRoot: The directory out of which you will serve your # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. # DocumentRoot "/var/www/html" # # Relax access to content within /var/www. # AllowOverride None # Allow open access: Require all granted # Further relax access to the default document root: # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn't give it to you. # # The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs/2.4/mod/core.html#options # for more information. # Options Indexes FollowSymLinks # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # Options FileInfo AuthConfig Limit # AllowOverride None # # Controls who can get stuff from this server. # Require all granted ``` This config part is telling us that the main place the webserver is looking to server a website is ```/var/www/html/```. So for us to make a site listen to port **9500** and server a website we need to change ```Listen 80``` to ```Listen 9500```. ```bash # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the # directive. # # Change this to Listen on a specific IP address, but note that if # httpd.service is enabled to run at boot time, the address may not be # available when the service starts. See the httpd.service(8) man # page for more information. # #Listen 12.34.56.78:80 Listen 9500 ``` It should look like this when adjusted. ## 3: Create index.html file The webserver will always attempt to first server an **index.html** file to the outside world, since it is not here we will need to make it ourselves. ``` vim /var/www/html/index.html ``` Fill it with funny text here is an example: ``` ()__() (='.'=) (")__(") Website bunny1! ``` ## 4: Reset selinux permissions Let's make sure SeLinux is in enforcing! ``` getenforce ``` If it is in permissive change it to enforcing in ```/etc/selinux/config``` and change it to enforcing. That will only take effect after a reboot so for now: ``` setenforce 1 ;getenforce ``` This should set SeLinux in Enforcing and show that it worked. To set the correct selinux permissions on this **index.html** we need to reset the permissions. ```bash restorecon -RFvv /var/www/ ``` This will reset the selinux permissions on the file to the correctly labeled ones. ## 5: Allow port through the firewall The firewall in Red Hat linux is called firewalld. First we need to check if firewalld is running. ```bash systemctl status firewalld ``` ```bash [root@rhcsa conf]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2022-09-22 14:15:38 UTC; 32min ago Docs: man:firewalld(1) Main PID: 672 (firewalld) Tasks: 2 (limit: 11106) Memory: 40.1M CPU: 8.430s CGroup: /system.slice/firewalld.service └─672 /usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid Sep 22 14:15:33 rhcsa.greateracademy.local systemd[1]: Starting firewalld - dynamic firewall daemon... Sep 22 14:15:38 rhcsa.greateracademy.local systemd[1]: Started firewalld - dynamic firewall daemon. ``` This is a correctly running firewalld service. The command to manipulate firewalld is **firewall-cmd** Let's see what rules the firewalld has at this moment: ```bash firewall-cmd --list-all ``` This shows the rules that are currently in effect: ```bash [root@rhcsa ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: cockpit dhcpv6-client http ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ``` As you can see these services already have access ```cockpit dhcpv6-client http```. With firewalld we can add pre-configured services or individual ports. Let's say we want to add http to the list of services allowed: ```bash firewall-cmd --add-service http ``` Let's check the list again: ```bash [root@rhcsa ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: cockpit dhcpv6-client http http ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ``` http is now a part of this list. However! When we reload firewalld to simulare a restart of the vm! ```bash firewall-cmd --reload ``` Then check the list again. ```bash firewall-cmd --reload ``` ```bash [root@rhcsa ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: cockpit dhcpv6-client http ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ``` The rule is gone to add the service to survive a reboot we need to add **--permanent** flag. so let's add it this time and reload it it: ```bash firewall-cmd --add-service http --permanent; firewall-cmd --reload; firewall-cmd --list-all ``` The result should be like this: ```bash [root@rhcsa ~]# firewall-cmd --add-service http --permanent; firewall-cmd --reload; firewall-cmd --list-all success success public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: cockpit dhcpv6-client http http ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ``` Now let's add an individual port: ```bash firewall-cmd --add-port 9500/tcp --permanent ``` This will add the port on the tcp protocol which http uses. ```bash firewall-cmd --reload; firewall-cmd --list-all ``` The result should be as following: ```bash [root@rhcsa ~]# firewall-cmd --reload; firewall-cmd --list-all success public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: cockpit dhcpv6-client http http ports: 9500/tcp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ``` The port has been added for our server! ## 6: Allow port through Selinux Now we need to add the port to SeLinux else it will not allow http traffic over the port. Let's have a look at the ```semanage``` command and the functionalities that SELinux could be blocking. To use the ```semanage``` command, we need the ```policycoreutils-python``` package to be installed. We can do this with the following command ```dnf install -y policycoreutils-python-utils.noarch```. More information on yum in later chapters. So now let's have a look at the ```semanage``` command and add the ```port -l``` options to it. This will give us a list of all the SELinux ports that are configured to be allowed. ```bash [root@rhcsa ~]# semanage port -l ``` This is quite a big list, but we can use ```grep``` on this. Lets ```grep``` on the http port. ```bash [root@rhcsa ~]# semanage port -l | grep http http_cache_port_t tcp 8080, 8118, 8123, 10001-10010 http_cache_port_t udp 3130 http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 pegasus_http_port_t tcp 5988 pegasus_https_port_t tcp 5989 ``` What we need is the **http_port_t**. This shows us that SELinux will allow the service http to use port 80. But what if we wanted to change this port so that we can http on port 9500. Let's have a look on how we can do this. ```bash semanage port -a -t http_port_t -p tcp 9500 ``` ```bash semanage port -l | grep http ``` See the results: ```bash [root@rhcsa ~]# semanage port -l | grep http http_cache_port_t tcp 8080, 8118, 8123, 10001-10010 http_cache_port_t udp 3130 http_port_t tcp 9500, 80, 81, 443, 488, 8008, 8009, 8443, 9000 pegasus_http_port_t tcp 5988 pegasus_https_port_t tcp 5989 ``` This will allow port **9500** to be used for **http_port_t** traffic which is what we needed. ## 7: Start the httpd server and check the result Now we need to start the **httpd** server. ```bash systemctl enable httpd --now ``` This starts and enabled the httpd server. We can test the server with the curl command: ```bash curl localhost:9500 ``` ```bash [root@rhcsa ~]# curl localhost:9500 ()__() (='.'=) (")__(") Website bunny1! ``` And test it from the hypervizor: ```bash curl 192.168.121.200:9500 ``` ```bash ()__() (='.'=) (")__(") Website bunny1! ```