If you are running Fedora Linux as a server, one issue you frequently encounter is strange permission denied error message triggered when you are accessing one of the available network services run on the server. There are a lot of network services to mention, but HTTP and FTP are two good examples of such services. Assume you are trying to access FTP server on your Fedora box. You type the IP address of the server and then supply the username and password. Voila!!! You thought you would be immediately logged in. But instead of seeing the files in your home folder, you are shown an error message. The error message may vary, from something like “Login incorrect for user blah” displayed by Midnight Commander, “500 OOPS: cannot change directory: /home/blah” from Total Commander, to other error messages shown by different FTP client programs.
If you are 100% sure that you supply the correct user and password information, why couldn’t you get in? Let us assume that you have root access to the server so that you can remotely troubleshoot from the console. This post will give some guide on how you can solve this problem based on common configurations of a Fedora server.
1. Check your firewall configuration
You might forget to open the FTP and HTTP port. If you are running iptables as your firewall program, you can invoke the following command to check if you have properly set the box to accept TCP connection from FTP and HTTP port.
root# iptables -L | egrep "ftp|https?" --color=always
In above figure, you can see that the firewall has been properly configured. All incoming TCP traffic to FTP, HTTP, and HTTPS ports has been allowed. Hence, there is big chance that the cause of permission problem is caused by SELinux. Troubleshooting SELinux for this problem will be explained in the next step.
2. Check your SELinux configuration
Some Fedora users and administrators may consider SELinux as a nightmare instead of helper. To my personal assessment, SELinux is a valuable preset tool to harden the security of a Fedora/RHEL box. There are three levels or modes of SELinux deployment: enforcing, permissive, and disabled. In enforcing mode, SELinux will enforce the security rules and prevent the execution of each action that violates the rule. In permissive mode, SELinux will print or log warning of security violation instead of annulling the action. When SELinux is disabled, there is no further security enhancement. Security will be exerted based on the file access permission, firewall configuration, and built-in security embedded in the executed file or application.
To check the status of SELinux on your Fedora box, you can invoke this command from the command line terminal:
root# cat /etc/selinux/config
In the figure above, you can see the content of a sample selinux config file. As you read through the whole content of the file, you will notice that SELinux is running on enforcing mode with targeted type of filtering. This means that opening the firewall is not enough. We also need to properly set several boolean configuration flags for actions associated with FTP and HTTP(S) services.
There are two methods to set SELinux boolean flags. The first method is using GUI. You can access SELinux management by clicking System > SELinux Management menu on your desktop. This step is depicted in the following picture.
After you provide the root password, you will be able to change the flags for all SELinux boolean configurations. Each boolean configuration is associated with a module. A brief description of each configuration is also provided in the management tab but you may consider getting more explanation for each one from the manual or consulting with your favorite search engine. The figure below shows the snapshot of GUI-based SELinux management for boolean configurations
Sometimes when you don’t have physical reach to your server, you may need to do the administrative tasks remotely. This usually means that you will administer the server from command line-based SSH terminal. In this case, you may need to get familiar with getsebool and setsebool, two shell commands used to manage boolean configurations of SELinux.
The command getsebool is used to get the boolean value of a certain SELinux configuration. Intuitively, the command setsebool is used to set the boolean value of an SELinux configuration. Since we have narrowed our discussion to security configurations related to FTP and HTTP(S), we will only use getsebool and setsebool to configure the security permissions of those services.
a. Configuring SELinux Security Permissions for HTTP(S) Service
Default security module for HTTP(S) service in SELinux is for httpd daemon from Apache Web Server. For other web servers, you might need to read their documentations about SELinux tweaks. The following figure compares configurations of a properly configured server and another one with HTTP permission issue.
As the depicted in the picture, the following command is used to get the value of httpd related SELinux boolean configurations:
root# getsebool -a |egrep "^.*httpd.*on$" --color=always
You may need to set the following configuration flags to on:
*httpd_builtin_scripting -> if set, it will allow calls to scripting language modules like PHP
*httpd_unified -> if set, it will allow httpd to handle all content files
*httpd_enable_homedirs -> if set, it will allow httpd to read user’s home directory
*httpd_read_user_content -> if set, it will allow httpd to read user content
*httpd_can_network_connect -> if set, it will allow httpd to connect to the network
To configure the problematic server with proper httpd boolean flags, we can invoke the following command from the command line:
root# setsebool -P config_directive=[on|1|true] ..
From the previous picture, we need to set the following configuration flags to on:
root# setsebool -P httpd_builtin_scripting=1 httpd_can_network_connect=1 httpd_can_network_connect_db=1 httpd_enable_cgi=1 httpd_enable_homedirs=1 httpd_read_user_content=1 httpd_unified=1
b. Configuring SELinux Security Permissions for FTP Service
Similar with previous example, we use getsebool to get the value of security configuration related to FTP.
root# getsebool -a |egrep "^.*ftp.*on$" --color=always
The picture below shows configuration of two servers, one with a user-accessible FTP server and the other with permission problem when accessing FTP server.
Based on the figure, we need to set the following FTP-related configurations to be on:
We invoke the following command to configure our problematic FTP server:
root# setsebool -P allow_ftpd_full_access=1 ftp_home_dir=1
Now we are done with tweaking SELinux for FTP and HTTP(S) services. You shouldn’t have any more problems accessing your FTP and HTTP server. What a happy day!