File system permissions in Linux distributions

at 2/05/2015
One critical component of the Linux OS that every Sysadmin must master is the File System permissions. If you are familiar with file permissions under Windows OS, you will see that there are many common elements in UNIX/Linux Systems. The permission system is less complicated than in Windows and you will see that once you've understood the principles behind this technology, everything will be much easier to digest.
By now we've learned that everything in Linux is displayed and treated as files which means that each element must have proper permissions set for users interacting with the Operating System. Each file will have three permission categories present at all time, as follows:

  • owner - the user that created the file and the one who's got rights to modify permissions. Of course, root can modify every file in the OS but, it's not recommended to use root like a standard user
  • group - the local group that has permissions on the file. By adding multiple users in one group you can enable permissions for multiple credentials. The group has similar functionality as in Windows but, only can be configured on a file
  • others - just like in Windows (Everyone), this category includes all other users not included in the first two categories

Each file or directory can have three main permissions, these are similar to Windows:
  • read - user/group is able to open the file and read the content but, cannot modify it. For directories this means that the user can display it's content.
  • write - user/group can modify the file's content. In case of directories, a user/group can rename and delete its files
  • execute - user/group can execute the file
Besides these standard permissions, each file or directory can receive three more "special" permissions:
  • set UID - the owner will be used when executing the file. This means that every user impersonates the owner and executes the file. If the owner is root then this can pose a real security threat because the file is most likely important
  • set GID - used to impersonate the assigned group when executing the file. For directories, all files contained will inherit the parent directory group
  • sticky - a particular file or directory can be deleted only by the owner of the file or by the owner of the parent directory. This type of System permissions are mostly used in public resources where multiple accounts have access to the same resources.
Remember that permissions set on a file does not apply in case of renaming or deleting the file, these permissions are set from the parent directory.
To change permissions for a file we use the following commands:
  1. chown - change the owner for the file
  2. chgrp - change the group of the file
We can use the -h option to apply the command on the symlink or -R to apply the changes to all files contained in the specified path.
When changing file permissions within Linux distributions you can use the chmod command. There are two ways in which we can set permissions:
Symbolic notation
in this method we use symbols to add/remove or set permissions on a file. These symbols are:
  • the entity for which we modify permissions: u=user/owner, g=group and a=all/others
  • the action executed on the file: + = add permissions, - = remove permissions and = for setting exact permissions replacing everything else
  • rights that will be configured: r=read, w=write, x=execute, s=setuid/setgid, t=sticky
Numeric notation
Using this method we assign permissions using a numbering format. Each permission group (owner, group, others) is represented by a 3 bit number.
Suppose we have the following example:
-rw-r--r--.  1 root root    10 Jan 29 02:15 f1
  • the first group rw- represents the owner permissions
  • the second group r-- represents group permissions
  • the third group r-- represents the others permissions
Each set is composed of three permissions types (read, write, execute) in this particular order. Each permission represents a number that is 2 at the power of the position, just like in the following example. The least significant bit is the one located in the right side:
r (read) - 2^2 = 4
w (write) - 2^1 = 2
x (execute) - 2^0 = 1
We need to sum up each number to assign all these permissions to the owner: 1+2+4 = 7
Based on this principles, if we want to assign read, write and execute permissions to a file only for the owner we would type chmod 700 f1 which would modify the permissions as follows:
-rwx------.  1 root root    10 Jan 29 02:15 f1
If we want to expand this permissions and set just read an write permissions to the group, we would type: chmod 760
-rwxrw----. 1 root root 10 Jan 29 02:15 f1
Now let's add read permissions for the others: chmod 764 f1
-rwxrw-r--. 1 root root 10 Jan 29 02:15 f1
For special permissions, the numeric notation is the following:
set UID = 4000
set GID = 2000
sticky = 1000
You'll need to remember the position for each set of permissions. These bits will then be transformed into binary and the numeric permission can be easily configured.
When setting default permissions for files and directories, you'll need to use the umask command in which you'll set a "mask" for the permissions desired. In other words, you'll need to eliminate the undesired permissions. umask command used without any parameters will display the current mask configured on a file

