Level: Medium

Type: Fix

Description: There’s a web server serving a file /var/www/html/index.html with content “hello sadserver” but when we try to check it locally with an HTTP client like curl 127.0.0.1:80, nothing is returned. This scenario is not about the particular web server configuration and you only need to have general knowledge about how web servers work.

Test: curl 127.0.0.1:80 should return: hello sadserver

This was a fun one! It touches on some very simple web server troubleshooting that many know with the exception to people who are just getting their start. I’ll walk through it a little and provide the thought process behind solving this.

So, we cannot access the the web server even from the machine the web application is hosted on. When we run the curl(1) command to view the applciation from the command line. It just hangs and doesn’t do anything.

root@ip-172-31-21-14:/# curl 127.0.0.1:80

This could be a couple of things. This machine isn’t Red Hat Linux based. So, it takes SELinux out of the equation. So my first thought is perhaps the firewall is the firewall is blocking it because there is no timeout.

Checking the status of UFW with the following command shows it as inactive. Indicates that the system is using the default firewall. Which is iptables(1).

root@ip-172-31-21-14:/# ufw status
Status: inactive

Checking the systems iptables entries shows that there is a drop rule; numbered 1, for input from and to anywhere on port 80. This will need to be removed before anything can reach the web application.

root@ip-172-31-21-14:/# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

To remove the rule. I entered the following command to delete the first INPUT rule.

root@ip-172-31-21-14:/# iptables -D INPUT 1

Listed the rules again to verify it’s gone and it’s no longer there. So now it’s time to test.

root@ip-172-31-21-14:/# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Ran the same command as last time. Now a new error comes up. The 403 Forbidden error can indicate a few things. But, in this case it’s probably file permissions for the file that’s being hosted. Generally it means the web server couldn’t access something. A best practice is to run these servers as a separate user account. Not root. So, if that user account cannot access the file. It wont be able to serve it.

root@ip-172-31-21-14:/# curl 127.0.0.1:80
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at 127.0.0.1 Port 80</address>
</body></html>

Checking the file permissions of the

root@ip-172-31-21-14:/# ls -lah /var/www/html/index.html 
-rw------- 1 root root 16 Aug  1  2022 /var/www/html/index.html

The web server is Apache. Checking the configuration file should give us some insight into which user or group the server is running as. In this case we need to look at the envvars file to see what that is.

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

After checking the envvars file. It looks like in this case it’s the www-data user and group the Apache web server is running as. Going to need to change the permissions of the index.html file to fix this.

# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

Changed the file permissions on index.html so they were owned by the www-data user and group. Going to test it again and see if it works.

root@ip-172-31-21-14:/# chown www-data:www-data /var/www/html/index.html

Looks like that works. We get the hello sadserver message back from the web server. This didn’t require a restart to the web server.

root@ip-172-31-21-14:/# curl 127.0.0.1:80
hello sadserver

Some key take aways from this. It’s not always server configuration that causes these things to break. Sometimes it’s the file system or the firewall - kind of hurt to say that. If you don’t pay attention to little things. It can impact the services you’re providing.

In this solution. You need to look for the firewall rules and the file permissions for the index.html file to solve it.