The SSH daemon

at 2/02/2015
The ssh (secure shell) is the standard in terms of remote login on Linux machines. It was introduced as a replacement for telnet and rlogin and it offers enhanced features. From Wikipedia: "Secure Shell (SSH) is a cryptographic network protocol for secure data communication, remote command-line login, remote command execution, and other secure network services between two networked computers". SSH encrypts data by creating a secure channel between a client hosting a SSH client program and a server hosting a SSH server program. It uses Public-key cryptography with two keys (public and private) to create a secure connection. With this tunnel in place, all sensitive information such as usernames and passwords are encrypted.
CentOS distributions are shipped with ssh server and client applications installed, you can verify if these packets are installed by executing rpm -qa | grep ssh:
remote access

If you need to install the ssh client or server package, execute the following command: yum install package_name. To search for a particular package execute yum install ssh:
remote management

Execute yum -ql package_name to see the contents of a rpm package:
remote access

The sshd (daemon) server has its configuration files stored under /etc/ssh:
secure shell

You can search for all ssh related files by executing: find / -name \*ssh\* -type f
All configuration parameters are stored under /etc/ssh/sshd_config.
remote support

By default, the ssh server will listen on port 22, if you want to change the listening port then remove the comment from the port line. The ssh private and public keys are stored in this location. There are a lot of options available in the configuration file so check out the man page for ssh if you want to customize it.
The four keys stored in the ssh folder are the following:
Private RSA key (v2): ssh_host_rsa_key
Public RSA key (v2): ssh_host_rsa_key.pub
Private DSA key (v2): ssh_host_dsa_key
Public DSA key (v2): ssh_host_dsa_key.pub
Private RSA key (v1): ssh_host_key
Public RSA key (v1): ssh_host_key.pub

When you install the openssh software the keys will be generated automatically, but if you need to generate them manually, execute the following command:
ssh-keygen -t rsa -N '' -f ssh_host_rsa_key
remote login

The pid file for sshd is stored in /var/run/sshd.pid:
remote login

The /etc/ssh/ssh_config is the configuration file for the ssh client. To open a ssh connection with a remote machine simply type ssh username@machine_name.

Linux Firewall

at 1/28/2015
Linux Firewall
Iptables is an in-build firewall application that is shipped with most Linux distributions. In CentOS, iptables is used by administrators to create firewall rules that either block or allow network traffic based on some predefined set of rules. The whole firewall app is composed of two elements: iptables and netfilter. While the iptables module is used to configure firewall rules in predefined tables by using command lines, netfilter is a kernel module that's responsible for filtering the network traffic. In this article I will show you how to work with iptables and how to configure your firewall rules. Network filtering with iptables is made by using several parameters: IP address, port numbers and protocols (TCP, UDP, FTP, etc.). When a firewall rule is created, it's placed in one of the following categories:
  • Input - packets that have the Server as destination
  • Output - packets originated from the Server
  • Forward - packets routed through the network that are passed by the Server to other machines for further processing 
When a packet is received by the Server its information is compared based on the firewall rules and if a match is found, the packet is either Accepted or Dropped. Each set of rules (Input, Output, Forward) will have several rules and every packet is checked with each one from top to bottom. Note that if all rules are checked and no match if found, then the default action is taken which can be either Accept or Drop. You should normally have a DENY ALL firewall rule that is placed at the bottom of each chain.
For this demonstration I will be using a CentOS 6.5 virtual machine. This is my testing environment so make sure you are not going to test Iptables in a production network. Iptables is deployed with all CentOS versions that are newer than 5.X. You can check if the packet has been installed by typing rpm -qa | grep iptables :
Linux software

I have two iptables packets installed , the basic packet + support for ipv6. We can use the lsmod command to view the modules loaded in the kernel. By default, the iptable_filter is loaded, type lsmod or lsmod | grep ip_tables to view the modules:
Linux kernel

To view all chains type iptables -L:
Firewall

To flush all rules type iptables -F, note that this command will erase all firewall rules and will ultimately close all ssh connections. I wanted to start from scratch with all rules so I've executed this command. We can delete a certain rule by typing iptables -D INPUT 4, where the number is the rule's position within the chain:
Linux tutorial

Now if I execute iptables -F, the rules will look like this:
Iptables

Let's build our firewall rules. We will start by enabling ssh from any location. To achieve this result we'll need to type iptables -A INPUT -p tcp --dport 22 -j ACCEPT:
Firewall rules

If our server would host a BIND service (DNS) then we would allow all incoming requests on port 53 TCP/UDP by using the following commands:
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
DNS traffic

I just remembered that I want to drop all incoming packets that are not matching any of my INPUT rules. We will create the rule by inserting it in the last position. We can also use the -A (append) parameter, but let's try something different this time: iptables -I INPUT 4 -j DROP
Firewall tutorial

In a production environment you will probably have multiple firewall rules so maybe it will be harder to know what number to use when deleting a rule. You can type iptables -L -n --line-numbers  to view all rules and their associated number:
computer security

If your server has multiple interfaces and you need to open up ports for each one, you will need to add the -i parameter and specify the desired interface. My virtual machine has two interfaces: loopback and ethernet0. Let's pretend our Server has a web service and we need to open HTTPS port on interface eth0 and HTTP on the loopback interface:
iptables -A INPUT -i lo -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
To view a detailed information regarding the firewall rules, type iptables -L --verbose:
Linux firewall

Let's say that you need to allow HTTP traffic for only one IP and HTTPS traffic for multiple IP addresses. We must first modify the rules created previously and DROP all traffic received on these two ports, except the ones that we desire. You cannot edit a rule directly in iptables but, you can replace it with another rule by typing the following:
iptables -R INPUT 5 -i lo -p tcp --dport 80 -j DROP
iptables -R INPUT 6 -i eth0 -p tcp --dport 443 -j DROP
iptables -L -n --line-numbers --verbose
Linux firewall

Ups...I forgot to delete the DROP all rule so I would simply type iptables -I INPUT 4. Now I will allow all HTTP incoming traffic originating from 192.168.0.50 through my loopback interface:
iptables -I INPUT 3 -s 192.168.0.50 -p tcp --dport 80 -i lo -j ACCEPT 

I will add a rule that will allow INBOUND HTTPS traffic on my eth0 interface coming from 10.10.10.0/24 network:
iptables -R INPUT 3 -s 10.10.10.0/24 -p tcp --dport 443 -j ACCEPT -i eth0
Let's verify our results:
Linux security

We can be even more specific by filtering an INCOMING packet based on its source IP and MAC address by loading the mac module. This is how our firewall rule would look like for 172.16.0.20 IP:
iptables -I INPUT 3 -s 172.16.0.20 -p tcp --dport 443 -i eth0 -m mac --mac-source 00:26:B9:16:E5:B0 -j ACCEPT:
Firewall filtering

But what if we want to restrict a range of ports for a specific network? Then we would need add a rule that looks similar to:
iptables -I INPUT 6 -s 10.10.100.0/16 -p tcp --dport 60:70 -j DROP -i eth0
Linux firewall

On the OUTPUT chain I want to allow all connections. I will add a comment to this rule by loading the comments module:
iptables -A OUTPUT -j ACCEPT -m comment --comment "Allow all outbound connections"
Linux Firewall

What's really important is to save your rules once you're finished. This way, the newly created rules will be kept when the system is rebooted. You will need to type /sbin/service iptables save:
Firewall tutorial

The command will execute the iptables initiation script and will run /sbin/iptables-save and write changes to /etc/sysconfig/iptables. Note that with each reboot, the iptables initialization script executes /sbin/iptables-restore which will load all rules saved in /etc/sysconfig/iptables.
That's about it for this article folks, I know that we've covered only the basics of Iptables, but should be enough for the first lesson. Iptables is a powerful Firewall program that enables you to create some really nice filtering rules. Wish you all the best and stay tuned for the following articles.