Skip to main content

Resources

Enabling CentOS system users and building publishing directories

In this process, we will learn how Apache provides you with the option to allow your system users to host web pages within their home directories. This approach has been used by ISPs since the outset of web hosting and in many respects, it continues to flourish due to its ability to avoid the more complex method of virtual hosting. In the previous process, you were shown how to install the Apache web server, and with the desire to provide hosting facilities for system users, it is the purpose of this process to show you how this can be achieved in CentOS 7.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges and a console-based text editor of your choice. It is expected that your server will be using a static IP address that supports a hostname or domain name and that the Apache web server is already installed and currently running. Also, at least one system user account should be available on the server.

The Process

To provide the functionality offered by this process, no additional packages are required but we will need to make some modifications to the Apache configuration file.

  1. To begin, log in as root and open the Apache userdir configuration file in your favorite text editor by typing the following command after you have created a backup copy of it first:
    cp /etc/httpd/conf.d/userdir.conf /etc/httpd/conf.d/userdir.conf.BAK vi /etc/httpd/conf.d/userdir.conf
  2. In the file, locate the directive that reads as UserDir disabled. Change it to the following:
    UserDir public_html
  3. Now scroll down to the section and replace the existing block with the one here:

                AllowOverride All
               Options Indexes FollowSymLinks
               Require all granted
  4. Save and exit the file. Now log in as any system user to work with your publishing web directory (su -), and then create a web publishing web folder in your home directory and a new home page for your user:
    mkdir ~/public_html && vi ~/public_html/index.html
  5. Now add the required HTML. You can use the following code as a starting point but it is expected that you will modify it to suit your own needs:


    Welcome to my web folder's home page

    Welcome to my personal home page


  6. Now modify the permissions of the Linux system user’s home folders by typing:
    chmod 711 /home/
  7. Set the read/write permissions for public_html 755 so Apache can execute it later:
    chmod 755 ~/public_html -R
  8. Now log in as root again using su -root to configure SELinux appropriately for the use of http home directories:
    setsebool -P httpd_enable_homedirs true
  9. As root, change the SELinux security context for your user’s web public directory (this needs policycoreutils-python package to be installed) with the username :
    semanage fcontext -a -t httpd_user_content_t /home//public_html restorecon -Rv /home//public_html
  10. To complete this process, simply reload the httpd service configuration:
    apachectl configtest && systemctl reload httpd
  11.  You can now test your setup by browsing to (substitute appropriately): http:///~ in any browser.

How Does It Work?

In this process, we learned how easy it is to host your own peers by enabling user directories on the Apache web server.

So what did we learn from this experience?

We began the process by making a few minor configuration changes to Apache’s userdir.conf in order to set up the user directory support. We activated the user directories by adjusting the UserDir directive from disabled to pointing to the name of the HTML web directory within each user’s home directory, which will contain all our user’s web content, and call this public_html (you can change this directory name to anything you like but public_html is the de facto standard for naming it). Then we proceeded to modify the tag. This directive applies all its enclosed options to the parts of the filesystem defined in the beginning tag /home/*/public_html. In our example, the following options are enabled for this directory: Indexes are used whenever a directory does not have index.html. This will show the file and folder content of the directory as HTML. As we will see in the process Securing Apache, this should be avoided for your web root whereas, for serving user directories, this can be a good choice if you just want to make your home folder accessible to your peers so they can quickly share some files (if you have any security concerns, remove this option). The FollowSymLinks option allows symbolic links (man ln) from this public_html directory to any other directory or file in the filesystem. Again, avoid this in your web root folder but for home directories, it can be useful if you need to make files or folders accessible within the public_html folder without the need to copy them into it (user directories often have disk quotas). Next we configured access control to the public_html folder. We did so by setting Require all granted, which tells Apache that in this public_html folder anyone from everywhere can access the contents through the HTTP protocol. If you want to restrict access to your public_html folder then you can replace all granted with different options. To allow access based on a hostname use, for example Require host example.com. With the ip parameter we can restrict the public_html folder to an internally available network only, for example Require ip 192.168.1.0/24. This is particularly useful if your web server has multiple network interfaces and one IP address is used for connecting to the public Internet and another one for your internal private network. You can add multiple Require lines within a Directory block. Remember to always set at least Require local which allows local access.

Having saved our work, we then began to make various changes to the home directories. First we created the actual public_html folder within our user’s home directory, which will be the actual personal web publishing folder later. Next, we changed its permissions to 755 which means that our user can do everything in the folder but all the other users and groups can only read and execute its content (and change into this folder). This type of permission is needed because all the files in the public_html folder will be accessed by a user named apache with the group apache if someone requests its content via the Apache web server later. If no read or execute permissions are set for the other users flag (man chmod), we will get an Access denied message in our browser. This will also be the case if we do not change the permissions for the parent /home/ directory in advance because parent directory permissions can affect its child subfolder permissions. A normal user home directory in CentOS Linux has the permissions 700 which means that the home directory’s owner can do anything but everyone else is completely locked out of the home folder and its content.

As written before, the Apache user needs access to the subfolder public_html so we have to change the permissions to 711 for the home folder so that everyone else can at least change into the directory (and then access the subfolder public_html as well since this is set to be read/write accessible). Next, we set the security context of our new web folder for SELinux. On systems running SELinux, it’s mandatory to set all the Apache web publishing folders to the httpd_user_content_t SELinux label (along with their contents) in order to make them available to Apache. Also, we made sure to set the correct SELinux Boolean to enable Apache home directories (which is enabled by default): httpd_enable_homedirs is true, read Working with SELinux to learn more about SELinux.

You should be aware that the previous process of managing the home directories should be repeated for each user. You will not have to restart Apache every time you enable a new system user but, having completed these steps for the first time, it will be simply a matter of reloading the configuration of the httpd service to reflect the initial changes made to the configuration file. From this point on, your local system users can now publish web pages using a unique URL based on their username.

 

Installing and configuring a caching-only nameserver in CentOS

Every network communication between computers can only be made through the use of unique IP addresses to identify the exact endpoints of the communication. For the human brain, numbers are always harder to remember and work with than assigning names to things. Therefore, IT pioneers started in the early 70s to invent systems for translating names to physical network addresses using files and later simple databases. In modern computer networks and on the Internet, the relationship between the name of a computer and an IP address is defined in the Domain Name System (DNS) database. It is a worldwide distributed system and provides the domain name to IP address resolution and also the reverse, that is IP address to domain name resolution. DNS is a big subject, and it is the purpose of this process to provide the perfect starting point by showing you how to install and setup your own caching-only and forwarding nameserver. Here we will use Unbound, which is a highly secure and fast recursive and caching DNS server solution, and therefore our preferred choice. But you need to remember that Unbound cannot be used as a fully authoritative DNS server (which means that it provides its own domain name resolution records) we will use the popular BIND server for this in a later process. A caching-only DNS server will serve to forward all the name resolution queries to a remote DNS server. Such a system has the intention of speeding up general access to the Internet by caching the results of any domain resolution request made. When a caching DNS server tracks down the answer to a client’s query, it returns the answer to the client. However, it also stores the answer in its cache for a specific period of time. The cache can then be used as a source for subsequent requests in order to speed up the total round-trip time.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a static IP address, and a console-based text editor of your choice. An Internet connection will be required to download additional packages. In this example, our DNS server runs in a private network with the network address 192.168.1.0/24.

The Process

In this process, we will first configure a caching-only and then a forwarding only DNS server.

Configuring a caching-only Unbound DNS server

In this section, we will consider the role of Unbound as a caching-only nameserver, handling recursive DNS requests to the other remote DNS servers and caching the query for a certain time period to improve the response time when the server is asked for the same name resolution again:

  1. To begin, log in as root and install the required packages by typing:
    yum install unbound bind-utils
  2. Now make a copy of the unbound configuration file so we can revert our changes later, and then open it in your favorite text editor:
    cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.BAK
    vi /etc/unbound/unbound.conf
  3. Scroll down to find the following line: # interface: 0.0.0.0 Remove the # sign to uncomment it (activate it), so it reads as follows:
    interface: 0.0.0.0
  4. Next, scroll down to find the line # access-control: 127.0.0.0/8 allow. Uncomment the line to activate it and change the network address to fit your needs:
    access-control: 192.168.1.0/24 allow
  5. Save and close the file, and then create an RSA keypair with certificates for secure DNSSEC support before you check the correctness of the changed configuration file:
    unbound-control-setup && unbound-checkconf
  6. Next, open the DNS service in your firewalld configuration on your server because we want to be able to use our new DNS service from other clients in the network for querying as well:
    firewall-cmd --permanent --add-service dns && firewall-cmd --reload
  7. Now ensure the service will be available at boot and start it afterwards:
    systemctl enable unbound && systemctl start unbound
  8. To test if we can reach our Unbound DNS server and make queries, execute the following command from the same server running our Unbound DNS service locally, which should give back the IP address of www.packtpub.com :
    nslookup www.packtpub.com 127.0.0.1
  9. For a more detailed view of the request you can also run locally on the DNS server:
    unbound-host -d www.packtpub.com
  10. From any other client in the network (needs bind-utils installed), you can query any public domain name using our new DNS server as well. For example, if our DNS server has the IP 192.168.1.7:
    nslookup www.packtpub.com 192.168.1.7
  11. Finally, let us use our new nameserver on the server itself. To do this, open the following file with your favorite text editor after you have made a backup copy:
    cp /etc/resolv.conf /etc/resolv.conf.BAK; vi /etc/resolv.conf
  12. Remove all the current nameserver references and replace them with the following:
    nameserver 127.0.0.1

    Note
    If you have set some DNS server information in your network-scripts interface (for example, when configuring a static IP address), you will want to review the /etc/sysconfig/network-scripts/ifcfg-XXX file and modify the current DNS reference to read as DNS1=127.0.0.1 as well.

Configuring a forwarding only DNS server

Now after we have successfully configured our first caching BIND DNS server, here we will show you how to transform it into a forwarding DNS server which will reduce the total bandwidth for resolving hostnames in comparison to the caching-only solution:

  1. Open BIND’s main configuration file again:
    vi /etc/unbound/unbound.conf
  2. Add the following lines to the end of the file:
    forward-zone: name: "." forward-addr: 8.8.8.8
  3. Next, check the correctness of your new configuration file and restart the service:
    unbound-checkconf && systemctl restart unbound
  4. Finally, test your new forwarding DNS server using the tests from the preceding caching DNS server section.

How Does It Work?

In this process, we have installed a caching-only Unbound DNS server with the basic aim of improving the responsiveness of our overall network by caching the answers to any name-based queries. Using such a process will shorten the waiting time on any subsequent visit to the same location. It is a feature that is particularly useful in saving bandwidth if you happen to be managing a large, busy, or slow network. It does not have its own domain name resolution feature but uses its default root domain’s DNS servers in order to perform this task (to learn more about the root domain, see later). Also, as we have seen, you can easily transform your caching nameserver into a pure forwarding system as well. While a caching DNS server makes recursive requests to several associated DNS servers and constructs the complete name resolution result from those multiple requests, a forwarding DNS delegates the complete recursive DNS search to another resolving DNS server which executes the complete search instead. This saves even more bandwidth for our DNS server because only single network requests to communicate with the remote resolving server are made instead of multiple when using the caching-only DNS service.

So what did we learn from this experience?

We started this process by installing the necessary packages. This included the main DNS server program called Unbound and a reference to bind-utils, a small package that enables you to run many different DNS related network tasks, such as dig, nslookup, and host. The next step was to begin making the necessary configuration changes by editing Unbound’s main configuration after we made a simple backup of the original file. Since after installation the default DNS server is completely restricted to doing everything locally only, our main purpose was to adjust the server to make connections from the outside possible. We began this process by allowing the DNS server to listen to all the available network interfaces using the interface directive and afterwards defined who on the network was allowed to make requests to our DNS server by setting allow-query to our local network. This means we allowed anyone in our subnetwork to make DNS resolution requests to our server.

At this point we created the RSA keypair with the unbound-control-setup tool, which is needed for the unbound-checkconf command to work. The generated keys and certificate are important if we want to use Unbound’s DNS Security Extensions (DNSSEC) features which help protect DNS data by providing authentication of origin using digital signatures (configuring DNSSEC is outside the scope of this division. To learn more, consult the Unbound configuration manual: man unbound.conf). Afterwards, we used the unbound-checkconf command, which was necessary to confirm that Unbound’s configuration file was syntactically correct. If the output of the command is empty, there are no errors in the file. We then proceeded by adding the predefined dns firewalld service to our default firewall, thus allowing the other computer systems in our local network to access the DNS server using port 53. Finally, we activated Unbound at boot time and started the service.

Of course, to complete this process we then tested if our new DNS server worked as expected in resolving domain names to IP addresses. We ran a simple nslookup query locally on the server and also from the other computers in the same network to see if our new DNS service was reachable from the outside. When using nslookup without any additional parameters, the program will use the default DNS server resolver known to the system (on CentOS 7 this is defined in /etc/resolv.conf) to resolve our hostnames, so we added another parameter addressing our alternative DNS server we want to query instead (127.0.0.1). For successful testing, the output must contain the resolved IP address of the www.packtpub.com server. On the DNS server, you could also use the unbound-host -d command to get a more technical view of the DNS query within the Unbound service.

After we successfully finished these tests, we updated the current nameserver resolver information on our DNS server with our new DNS service running on localhost.

There's more…

Now we want to see how BIND will perform for caching DNS information. To do this, on your DNS server simply select a target website you have not visited before and use the dig command. For example:
dig www.wikipedia.org

Having run this test, you may see a query time that results in something like the following:
;; Query time: 223 msec

Now repeat this exercise by retesting the same URL. Depending on your networking environment, this may produce the following result:
;; Query time: 0 msec

Now do it again for another website. On every repeat of the preceding command, you should not only see a reduced query time but also experience a faster response time in delivering the output. This same result will be evident in the browser refresh rate, and as a result, we can say that this simple exercise has not only introduced you to Unbound but it will ultimately serve to improve the speed of your local network when surfing the World Wide Web.

 

Locking down remote access in CentOS and hardening SSH

In this process, we will learn how to provide additional security measures in order to harden the secure shell environment. The Secure Shell (SSH) is the basic toolkit that provides remote access to your server. The actual distance to the remote machine is negligible, but the shell environment enables you to perform maintenance, upgrades, the installation of packages and file transfers; you can also facilitate whatever action you need to carry out as the administrator in a secure environment. It is an important tool; as the gateway to your system, it is the purpose of this process to show you how to perform a few rudimentary configuration changes that will serve to protect your server from unwanted guests.

To Start With: What Do You Need?

To complete this process, you will require a minimal installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to download additional packages. It is assumed that your server already maintains at least one non-root-based administration account that can use the new features provided by this process.

The Process

The role of SSH will be vital if you are forced to administer your server from a remote location, and for this reason, it is essential that a few basic steps are provided to keep it safe:

  1. To begin, log in as root and create a backup of the original configuration file by typing the following command:
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
  2. Now, open the main sshd configuration file by typing the following:
    vi /etc/ssh/sshd_config
  3. We shall begin by adjusting the time allowed to complete the login process, so scroll down and find the line that reads:
    #LoginGraceTime 2m
  4. Uncomment this line and change its value to something more appropriate such as:
    LoginGraceTime 30
  5. Now, scroll down a couple of more lines and find the line that reads as follows:
    #PermitRootLogin yes
  6. Change this to the following:
    PermitRootLogin no
  7. Find the following line:
    X11Forwarding yes
  8. And change it to the following:
    X11Forwarding no
  9. Save and close the file before restarting the SSH service, as shown here:
    systemctl restart sshd
  10. At this stage, you may want to consider creating a new SSH session using the new settings before exiting the current session. This is to ensure that everything is working correctly and to avoid locking yourself out of the server accidentally. If you have difficulty starting a new SSH session, then simply return to the original session window and make the necessary adjustments (followed by a restart of the SSH service). However, if no difficulties have been encountered and you are on successful secondary login, you may close the original shell environment by typing exit.

    Note
    Remember, having followed this process you should now find that root access to the shell is denied and you must log in using a standard user account. Any further work requiring root privilege will require the su or sudo command, depending on your preferences. 

How Does It Work?

SSH is a vital service that enables you to access your server remotely. A server administrator cannot work without it. In this process, you were shown how to make that service a little more secure.

So, what did we learn from this experience?

We began the process by creating a backup copy of our original main sshd configuration file. The next step was to open and edit it. The configuration file for SSH maintains a long list of settings that is ideal for most internal needs, but for a server in a production environment, it is often advised that the default SSH configuration file will need changing to suit your particular needs. In this respect, the first step was to make a recommended change to the login grace time, LoginGraceTime 30. Instead of the default two minutes, the preceding value will allow only up to 30 seconds. This is the period of time where a user may be connected but will have not begun the authentication process; the lower the number, the fewer unauthenticated connections are kept open. Following this, we then removed the ability of a remote user to log in as the root user by using the PermitRootLogin no directive. In most cases, this is a must and a remote server should not allow a direct root login unless the server is in a controlled environment. The main reason behind this is to reduce the risk of getting hacked. The first thing every SSH hacker tries to crack is the password for the user root. If you disallow root login, an attacker needs to guess the user name as well, which is far more complex. The next setting simply disabled X11Forwarding. In situations like these, it is often a good idea to apply the phrase “if you do not use it, disable it”. To complete the process, you are required to restart the SSH server in order to allow the changes to take immediate effect and start a new SSH session with the intention of making sure that the modifications did indeed work as expected. No system is ever safe, but having done this you can now relax, safe in the knowledge of having made the SSH server a little bit safer.

There's more…

There are a few more topics to cover to make your SSH server even more secure: we should change the SSH port number and show you how to limit SSH access to specific system users.

Changing the SSH port number of your CentOS server

Port 22 is the default port used by all SSH servers, and changing the port number used can go a small way to increase the overall security of your server. Again, open the main SSH daemon configuration file, sshd_config. Now, scroll down and locate the following line that reads:

#Port 22

Remove the leading # character (uncomment) and change the port number to another value by replacing XXXX with an appropriate port number:

Port XXXX

You must ensure that the new port number is not already in use, and when complete, save the file and close it. It is important to remember that any changes made here are reflected in your firewall configuration. So, we need to open the new port in firewalld as well. Set the new port via the environment variable NEWPORT (replace XXXX with your new SSH port), then execute the following sed command to change the SSH firewalld service file and reload the firewalld daemon afterwards (for details, read the firewall process)
NEWPORT=XXXX
sed "s/port=\"22\"/port=\"$NEWPORT\"/g" /usr/lib/firewalld/services/ssh.xml > /etc/firewalld/services/ssh.xml firewall-cmd --reload

Also, we have to tell SELinux (see Working with SELinux to learn more about it) about the port change because it is restricted to port 22 by default. Make sure that the SELinux tools have been installed, then create a security label for our custom port, replacing XXXX with your changed port number:
yum install -y policycoreutils-python semanage port -a -t ssh_port_t -p tcp XXXX

Finally restart the sshd service to apply our port change.

Limiting SSH access by user or group in CentOS

By default, all valid users on the system are allowed to log in and enjoy the benefit of SSH. However, a more secure policy is to only allow a predetermined list of users or groups to log in. When henry, james, and helen represent valid SSH users on the system, in the sshd_config add this line to read as follows:

AllowUsers henry james helen

Alternatively, you can use the following method to enable any user that is a member of a valid administration group to log in. When admin represents a valid SSH group on the system, add this line to read as follows:

AllowGroups admin

When you have finished, save and close the file before restarting the SSH service.

 

CentOS backups and taking snapshots

In this process, we will show you how to do data backups, on a regular basis, that will take snapshots of some of your system’s directory using the crond daemon. This will run the rsync program at regular intervals to implement a fully automated backup solution.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges and a console-based text editor of your choice. It is also advantageous if you have read the Synchronizing files and doing more with rsync and Scheduling tasks with cron process to get a deeper understanding of used commands.

The Process

It’s important to install the rsync program on your server before proceeding with this process.

  1. First, log in as root and create a directory where our backups will land:
    mkdir /backups
  2. Now, we will create the following shell script file and open it for editing:
    mkdir ~/bin;vi ~/bin/mybackup.sh
  3. Put in the following content, replacing /backups in the environment variable DEST and SOURCE with the one you would like to backup as well as the recipient’s EMAIL:
    #!/bin/bash
    SBJT="cron backup report for `hostname -s` from $(date +%Y%m%d:%T)"
    FROM=root@domain
    EMAIL=johndoe@internet.com
    SOURCE=/root
    DEST=/backups
    LFPATH=/tmp
    LF=$LFPATH/$(date +%Y%m%d_%T)_logfile.log
    rsync --delete --log-file=$LF -avzq $SOURCE $DEST
    (echo "$SBJT"; echo; cat $LF ) | sendmail -f $FROM -t $EMAIL
  4. Make the script executable:
    chmod a+x /root/bin/mybackup.sh
  5. Now, open crontab using:
    crontab -e
  6. Next, create the following entry by adding the following line to the end of the document, then save and close it:
    30 20 * * * /root/bin/mybackup.sh

How it works…

In this process, we have created a fully automatic backup solution for a single system directory, which will create a snapshot of the files at a certain time point. At the time the backup process is complete you will receive an e-mail informing you that a backup has been made with a brief review of the actions taken.

So what did we learn from this experience?

We started this process by creating a directory where our backup will be placed. Next we created the actual script and filled it with some commands. Line 1 defines the file as a bash script, lines 2-6 are variables you can modify and customize to fit your own needs. lines 7-8 create a path and name for the log file based on the date, and line 9 calls rsync which will synchronize all our source files to the target directory /backups. It uses a special --log-file parameter which writes all output to the given file. The final line (10) sends the content of this log file to an email address.

Remember, you should customize the values as required (that is, change the e-mail address used, select a source directory, and choose a destination directory, and so on.). Before it can be used and executed by cron, we made it executable. Finally, we added this script as a cron job to run on a daily schedule at 20:30 hours. However, as this may be some hours away, if you would like to test your script right now, you can execute it on the command line using the following:
/root/bin/mybackup.sh

In conclusion, it will go without saying that a backup should be located on an external drive or on a separate partition, but having completed this introduction I think you will agree that rsync is ideally positioned in such a way that it will enable any server administrator to develop their own policy with regard to maintaining an effective backup of important data.

 

CentOS text files navigation with less

No doubt you will frequently use programs and tools that use the program less or less-like navigation to view and read file content or display output. At first, the control can seem a bit unintuitive. Here, in this process, we will show you the basics of how to navigate through a file using fewer controls.

To Start With: What Do You Need?

In order to implement this process, you will require a working installation of the CentOS 7 operating system with root privileges.

The Process

  1. To begin, log in as root and type the following command to open a program that uses less for navigation:
    man man
  2. To navigate, press the up and down key to scroll up and down one line at a time, the spacebar to scroll down a page, and the b key to scroll up a page. You can search within the text using the forward slash key, /, followed by the search term, then press Return to search. Press n to jump to the next search result. Press the q key to exit.        

How Does It Work?

Here, in this short process, we have shown you the very basics of less navigation, which is essential for reading man pages and is used by a lot of other programs throughout this book to display text. We only showed you the basic commands and there is much more to learn. Please read the less manual to find out more on man less command.

 

Setting up NRPE on remote client hosts

The Nagios Remote Plugin Executor (NRPE) is a system daemon that uses a special client-server protocol and should be installed on all client hosts that you want to monitor via your Nagios server remotely. It allows the central Nagios server to trigger any Nagios checks on these client hosts securely and with low overhead. Here, we will show you how to set up and configure any CentOS 7 client to use NRPE; if you’ve got more than one computer in your network that you want to monitor, you need to apply this process for every instance.

To Start With: What Do You Need?

To complete this process, you will require a computer other than your Nagios server with an installation of the CentOS 7 operating system and root privileges, which you want to monitor, and which needs a console-based text editor of your choice installed on it, along with a connection to the Internet in order to facilitate the download of additional packages. This computer needs to have access to our Nagios server over the network. In our example, the Nagios server has the IP address 192.168.1.7, and our client system will have the IP address 192.168.1.8.

The Process

  1. Log in as root on your CentOS 7 client system and install all Nagios plugins as well as NRPE on it:
    yum install epel-release;yum install nrpe nagios-plugins-all nagiosplugins-nrpe
  2. Afterwards, open the main NRPE config file (after making a backup first):
    cp /etc/nagios/nrpe.cfg /etc/nagios/nrpe.cfg.BAK && vi /etc/nagios/nrpe.cfg
  3. Find the line that starts with allowed_hosts, and add the IP address of your Nagios server separated by a comma so that we can communicate with it (in our example ,192.168.1.7, so change it accordingly); it should read as follows:
    allowed_hosts=127.0.0.1,192.168.1.7
  4. Save and close the file, then enable NRPE at boot and start it:
    systemctl enable nrpe && systemctl start nrpe
  5. Then enable the NRPE port in firewalld. To do this, create a new firewalld service file for NRPE:
    sed 's/80/5666/g' /usr/lib/firewalld/services/http.xml | sed 's/WWW
    (HTTP)/Nagios NRPE/g' | sed 's/.*\/description>//g' >
    /etc/firewalld/services/nrpe.xml
    firewall-cmd --reload
    firewall-cmd --permanent --add-service=nrpe; firewall-cmd --reload
  6. Finally, test the NRPE connection. To do this, log in as root on your Nagios server (for example, at 192.168.1.7) and execute the following command to check NRPE on our client (192.168.1.8):
    /usr/lib64/nagios/plugins/check_nrpe -H 192.168.1.8 -c check_load
  7. If the output prints out an OK -load average message with some numbers, you have successfully configured NRPE on the client!

How Does It Work?

Here in this process, we have shown you how to install NRPE on your CentOS 7 clients that you want to monitor with your Nagios servers. If you want to monitor other Linux systems running other distributions such as Debian or BSD, you should be able to find appropriate packages using their own package managers or compile NRPE from source. Besides the NRPE package, we also installed all the Nagios plugins on this machine since NRPE is only the daemon for running monitoring commands on client computers, but it does not include them. After installation, NRPE is listening only on localhost (127.0.0.1) connections by default, so we then had to change this to also listen to connections from our Nagios server, which runs with the IP 192.168.1.7, using the allowed_hosts directive in the main NRPE configuration file. The NRPE port 5666 is needed for incoming connections from the Nagios server, so we also had to open it in the firewall. Since no firewalld rule is available for it by default, we created our own new service file and added it to the current firewalld configuration. Afterwards, we could test our NRPE installation from our Nagios server by running a check_nrpe command using the client’s IP address and a random check command (check_load returns the system’s load).

 

Installing Apache and serving web pages in CentOS

In this process, we will learn how to install and configure the Apache web server to enable the serving of static web pages. Apache is one of the world’s most popular open source web servers. It runs as the backend for over half of all the Internet’s web sites and can be used to serve both static and dynamic web pages. Commonly referred to as httpd, it supports an extensive range of features. It is the purpose of this process to show you how easily it can be installed using the YUM package manager so that you can maintain your server with the latest security updates. Apache 2.4 is available on CentOS 7.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to download additional packages. It is expected that your server will be using a static IP address and a hostname.

The Process

Apache is not installed by default and for this reason, we will begin by installing the necessary packages using the YUM package manager.

  1. To begin, log in as root and type the following command:
    yum install httpd
  2. Create a home page by typing:
    vi /var/www/html/index.html
  3. Now add the required HTML. You can use the following code as a starting point but it is expected that you will want to modify it to suit your own needs:


    Welcome to my new web server

    Welcome to my new web server

    Lorem ipsum dolor sit amet, adipiscing elit.


  4. You can now remove the Apache 2 test page with the following command:
    rm -f /etc/httpd/conf.d/welcome.conf
  5. Having completed these steps, we will now consider the need to configure the httpd service for basic usage. To do this, open the httpd configuration file in your favorite text editor by typing (after you have made a backup of the file):
    cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.BAK vi /etc/httpd/conf/httpd.conf
  6. Now scroll down to find the line ServerAdmin root@localhost. The traditional approach to setting this value is based on the use of the webmaster identity, so simply modify the e-mail address to reflect something more relevant to your own needs. For example, if your server’s domain name was www.centos7.home then your entry will look similar to this:
    ServerAdmin webmaster@centos7.home
  7. Now scroll down a few more lines to find the ServerName directive as follows: #ServerName www.example.com:80. Uncomment this line (which means remove the leading # sign at its beginning) and replace the value www.example.com with something more appropriate to your own needs. For example, if your server’s domain name was www.centos7.home then your entry will look as follows:
    ServerName www.centos7.home:80
  8.  Next, we will expand the DirectoryIndex directive a bit more. Find the line DirectoryIndex index.html, which is part of the block, then change it to:
    DirectoryIndex index.html index.htm
  9. Save and close the file, and then type the following command to test the config file:
    apachectl configtest
  10. Next, let’s configure our web server’s firewall by allowing incoming http connections (this defaults to port 80) to the server:
    firewall-cmd --permanent --add-service http && firewall-cmd --reload
  11. Now proceed to set the httpd service to start at boot and start the service:
    systemctl enable httpd && systemctl start httpd
  12. You can now test httpd from any computer in the same network as your web server (both systems should be able to see and ping each other), pointing your browser at the following URL by replacing XXX.XXX.XXX.XXX with the IP address of your server in order to see our own custom Apache test page we created:
    http://XXX.XXX.XXX.XXX.
  13. Alternatively, if you don’t have a web browser, you can check if Apache is up and running using curl by fetching our test page on any computer in your network:
    curl http://XXX.XXX.XXX

How Does It Work?

Apache is a software package that enables you to publish and serve web pages, and is more commonly known as httpd, Apache2 or simply Apache. It was the purpose of this process to show you how easily CentOS enables you to get started with your very first website.

So what did we learn from this experience?

We began the process by installing Apache via the YUM package manager and the package named httpd. Having done this, we learned that on CentOS 7 the default location to serve static HTML is /var/www/html so our first task was to create a suitable home page, which we put in /var/www/html/index.html. Here we used a basic HTML template to get you started and it is expected that you would like to customize the look and feel of this page yourself. Following this, we then removed the default Apache 2 welcome page found in /etc/httpd/conf.d/welcome.conf. Following this, the next stage was to open the httpd.conf configuration file in our favorite text editor after making a backup of it so we could revert our changes if any problems occurred. First we defined the server’s e-mail address and the server name, which often appear in the error messages on the server-generated web pages; for this reason it should reflect your domain name. Next, we adjusted the DirectoryIndex directive, which defines which files will be sent first to the browser if a directory is requested. Often people request not a specific web page but a directory instead. For example, if you browse to www.example.com, you request a directory, while www.example.com/welcome.html is a specific web page. By default Apache sends the index.html in the requested directory but we expanded this since a lot of websites use the .htm extension instead. Finally, we saved and closed the httpd configuration file in the usual way before proceeding to check if the Apache configuration file contained any errors by using the apachectl configtest command. This should print out a Syntax OK message so we could enable the httpd service to start at boot time. We had to open the standard HTTP port 80 in our firewalld to allow incoming HTTP requests to the server, and finally we then started the httpd service. Remember, you can also always reload Apache’s configuration file if it has been changed without fully restarting the service, by using: systemctl reload httpd. Having completed these steps, it was simply a matter of opening your browser from another computer in the same network and electing a method of viewing our new Apache start page. You can use your server’s IP address (for example, http://192.168.1.100), while those with hostname support can type the hostname (for example, http://www.centos7.home) instead. Apache’s access and error log files can be found in /var/log/httpd. To get a live view of who is currently accessing your web server, open /var/log/httpd/access_log; to see all the errors, type /var/log/httpd/error_log.

Apache is a big subject and we cannot cover every nuance, but over the coming processes, we will continue to expose additional functionalities that will enable you to build a web server of choice.

 

Troubleshooting CentOS users and file transfers

Analyzing log files is the most important technique for troubleshooting all kinds of problems or improving services on Linux. In this process, you will learn how to configure and enable vsftpd’s extensive logging features in order to help system administrators when problems arise, or simply to monitor usage with this service.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges and a console-based text editor of your choice. It is expected that your server will be using a static IP address and that vsftpd is already installed with a chroot jail and is currently running.

The Process

  1. To do this, log in as root and type the following command to open the main configuration file in your favorite text editor:
    vi /etc/vsftpd/vsftpd.conf
  2. Now, add the following lines to the end of the configuration file to enable verbose logging features:
    dual_log_enable=YES log_ftp_protocol=YES
  3. Finally, restart the vsftpd daemon to apply the changes:
    systemctl restart vsftpd

How Does It Work?

In this process, we have shown how to enable two separate logging mechanism: first, the xferlog log file that will log detailed information about user uploads and downloads, then the vsftpd log file that contains every FTP protocol transaction between the client and the server outputting the most detailed logging information possible for vsftpd.

So what did we learn from this experience?

In this process, we opened the main vsftpd configuration file and added two directives to the end of the file. First, dual_log_enable will make sure both the xferlog and vsftpd log files will be used for logging. Afterwards, we increased the verbosity of the vsftpd log file by enabling log_ftp_protocol.

After restarting the service, the two log files, /var/log/xferlog and /var/log/vsftdp.log, will be created and filled with useful FTP activity information. Now, before we open the files, let’s create some FTP user activity. Log in with any FTP user on the server using the ftp command-line tool and issue the following FTP command at the ftp> prompt to upload a random file from the client to the server:
put ~/.bash_profile bash_profile_test

Now, back on the server, inspect the /var/log/xferlog file to see detailed information about the uploaded file and open /var/log/vsftpd.log for all other user activities (such as login time or other FTP commands that users issued).

Please note that both the log files only keep track of user and FTP activity and are not meant to debug problems with the vsftpd service such as configuration file errors. Use the systemctl status vsftpd -l or journalctl -xn, to debug general problems with the service.

 

Extending the capacity of the CentOS filesystem

CentOS 7 uses the Logical Volume Manager (LVM) to organize the structure and available capacity of your partitions. It is a very dynamic and flexible system that can be extended or rearranged over time, and which is essential in today’s most demanding and ever-changing environments. At the moment, buzzwords such as big data or cloud computing can be heard everywhere. Since massive amounts of data get produced all the time, storage requirements and disk space have to grow at the same steady pace. In this process, you will learn how to work with the LVM system and how to extend your physical drives, and also how to shrink and extend the capacity of your filesystems.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges. We will use virtual block devices instead of real disk devices to show you from scratch how to set up a LVM first, and afterward how to work with it. Please read the Creating a virtual block device process and create three 1 gigabyte virtual block devices with the GPT partition table, which will be labeled as /dev/loop0, /dev/loop1, and /dev/loop2 in this example.

Again, feel free to use real disk devices if you feel ready for it.

The Process

First, we will start by creating an LVM test environment similar to the standard CentOS 7 LVM structure, which is set up during the installation of every server system:

  1. First, let’s log in as root and show information about our virtual block devices:
    lsblk -io NAME,SIZE
  2. Next, create new partitions spanning the whole disk on each of the three virtual block devices (without a filesystem label):
    parted -a optimal /dev/loop0 mkpart primary 2048KiB 100%
    parted -a optimal /dev/loop1 mkpart primary 2048KiB 100%
    parted -a optimal /dev/loop2 mkpart primary 2048KiB 100%
  3. Now, let’s create LVM physical volumes on each of the loop devices (type yes to remove the gpt label):
    pvcreate /dev/loop0p1 pvcreate /dev/loop1p1 pvcreate /dev/loop2p1
  4. Next, show information about our physical volumes:
    pvdisplay
  5. Next, we will create a new LVM volume group on our first physical volume:
    vgcreate myVG1 /dev/loop0p1
  6. Now, show information about the created group:
    vgdisplay myVG1
  7. Afterward, let’s create some logical volumes on our first volume group, which will be treated as virtual partitions in our Linux system:
    lvcreate -L 10m -n swap myVG1
    lvcreate -L 100m -n home myVG1
    lvcreate -L 400m -n root myVG1
  8. Next, show information about the logical volumes:
    lvdisplay myVG1
  9. Now, display how much free space our underlying volume group has left, which becomes important if you want to expand some logical volumes (see the section Free PE / Size in the output):
    vgdisplay myVG1
  10. Afterward, let’s create the filesystems on those new logical volumes:
    mkswap /dev/myVG1/swap
    mkfs.xfs /dev/myVG1/home
    mkfs.xfs /dev/myVG1/root
  11. Now, after we have created our test LVM system (which is very similar to the real CentOS LVM standard layout, but with smaller sizes), let’s start working with it.
  12. First, let’s shrink the root partition, which is currently 400 megabytes (M) in size, by 200 megabytes, and afterward, let’s increase the home partition by 500 megabytes (confirm the possible data loss):
    lvresize -L -200m /dev/myVG1/root
    lvresize -L +500m /dev/myVG1/homE
  13. Use vgdisplay myVG1 again to see how the volume group’s free space changes by running the previous commands (see Free PE / Size).
  14. Now, let’s expand the XFS filesystem on the grown logical volume:
    mkdir /media/home-test;mount /dev/myVG1/home /media/home-test xfs_growfs /dev/myVG1/home
    Note
    It is very important not to use resize2fs for growing XFS filesystems, because it’s incompatible and can corrupt them.
  15. Now, let’s say that after some time your data has grown again, and you need the home partition to be 1.5 gigabytes (G), but you only have 184.00 MiB left on the underlying volume group. First, we need to add our two prepared physical volumes from the beginning of this process to our volume group:
    vgextend myVG1 /dev/loop1p1 /dev/loop2p1 vgdisplay myVG1
  16. Afterward, we have enough free space in our volume group (see Free PE / Size) to expand our home logical volume (the volume must stay mounted):
    lvresize -L +1500m /dev/myVG1/home xfs_growfs /dev/myVG1/home

How Does It Work?

Here, in this process, we have shown you how to work with the LVM for XFS partitions. It has been developed with the purpose of managing disk space on several hard disks dynamically. You can easily merge many physical hard disks together to make them appear as a single virtual hard disk to the system. This makes it a flexible and very scalable system in comparison to working with plain old static partitions. Traditional partitions are bound to, and cannot grow over, the total disk capacity they reside on, and their static partition layout cannot be changed easily. Also, we have introduced some important LVM technical terms that provide different abstraction layers to a hard disk, and which will be explained in this section so as to understand the concepts behind it: physical volume (pv), volume group (vg), and logical volume (lv).

So, what did we learn from this experience?

We started this process by creating three virtual block devices of 1 gigabyte (G) each and then one partition spanning the whole device on each of them. Afterwards, we defined these single-partition devices as physical volumes (pv) using the pvcreate command. A pv is an LVM term that defines a storage unit in the LVM world. It must be defined on a partition, full drive, or loop device. A pv is just an abstraction of all the space available in the surrounding partition so that we can work with it on an LVM basis. Next, we created a volume group (vg) with the vgcreate command, where we also had to define a volume group name of our choice and put the first pv in it as a basic storage volume. As you can see, a vg is a container for at least one pv (we add more pv’s later). Adding or removing pv’s to or from a vg is the heart of the whole scalability concept of the LVM system. The pv’s don’t have to be all the same size, and it is possible to grow your vg over time by adding dozens of new physical drives all defined as pv. You can have more than one vg on your system, and you can identify them by the unique names you are giving to them. So, in summary, to extend the space of your vg, you have to create pv’s out of physical drives, which you can then add to.

Finally, we created logical volumes (lv) on our vg, which can be seen and used like real physical partitions within a vg. Here, we created three lv’s using the lvcreate command, by which we need to define the name of the vg (remember, there can be more than one vg on your system) that we want to put our target lv on, along with the size of the volume, as well as a name for it as the last parameter. You can add multiple lvs into a vg and you don’t need to use the whole allocated space from the underlying free space of the vg. You can be very flexible with it. The best part is that your decision about your volumes’ size and layout doesn’t have to be fixed for all time; you can change them anytime later. It is a very dynamic system that can be extended and shrunk, deleted and created, without having to unmount the volume beforehand. But you have to remember that all lvs are bound to a vg, and it is not possible to create them without it or outside its spacial boundaries. If you need to extend an lv’s space over the borders of the underlying vg, you have to extend the vg, as show in this process.

Note
As you may have seen, for every LVM term, there is a “display” and “create” command, so it’s easy to remember: pvdisplay, vgdisplay, lvdisplay, pvcreate, vgcreate, lvcreate.

After you have successfully created your lv’s, you can work with them as you would with every other block device partition on your system. The only difference is that they reside in special device folders: /dev// or /dev/mapper//. For example, the home volume created in this example has the name /dev/myVG1/home. Finally, in order to use them as normal mount points, we created some test filesystems on them.

In the second part of this , we showed you how to extend our vg and how to shrink and expand our lv’s test system.

We started by using the vgdisplay myVG1 command to show the currently available space on the vg. In the command output, we saw that our current volume group has a total of 996M (VG Size), the allocated size from our lv’s (swap, home, root) is 512M (Alloc PE / Size), and the free size is 484M (Free PE /Size). Next, we used the lvresize command to shrink and expand the logical volume’s root and home. The -L parameter sets the new size of the volume, and with the + or -sign, the value is added to or subtracted from the actual size of the logical volume. Without it, the value is taken as an absolute one. Remember that we could only increase the home partition because the current volume layout does not occupy the complete vg’s total space. After resizing, if we use the vgdisplay command again, we see that we now occupy more space in the vg; its free size has been decreased to 184M. Since we expanded the home volume from 100M to 500M in total, we need to remember to expand its XFS filesystem too, since expanding a volume does not automatically expand its filesystem. Therefore, 400M of the current volume are unallocated without any filesystem information. We used the command, xfs_growfs, which will, without defining a limit parameter, use the complete unallocated area for the XFS filesystem. If you want to resize any other filesystem type, such as ext4, you would use the resize2fs command instead.

Finally, we wanted to grow the home volume by 1.5G, but we only have 184M left on our vg to expand. This is where LVM really shines because we can just add some more physical volumes to it (in the real world, you would just install new hard disks in your server and use them as pvs). We showed you how to extend the capacity of your vg by adding two 1G-sized pvs to it using the vgextend command. Afterward, we used vgdisplay to see that our vg has now grown to 3G in total size, so finally, we could extend our home lv as it would now fit into it. As a last step, we expanded the XFS file system once again to fill up the whole 2G home volume size.

Please remember, all the time, that if you use vg’s with several physical hard disks, your data will be distributed among these. An LVM is not a RAID system and has no redundancy, so if one hard disk fails, your complete vg will fail too and your data will be lost! In order to deal with this problem, a proposed solution could be to use a physical RAID system for your hard disks and create an LVM on top of that.

 

Synchronizing files in CentOS and doing more with rsync

rsync is a program that can be used to synchronize files and directories across a variety of local and remote locations. It can interact with multiple operating systems, work over SSH, provide incremental backups, execute commands on a remote machine, and replace the need for the cp and scp commands. The rsync program is an invaluable asset for any system administrator who intends to run a server or manage a network of computers, as it not only simplifies the process of making backups in general, but it can be used to action a complete backup solution. For this reason, it is the purpose of this process to offer a suitable starting point for a small utility that will quickly become your trusted friend.

To Start With: What Do You Need?

In a bid to complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to facilitate the download of additional packages.

The Process

During the course of this process, it will be assumed that you know the location of the source files and directories that you wish to synchronize and that a suitable destination is available:

  1. To begin this process, log in as root and install rsync by typing:
    yum install rsync
  2. Now, create a target directory for our synchronization (change the folder name appropriately):
    mkdir ~/sync-target
  3. To begin the synchronization process, simply repeat the following command by modifying the value used for /path/to/source/files/ with something more applicable to your needs:
    rsync -avz --delete /path/to/source/files/ ~/sync-target
  4. Having used the Return key to confirm the preceding instruction, your system will now respond with a live report of what is being copied. When this process has finished, you can then compare both directories to see that the contents are exactly the same. To do this, use the diff command (if both are the same, no output will be written):
    diff -r /path/to/source/files/ ~/sync-target

How it works…

In this process, we considered the use of rsync through the command line. Of course, this is only one of the many ways that this tool can be used, but by using this approach we were able to explore a handful of the features provided by this very valuable utility.

So, what did we learn from this experience?

Rsync is not intended to be complicated. It is a fast and efficient file synchronization tool that is designed to be versatile by giving you complete access to an array of features on the command line. It can be used to maintain an exact copy (or mirror) of the source directory on the same machine or on a completely different system, and it does this by copying all the files once and then only updating the files that have changed the next time you run it. This can save tremendous bandwidth and should be your primary tool when copying data over the network. The use of the phrase, --delete, is important, as it instructs rsync to delete files on the target that do not exist in the source, while the chosen flags imply that rsync should use -an archive mode in order to recursively copy files and directories while keeping all permissions and time-based information; –v)verbosity mode so you can see what is happening; and –z to compress the data during the file transfer in order to save bandwidth and reduce the amount of time required to complete the entire process.

As you can see, rsync is very flexible and has many options that go beyond the purpose of this process, but if you want to exclude certain files you could always extend the original instruction by invoking the --exclude flag. By doing this, you tell rsync to back up an entire directory but ensure that it does not include a predefined pattern of files and folders. For example, if you are copying files from your server to a USB device and you do not want to include large files (such as a .iso image) or ZIP files, then your command may look similar to this:
rsync --delete -avz --exclude="*.zip" --exclude="*.iso" /path/to/source/ /path/to/external/disk/

On a final note, there is the subject of verbosity. Verbosity is very useful, but a tendency to use bytes as its primary unit of measurement can be a source of confusion. So, in order to change this, you can invoke rsync with the –h (or human readable) option, as shown next:
rsync -avzh --exclude="home/path/to/file.txt" /home/ /path/to/external/disk/

 

 

 

Updating the CentOS installation and enhancing the minimal install

This process will rightly explain you the way to enhance the minimal install along with additional tools. This will provide you with various administrative and developmental options that might stand extremely vital for your server to work in its lifetime. 

However, this minimal install is said to the most efficient and the most friendly way for installing a server, but implementing this minimal server does definitely require some extra features so, in order to make it much compelling. We know the importance of administrative and developmental tools for the smooth running of your server and this process how to install these extra packages

To Start With: What Do You Need?

  1. A minimal installation of CentOS 6 operating system added with its root privileges. 
  2. A high-speed Internet connection for smooth downloading of additional packages.

The Process:

  1. The primary task is to update the system.
    So login as root and type,
    yum -y update
  2. Now, CentOS will look for relevant updates and if updates are available, they will get installed. Further, after completion of the update, you should reboot your computer
    You should type,
    reboot
  3. After the server reboots and finally returns to the login screen, we will complete by enhancing the current installation along with a series of package groups. So, login as root and type,
    yum –y groupinstall "Base" "Development Libraries" "DevelopmentTools"
  4. After the installation is complete, you are required to reboot the server by typing, 
    reboot

How Does It Work?

This process works to increase the minimal installation of the CentOS operating system. You also got introduced to Yum Package Manager. 

We initiated by updating the system so that we make sure that the system is up to date. Further, during this time, it is best to reboot the server and this is solely because to take advantage of a new kernel or rather any other revised security updates. We also came to know about how to add a new series of package groups that would stand highly essential for use in the future. 

 

 

Installing and configuring Nagios Core in CentOS

In this process, we will learn how to install Nagios Core version 4, an open-source network monitoring system that checks whether hosts and services are working and notifies users when problems occur or services become unavailable. Nagios provides solutions to monitor your complete IT infrastructure and is designed with an architecture that is highly extendable and customizable and goes far beyond simple bash scripts to monitor your services. (Refer to the Monitoring important server infrastructure process.)

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to facilitate the download of additional packages. Nagios Core 4 is not available in the official sources but from the EPEL repository; make sure to have installed it before (refer to the Using a third-party repository process in, Managing Packages with YUM). For the Nagios web frontend, you need a running Apache2 web server as well as PHP (refer to the processes from, Providing Web Services) installed on your Nagios server. In our example, the Nagios server has the IP address 192.168.1.7, and it will be able to monitor all IT infrastructure in the complete 192.168.1.0/24 subnet.

The Process

Nagios Core 4 is not available by default, so let’s begin by installing all the required packages:

  1. To do so, log in as root and type the following command:
    yum install nagios nagios-plugins-all nagios-plugins-nrpe nrpe
  2. First, create a new user account called nagiosadmin, which is needed for authentication to the web frontend (enter a secure password when prompted), then reload the Apache configuration:
    htpasswd /etc/nagios/passwd nagiosadmin && systemctl reload httpd
  3. Now, add an e-mail address for the nagiosadmin web user to the Nagios configuration, open the following file, and search and replace the string, nagios@localhost, with an appropriate e-mail address you want to use here (it can be a domain-wide or external e-mail address):
    vi /etc/nagios/objects/contacts.cfg
  4. Now, we need to adjust the main configuration file to activate /etc/nagios/servers as our server’s definition configuration directory, where we will put all our server config files later, but first, make a backup:
    cp /etc/nagios/nagios.cfg /etc/nagios/nagios.cfg.BAK
    sed -i -r 's/^#cfg_dir=(.+)servers$/cfg_dir=\1servers/g'
    /etc/nagios/nagios.cfg
  5. We will have to create the server’s config directory that we just defined in the last step:
    mkdir /etc/nagios/servers
    chown nagios: /etc/nagios/servers;chmod 750 /etc/nagios/servers
  6. Afterwards, to check the correctness of the nagios.cfg syntax, run the following:
    nagios -v /etc/nagios/nagios.cfg
  7. Finally, enable the Nagios daemon on boot and start the service:
    systemctl enable nagios && systemctl start nagios

How Does It Work?

Here in this process, we have shown you how to install the Nagios Core v4 server (Core is the open-source version of the Nagios project) on CentOS 7. Besides the main Nagios package, we also required the NRPE package and all the Nagios plugins on our Nagios server. After installing, we created a user account, which is able to log in to the web frontend, and we set the e-mail address for this user in the main Nagios configuration file. Next, we activated the /etc/nagios/servers directory using sed, where all our server definition files will be put in a later process, here. Then, we created the directory and changed permissions to the Nagios user. To test the Nagios server installation, open a web browser on a computer in the same subnet 192.168.1.0/24 as your Nagios server, open the following URL (in our example, the Nagios server has the IP 192.168.1.7, so change accordingly), and then log in with your newly created nagiosadmin user account to http://192.168.1.7/nagios.

 

Using Fetchmail in CentOS

So far in this segment, we have shown you two different forms of MTA. First, we introduced you to the Postfix MTA, which is a transport agent used for routing e-mails from a mail client to or between mail servers and delivering them to the local mailboxes on the mail server using the SMTP protocol. Then we showed you another type of MTA which sometimes called an access agent and which the Dovecot program can be used for. This delivers mails from the local Postfix mailboxes to any remote mail client programs using the POP3 or IMAP protocol. Now we will introduce you to a third type of MTA, which can be termed a retrieval agent, and explain what we will use the program Fetchmail for. Nowadays, almost everybody has more than one e-mail account, from one or more different mail providers, which can be hard to maintain if you need to login to all those different webmail sites or use different accounts in your mail program. This is where Fetchmail comes into play. It is a program, running on the same server as your domain-wide Postfix mail server and which can retrieve all your different e-mails from all your different mail providers and pass them into the local user mailboxes of your Postfix MTA. Once they are stored in their appropriate place, users can access all these mails in the usual way provided by the access agent Dovecot over POP3 or IMAP. Here in this process we will show you how to install and integrate Fetchmail into your server running the Postfix MTA.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to download additional packages. It is assumed that you are working through this chapter division process by process in the order that they appear and for this reason, it is expected that Postfix has been configured as a domain-wide MTA and Dovecot has been installed to provide a POP3/IMAP mail access service. In order to test Fetchmail in this process, we also need to have registered some external e-mail addresses: you need the name of the external e-mail server address and the port of your e-mail provider, as well as your user login credentials at hand. Often you can find this information from your mail provider’s Frequently Asked Questions (FAQ) section on their webpage. Also, for some e-mail addresses, you need to first enable POP3 or IMAP in your e-mail settings before you can use Fetchmail.

The Process

Fetchmail is not installed by default and for this reason we must begin by installing the necessary packages. Perform the following steps:

  1. To begin, log in your mail server running your Postfix server and type:
    yum install fetchmail
  2. Once installed, we will log into a system’s user account for which we want to enable Fetchmail to download external mail from an external mail provider into his local mailbox, in our example it will be the system user john: su -john. Now let’s configure Fetchmail with an external e-mail address. If your e-mail provider is called mailhost.com and it runs a POP3 server at pop.mailhost.com and IMAP on imap.mailhost.com with the username , here (please substitute your own values) is an example command line to test connecting and fetching mails from this provider:
    fetchmail pop.mailhost.com -p pop3 -u -k -v
  3. If you want to use IMAP with the same provider instead:
    fetchmail imap.mailhost.com -p IMAP -u -v
  4. If the Fetchmail command was successful, all new messages will be downloaded from the server into your local mailbox in your user account.

How Does It Work?

Here in this process, we showed you how to install and test Fetchmail, which provides automated mail retrieval capabilities for any user account having a local mailbox on our Postfix server. As a result, for a client connecting to the mail server using POP3 or IMAP, the mails fetched this way look like normal incoming e-mails. Fetchmail is often used to combine and bundle all your different mail accounts into one single account, but you can also use it if your mail provider does not have a good virus or spam filter. Here you download the mails from your host’s e-mail server, then process the mails using tools such as SpamAssassin or ClamAV before sending mails to your clients.

So what did we learn from this experience?

We began this process by installing the YUM package for Fetchmail. As we wanted to set up Fetchmail for a system user’s mailbox called john, next we logged in as this user. Afterwards, we tested the Fetchmail program by running a simple command line to fetch mail from a single mail provider. As said before, for a successful login to your external mail provider, you need to know the exact login information (server address, port, username, and password, as well as the type of protocol) of the server before you can use Fetchmail.

Remember that, while some e-mail providers let the user decide if he wants to connect securely using SSL or not, some hosters such as gmail.com only allow secure connections. This means that the example command shown here in this process is likely to fail on every major e-mail provider if they don’t support POP3/IMAP access without SSL connections. Proceed to the next section in order to learn how to use Fetchmail with SSL POP3/IMAP encryption.

You should always prefer SSL encryption if your mail provider offers both. Also, some providers such as gmail.com only let the user use their services via webmail and disable POP3/IMAP service features by default; you need to enable them in your account’s settings on your provider’s website (see later).

We specified with the -p parameter which mail protocol to use with the fetchmail command. With the -u parameter, we specified the user identification to be used when logging in to the mailserver, which is completely dependent on our e-mail provider. For POP3, we applied the -k flag to ensure that the e-mails only get fetched from the server but never deleted (which is the default when using the POP3 protocol). Finally, we used -v to make the output more verbose and give us more information for our simple test. If your e-mail provider supports SSL, you also need to add a -ssl flag to the Fetchmail command as well as the root certificate of the mail server (see the next section for more information). If you run the previous command, Fetchmail will immediately start asking the mail server for any mail in the inbox on the server and download anything to your user’s local mailbox.

There's more…

In this section, we will show you how to configure Fetchmail to download all your e-mails from some real-life mail providers using POP3S, IMAPS, and the POP3 and IMAP protocols to your local mailbox on the Postfix server using a configuration file. Finally, we will show you how to automate the Fetchmail process.

Configuring Fetchmail with gmail.com and outlook.com e-mail accounts

Here we will configure the different external mail accounts which Fetchmail will download from: the popular gmail.com and outlook.com e-mail providers and a hypothetical one at my-email-server.com.

As we learned in the main process that Fetchmail processes configuration options on the command line by default, this should not be your preferred way of using Fetchmail to download your mail from different mail accounts automatically. Normally Fetchmail should be running as a service in daemon mode in the background at boot time or with a cron job and polls a list of mail servers defined in a special configuration file at specific time intervals. With this, you can conveniently configure multiple mail servers and a long list of other options.

Note
At the time of writing this book, for gmail.com to work with Fetchmail you need to login to the gmail.com website with your user account and first enable IMAP by going to your accounts settings in Forwarding and POP/IMAP. Also, enable Allow less secure apps under Sign-in & security in My account. For outlook.com, login to your mail account on the webpage, then click on options, again click on options, then click on Connect devices and apps with POP, and then click on enable POP.

Both outlook.com and gmail.com use secure POP3S and IMAPS protocols, so you need to download and install the root certificates they are signing their SSL certificates with on your Fetchmail server first in order to be able to use their services. Here we can install the Mozilla CA certification bundle, which has been compiled by the Mozilla foundation and includes the most commonly used root server certificates used by all major websites and services, such as those used by our mail providers. For gmail.com we need the Equifax Secure Certificate Authority root certificate and for outlook.com we need the root server certificate from Globalsign. Fetchmail needs these root certificates to verify the validity of any other SSL certificate downloaded from the e-mail server. Login as root on your Postfix server and install the following package:
yum install ca-certificates

Afterwards, login as a Linux system user, for example, john, who we will create a new Fetchmail configuration file for, and who already has a local Postfix mailbox directory on our server located in his home directory under ~/Maildir. Now before configuring any account in the Fetchmail configuration file, you should always first test if the connection and authentication to the specific account are working with the Fetchmail command line, as shown in the previous process. For testing our different mail providers’ accounts, we need three different command line calls. For testing if your provider is using SSL encryption, you need the –ssl flag; a typical output for a mail provider who is not allowing non-SSL connections could be:
Fetchmail: SSL connection failed.
Fetchmail: socket error while fetching from @
Fetchmail: Query status=2 (SOCKET)

If your google and outlook username is johndoe at both mail providers for testing google with the IMAPS protocol try (enter your e-mail user’s password when prompted):
fetchmail imap.gmail.com -p IMAP --ssl -u johndoe@gmail.com -k -v

If the login was successful, the output should be similar to (truncated):
Fetchmail: IMAP A0002 OK johndoe@gmail.com authenticated (Success)
9 messages (2 seen) for johndoe at imap.gmail.com.
Fetchmail: IMAP> A0005 FETCH 1:9 RFC822.SIZE

For testing outlook.com with POP3S, use:
fetchmail pop-mail.outlook.com -p POP3 --ssl -u johndoe@outlook.com -k -v

On success, the output should be similar to (it has been truncated):
Fetchmail: POP3> USER johndoe@outlook.com
Fetchmail: POP3 +OK password required
Fetchmail: POP3 +OK mailbox has 1 messages

For our third hypothetical e-mail account at my-email-server.com, we will use POP3 or IMAP without SSL so test it using our account:
fetchmail pop3.my-email-server.com -p POP3 -u johndoe -k -v
fetchmail imap.my-email-server.com -p IMAP -u johndoe -v

You should also check if all the fetched mails from your external providers have been downloaded correctly. View your system user’s local mailbox using the mailx command (mailx -f ~/Maildir). After we successfully verify that Fetchmail is able to connect to the servers and fetch some mails, we now can proceed to create a local Fetchmail configuration file in our system user’s home directory in order to automate this process and configure multiple mail addresses. Start by opening a new empty file using vi ~/.fetchmailrc. Remember that all the commands which can be put on the command line can also be used with slightly different names in the configuration file (and much more). Now put in the following content (replace john with your actual Linux system user, johndoe with your e-mail user account name, and secretpass with your actual mail password for this account):
set postmaster "john"
set logfile fetchmail.log
poll imap.gmail.com with proto IMAP
user 'johndoe@gmail.com' there with password 'secretpass' is john here
ssl
fetchall
poll pop-mail.outlook.com with proto POP3
user 'johndoe@outlook.com' there with password 'secretpass' is john here
ssl
fetchall
poll pop3.my-email-server.com with proto POP3
user 'johndoe@my-email-server.com' there with password 'secretpass' is john
here
fetchall

Save and close this file. In this file, we used the following important commands:

  • postmaster: Defines the local Linux user which will receive all the warning or error mails if Fetchmail runs into problems.
  • logfile: Defines a filename for a log file, which can be very helpful for us to supervise and debug Fetchmail output when it’s running continuously over a long period of time in the background.
  • poll section: Specifies downloading mails from a specific mail provider. For every mail account, you will define one such poll section. As you can see here, the syntax is very similar to the one used on the command line when we tested the single connections. With proto we define the mail protocol, user is the login user for the mail account, password is the login password of your account, and with the is here parameter you specify which local system user account this mail account is tied to. For SSL connections you need the ssl flag, and we specified the fetchall parameter to make sure we also download all the e-mail messages flagged as read by the e-mail provider as otherwise Fetchmail would not download e-mails that have already been read.

Next change the permissions of the .fetchmailrc file because it contains passwords and should therefore not be read by anyone other than our own user:
chmod 600 ~/.fetchmailrc

Finally, we execute Fetchmail with the settings given in our configuration file. For testing, we will use a very verbose parameter here: fetchmail -vvvv. All the new mails from all your different e-mail providers should now be fetched, so afterwards you should go through the output and see if every server was ready and could be polled just as the single tests we did on the command line tests earlier. All the new mails should have been downloaded to the local mailbox, so in order to read your local mails you can use the mailx command as usual, like: mail -f ~/Maildir.

Automating Fetchmail

As just said, we can now manually start the polling process every time we want by just typing in fetchmail on the command line. This will poll and fetch all new mails from the mail servers specified in our new configuration file and then after processing each entry once it will exit the program. Now what’s still missing is a mechanism to continuously query our mail servers at a specific interval updating our mailbox whenever new mails can be fetched. Here you can use two approaches. Either run the fetchmail command as a cron job or as an alternative you can start Fetchmail in daemon mode (use the parameter set daemon in your .fetchmailrc config file to activate it.) and put it in the background.

This way Fetchmail will run constantly and wake up at a given time point and start the polling until everything finishes processing and then go back to sleep until the next interval has been reached.

As both methods are basically the same, here we will show you how to run Fetchmail as a cron job, which is much easier to set up because we don’t have to create some custom systemd service files (currently in CentOS 7 there is no fetchmail systemd service available out-of-the box). For every system user (for example, john) who has a fetchmail configuration file, to start the e-mail server polling process every 10 minutes type in the following command once to register the cron job:
crontab -l | { cat; echo "*/10 * * * * /usr/bin/fetchmail &> /dev/null "; } | crontab

Note

Do not set the Fetchmail polling cycle shorter than every 5 minutes; otherwise, some mail providers may block or ban you, as it just overloads their systems.

 

Customizing the FTP service on CentOS

In this process, you will learn how to customize your vsftpd installation. vsftpd has a lot of configuration parameters, and here we will show how to create a custom welcome banner, change the server’s default-time out, limit user connections, and ban users from the service.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges and a console-based text editor of your choice. It is expected that your server will be using a static IP address and that vsftpd is already installed with a chroot jail and is currently running.

The Process

  1. To begin with, log in as root and open the main vsftpd configuration file:
    vi /etc/vsftpd/vsftpd.conf
  2. First, provide an alternative welcome message, uncomment the following line, and alter the message as required. For example, you could use this:
    ftpd_banner=Welcome to my new FTP server
  3. To change the default FTP time-outs, uncomment these lines and substitute the numeric values as required:
    idle_session_timeout=600
    data_connection_timeout=120
  4. Now, we will limit the connections: the data transfer rate in bytes per second, the number of clients, and the maximum parallel connections per IP address. Add the following lines to the end of the file:
    local_max_rate=1000000
    max_clients=50
    max_per_ip=2
  5. Next, save and close the file. To ban a specific user, you can use the following commands while replacing the username with an appropriate system user value that fits your needs:
    echo "username" >> /etc/vsftpd/user_list
  6. Now to apply the changes, restart the FTP service:
    systemctl restart vsftpd

How Does It Work?

In this process, we have shown some of the most important vsftpd settings. Covering all the configuration parameters here is outside the scope of this process. To learn more about it, read through the entire main vsftpd configuration file at /etc/vsftpd/vsftpd.conf, as it contains a lot of useful comments; alternatively, you can read the man vsftpd.conf manual.

So what did we learn from this experience?

We began by opening the main vsftpd configuration file and then activated and customized the welcome banner using the ftpd_banner directive. On the next successful login, your users should see your new message. Next, when dealing with a large number of users, you may want to consider changing the values for a default timeout and limit the connections in order to improve the efficiency of your FTP service.

First, we changed our server’s timeout numbers. An idle_session_timeout of 600 seconds will logout the user if he is inactive (not executing FTP commands) for 10 minutes, while a data_connection_timeout of 120 seconds will kill the connections when a client data transfer is stalled (not progressing) for 20 minutes. Then we changed the connection limits. A local_max_rate of 1000000 bytes per second will limit the data transfer rate of a single user to roughly one megabyte per second. A max_clients value of 50 will tell the FTP server to only allow 50 parallel users to the system, while a max_per_ip of 2 allows only two connections per IP address.

Then we saved and closed the file. Finally, we showed how to ban users from using our FTP service. If you wanted to ban a specific user from using the FTP service as a whole, the user’s name should be added to the /etc/vsftpd/user_list file. If you ever need to re-enable the user at any time, simply reverse the previous process by removing the user concerned from /etc/vsftpd/user_list.

 

Maintaining CentOS filesystem

In this process, we will learn how to check the consistency and optionally repair CentOS 7 filesystems. Filesystem inconsistencies are rare events and filesystem checks normally are running automatically at boot time. But system administrators should also know how to run such tests manually if they believe there is a problem with the filesystem.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges. We will use virtual block devices instead of real disk devices because we cannot apply any file system check on a mounted disk. Therefore, you should have applied the Formatting and mounting a filesystem process and created a 1 gigabyte virtual block device with two partitions of half the total size: first, a partition with an XFS, and then another one with an ext4 filesystem. We will use the virtual block device named /dev/loop0 in this example.

As said before, these can be easily exchanged with real disk names.

The Process

  1. To begin with, log in as root and show information about the current block devices attached to the system:
    lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL
  2. Here, you should see two partitions on the loop0 device: /dev/loop0p1 and /dev/loop0p2. If you see that they are currently mounted to the system, unmount them now:
    umount /dev/loop0p1 umount /dev/loop0p2
  3. Now, let’s check the XFS filesystem which in our example is loop0p1 (change appropriately):
    xfs_repair -n /dev/loop0p1
  4. For the second partition on the disk that is ext4, we will use the following line
    fsck -f /dev/loop0p2

How Does It Work?

In this process, we have learned how easy it is to run a filesystem check on a XFS or ext4 filesystem. The most important lesson you should have learned here is that you always have to unmount your disk partitions before running any filesystem checks!

So, what did we learn from this experience?

Since we cannot run any filesystem checks on any mounted device, if you want to check your system’s disks and partitions, often you have to run such checks in the rescue mode where your filesystems are not mounted (for example, you cannot unmount the root partition to check because it’s needed by the system all the time, whereas, for a separate home partition, it would be possible).

For the XFS file system, we use the xfs_repair tool, and for all others we will use the fsck program with the -f parameter (force) to check our filesystem.

It is important to note that we always need to run fsck instead of the specific fsck. (such as fsck.ext4, fsck.btrfs), because it auto-detects the right tool for you. This is necessary because if you run the wrong specific fsck. tool on the wrong filesystem (let’s say running fsck.ext4 on a btrfs filesystem), it can completely destroy it!

There's more…

So far, we have only showed you how to check a filesystem using xfs_repair and fsck. If some errors occur during the “checking” run on an XFS filesystem, run xfs_repair without the -n option—for example, use xfs_repair /dev/loop0p1. On a non-XFS partition, such as ext4, you would run fsck with the -a option (a for auto repair)—for example, fsck -a /dev/loop0p2. For fsck, if you got a lot of errors, it’s best to use -y as well so that you do not have to confirm every error fix.

Now, let’s simulate what would happen if we got a corrupted XFS filesystem using our virtual block device (never do this on any real disk partition!):

  1. First, mount the /dev/loop0p1 partition to your root filesystem:
    mkdir /media/vbd-1 mount -t xfs /dev/loop0p1 /media/vbd-1
  2. Next, create a large number of files on this mounted filesystem—for example, 2000 files:
    for i in {1..2000}; do dd if=/dev/urandom bs=16 count=1 of=/media/vbd1/file$i; done
  3. Now, unmount the device and corrupt the filesystem using dd:
    umount /dev/loop0p1
    dd bs=512 count=10 seek=100 if=/dev/urandom of=/dev/loop0p1
  4. Now, run a filesystem check:
    xfs_repair -n /dev/loop0p1
  5. This will most likely show you a list of corrupted files; in order to fix it, use the following line:
    xfs_repair /dev/loop0p1

You can also simulate such a filesystem corruption on your ext4 virtual block device, and then repair it using fsck -ay /dev/loop0p2.

 

Scheduling tasks with cron in CentOS

In this process, we will investigate the role of server automation and the convenience of running specific tasks at predefined periods by introducing you to the time-based job scheduler known as cron. Cron allows for the automation of tasks by enabling the administrator to determine a predefined schedule based on any hour, any day, or any month. It is a standard component of the CentOS operating system, and it is the purpose of this process to introduce you to the concept of managing recurring tasks in order to take advantage of this invaluable tool and to make CentOS work for you.

To Start With: What Do You Need?

In a bid to complete this process, you will require a minimal installation of the CentOS 7 operating system with root privileges, and a console-based text editor of your choice. The crontab program uses Vim for file editing. If you do not know how to work with Vim, go through the tutorial shown in the article Introduction to Vim, Configuring the System

The Process

The purpose of this process is to create a script that will write the time and date with a few words of your choice to a text file every five minutes. This may seem to be a relatively simple exercise, but the intention is to show you that, from such simplicity, cron can be used to do so much more that will make working with CentOS an absolute pleasure.

  1. To begin this process, log in as root and create your first cron job by typing:
    crontab -e
  2. We will now create a simple cron job that will write the date and time with the words hello world to a file located at /root/cron-helloworld.txt every five minutes. To do this, add the following line:
    */5 * * * * echo `date` "Hello world" >>$HOME/cron-helloworld.txt
  3. When complete, simply save the file and exit the editor. The system will now respond with the following message:
    crontab: installing
    new crontab
  4. The preceding message informs you that the server is now creating the new cron job and will automatically activate it. You can view the output of the script by reviewing the file found at /root/cron-helloworld.txt (you have to wait 5 minutes), or by monitoring the logfile found at /var/log/cron (use tail -f /var/log/cron and Ctrl+C to exit).

How it works...

Cron is the name of a program that enables CentOS users to execute commands or scripts automatically at a specified time and date. Cron’s settings are kept in a user-specific file called crontab, and as we have seen in this process this file can be edited to create automated tasks as often as they are required.

So what did we learn from this experience?

The example used was very simple, but in many ways, this was the purpose of this process. Crontab uses a daemon, crond, which runs constantly in the background and checks once a minute to see if any of the scheduled jobs need to be executed. If a task is found, then cron will execute it. To edit an existing crontab file or to create a new crontab, we use the crontab -e command. To view a list of current cron jobs, you can type crontab -l. Alternatively, to view a list of the current jobs for another user, you can type crontab -u username -l. Tasks or jobs are generally referred to as cron jobs, and by avoiding complication in our first script, it was the intention to show you that the nature of command construction was very simple. The formation of a cron job looks like this:

Entries are separated by a single or tabbed space, and the allowed values are primarily numeric (that is, 0-59 for a minute, 0-23 for an hour, 1-31 for a day of the month, 1-12 for the month of the year, and 0-7 for day of the week). However, in saying this, it is also true to say that there are more specific operators ( / , -) and cron-specific shortcuts (that is, @yearly, @daily, @hourly, and @weekly) that do allow for additional controls. For example, where the / operator is used to step through specified units, it can be read as every, so in our process, the use of */5 will run the task every five minutes while the use of */1 runs the task every minute. As an addition to this, you should be aware that the use of this syntax will align all commands on the hour. So, with this in mind, the most suitable template or starting point for anyone wanting to write their first cron job is to start with a series of five asterisks followed by the command, like this:

* * * * * /absolute/path/to/script.sh

Then, proceed to configure the minute, hour, day, month, and day-of-the-week values as desired. For example, if you want a particular PHP script to run at 8 P.M. (20:00 hrs) on every weekday (Monday-Friday), it may look like this:
0 20 * * 1-5 /full/path/to/your/php/script.php

So, with this in mind, and by completing this process, you can see how cron can be used to manage a database backup, run a scheduled system backup, provide support to websites by activating scripts at predefined intervals or run various bash scripts and a whole lot more.

There's more…

To delete or disable a cron job, it is simply a matter of either removing the instruction from an individual user’s cron file or by placing a hash (#) at the beginning of the line. Individual cron files can be found at /var/spool/cron/, and the use of the hash will either disable the cron job or allow you to write comments. To completely remove a crontab file, you can also use crontab -r. For example, if you want to remove the cron job created in the main process, you can log in as root and begin by typing the command, crontab -e. At this point, you may either remove the entire line or comment it out, as shown here:
# */15 * * * * echo `date` "Hello world" >>$HOME/cron-helloworld.txt

Next, save the file. There are also some special cron directories in the filesystem for system-wide cron jobs that will if you drop a script file in it, run it automatically at a certain time point. The folders are called cron.daily, cron.hourly, cron.weekly, and cron.monthly in the /etc directory and their names refer to the time point that they are run. Just remove the script from the folder if you don’t want to execute it any more. Take a look at the Monitoring important server infrastructure process for an example.

 

CentOS troubleshooting in rescue mode

We all make mistakes and this is especially true for novice Linux system administrators. Linux can have a steep learning curve and sooner or later there will be a point in your career where your CentOS installation does not start up due to a broad number of reasons, including hardware problems or human mistakes such as configuration errors. If this has happened to you then you can use the CentOS rescue mode in order to boot an otherwise unbootable system and try to undo your mistakes or find out the root of the problems. In this process, we will show you three common use cases when to use this option:

  • Accessing the filesystem for recovering important data or undoing changes to configuration files if CentOS is not booting up
  • Changing the root password if you forgot it
  • Re-installing the boot loader which can be damaged when installing another operating system on the same hard disk where CentOS is installed

To Start With: What Do You Need?

In order to complete this process, you will require a standard installation media (CD/DVD or USB device) of the CentOS 7 operating system. For recovering the data from the system, you will need to connect some sort of external storage device to the system, such as an external hard disk or a working network connection to another computer to copy all your precious data to a different location.

The Process:

To begin this process, you should boot your server from the CentOS installation CD/DVD or the USB device and wait until the first welcome splash screen appears with the cursor waiting at the Test this media & install CentOS 7 menu option.

Reaching rescue mode

  1. From the main menu, use the down arrow key to select Troubleshooting and then press the Return key to proceed.
  2. On the troubleshooting screen, use the down arrow key to highlight Rescue a CentOS system. When you are ready, press the Return key to proceed.
  3. After some loading time, we enter the rescue screen, which includes various confirmation sub-screens. To begin this section, use the left and right arrow keys to choose Continue and press the Return key to proceed.
  4. On the first sub-screen, choose OK and press the Return key to proceed.
  5. Again, in the following sub-screen, choose OK and press the Return key to proceed.
  6. On the next screen, choose the Start shell and by using the Tab key, highlight OK and press the Return key to proceed.
  7. By completing the preceding steps, you will launch a shell session. You will notice this at the bottom of your display. The current status of the shell session will read as follows:
    bash-4.2#_
  8. At the prompt, type the following instruction to change the root filesystem, before pressing the Return key to complete your request:
    chroot /mnt/sysimage
  9. Congratulations! You just reached the rescue mode. To exit it at any time, simply type the following command and then press the Return key to complete your request (don’t do this right now as this will restart the system):
    reboot
  10. After the basic rescue mode is reached, we have the following options, depending on the type of problem.

Accessing the filesystem

If you are now in the rescue mode and need to back up important files from the filesystem, you need a destination location for the data transfer. For transferring the data we want to recover from the server to another computer please physically connect an external USB device to it. You can also use network storages for the recovery. For example, you could import an NFS server share and copy data to it. 

  1. On the rescue mode command line, type in the following command, which will show you all the current partitions connected to the system, and then press the Return key to complete your request:
    fdisk -l
  2. You now need to find out the right device name with the partition number of your connected device; comparing the total size or the filesystem output of the various devices with the specifications from your stick can help you in this process. You can also try the following trick: run the fdisk -l command twice, first with the plugged-in USB device and then again with the USB device unplugged, and compare the output of both the commands. It should be different from one device name which you are searching for!
  3. If you have found the right device name in the list, create a directory to mount the stick to the filesystem:
    mkdir /mnt/hdd-recover
  4. Next, mount the disk partition to this folder. Here we assume that the USB device of interest has the device name sdd1 (please change if different on your system):
    mount /dev/sdd1 /mnt/hdd-recovery
  5. The original system’s hard disk’s root partition has been mounted under a specific folder by the rescue system automatically (under /mnt/sys image), if you need to access it for example to change configuration files which caused startup problems or make a full or partial backup. For example, if you need to back up your Apache web server configuration files, use:
    cp -r /mnt/sysimage/etc/http /mnt/hdd-recovery
  6. If you need to access the data that lives on partitions other than the currently mounted root partition, use fdisk -l to identify the partition of interest. Then create a directory and mount the partition to it and change to that directory to access your data similar you did when mounting the USB device.
  7. To finish backing up the files, type:
    reboot

Accessing the filesystem

  1. If you are in the rescue mode for changing the root password, just use the following command and provide a new password:
    passwd
  2. To complete changing the password, type:
    reboot

Re-install the CentOS boot loader

  1. We will now use the fdisk command to find the name of all the current partitions. To do this, type the following instruction and then press the Return key to complete your request:
     fdisk –l
  2. Now run the following command:
    dmesg | grep -Fq "EFI v"
  3. If the preceding command does not produce any output look for the * symbol in the fdisk listing in the boot column to find the correct start partition, and assuming that your boot disk is on /dev/sda1 (change this as required), type the following:
    grub2-install /dev/sda
  4. Otherwise, if there is an output, run instead:
    yum reinstall grub2-efi shim
  5. If no error is reported, the console should respond as follows:
    # this device map was generated by anaconda
    (hd0) /dev/sda
  6. The console output from the last step has confirmed that GRUB has now been successfully restored.
  7. To reboot the computer, type:
    reboot

How Does It Work?

There are a broad variety of problems which can be resolved by the tools provided through the rescue mode environment. Often these problems refer to booting problems but can also be from different types, such as forgetting the root password. Rescue mode can be a lifesaver and an understanding of it is a very important skill to learn. 

Tip

Remember to always be careful when working with bootloader commands as improper use can make your operating system unbootable.

 

Troubleshooting SELinux

In this process, you will learn how to troubleshoot SELinux policies, which is most often needed when access to some SELinux objects has been denied and you need to find out the reasons for it. In this process, we will show you how to work with the sealert tool, which will create human-readable and understandable error messages to work with.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges. It is assumed that you are working through serially process by process, so by now you should have installed the SELinux tools and applied the Working with policies process, as we will produce some SELinux denial events in order to show you how to use the log file tools.

The Proces

  1. To begin, login as root and provoke a SELinux denial event:
    touch /var/www/html/test2.html
    semanage fcontext -a -t user_tmp_t /var/www/html/test2.html
    restorecon -v /var/www/html/test2.html
    curl http://localhost/test2.html
  2. Now, let’s generate an up-to-date human readable log file:
    sealert -a /var/log/audit/audit.log
  3. In the program’s output, you will get a detailed description of any SELinux problem and, at the end of each so called alert, you will even find a suggested solution to fix the problem; in our example, the alert of interest should read (the output is truncated) as shown next:
    SELinux is preventing /usr/sbin/httpd from open access on the file
    /var/www/html/test2.html.
    /var/www/html/test2.html default label should be httpd_sys_content_t

How Does It Work?

Here in this process, we showed you how easily one can troubleshoot SELinux problems using the sealert program. We started by provoking a SELinux deny access problem by creating a new file in the web root directory and assigning it a wrong context type of value user_tmp_t, which has no access rule defined in the httpd policy. Then, we used the curl command to try and fetch the website and actually produce the Access Vector Cache (AVC) denial message in the SELinux logs. Denial messages are logged when SELinux denies access. The primary source where all SELinux logging information is stored in the audit log file, which can be found at /var/log/audit/audit.log, and easier-to-read denial messages will also be written to /var/log/messages. Here, instead of manually grepping for error messages and combining both log files, we use the sealert tool, which is a convenience program that will parse the audit and messages log file and present valuable AVC content in a human-readable format. At the end of each alert message, you will also find a suggested solution to the problem. Please note that those are auto-generated messages and should always be questioned before applying.

 

Delivering the mail with Dovecot in CentOS

In a previous process, you were shown how to configure Postfix as a domain-wide mail transport agent. As we have learned in the first process of Postfix that it only understands the SMTP protocol and does a remarkable job to transport messages from another MTA or mail user client to other remote mail servers or storing mails which are destinated to itself into its local mailboxes. After storing or relaying mails, Postfix jobs end. Postfix can only understand and speak the SMTP protocol and is not capable of sending messages to anything other than MTAs. Any possible recipient user for a mail message who wants to read his mails would now need to log in to the server running the Postfix service using ssh and look into his local mailbox directory, or alternatively use mailx locally to view his messages on a regular basis to see if there are any new mails. This is highly inconvenient and nobody would use such a system. Instead, the users choose to access and read their mail from their own workstations other than where our Postfix server is located. Therefore, another group of MTAs has been developed, sometimes are called access agents and which have the main functionality to synchronize or transfer those local mailbox messages from the server running the Postfix daemon over to external mailing programs where users can read them. These MTA systems use different protocols than SMTP, namely POP3 or IMAP. One such MTA program is Dovecot. Most professional server administrators would agree that Postfix and Dovecot are perfect partners and it is the purpose of this process to learn how to configure Postfix to work with Dovecot in order to provide a basic POP3/IMAP and a POP3/IMAP over SSL (POP3S/IMAPS) service for our mailboxes to provide an industry standard e-mail service for your users across the local network.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to download additional packages. It is also assumed that you are working through this chapter division process by the process in the order that they appear and for this reason, it is expected that Postfix has been configured as a domain-wide MTA.

Note
This process serves as a guide to setting up a basic POP3S/IMAPS service for trusted users on a local network. It is not suitable for general Internet use without applying additional security measures.

The Process

Dovecot is not installed by default, and for this reason we must begin by installing the necessary packages by following the given steps:

  1. To start, log in as root and type in the following command:
    yum install dovecot
  2. Once installed, enable the Dovecot service at boot by typing:
    systemctl enable dovecot
  3. Now open the main Dovecot configuration file in your favorite text editor, after creating a backup copy, by typing:
    cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.BAK
    vi /etc/dovecot/dovecot.conf
  4. Begin by confirming the protocols we want to use by activating (removing the # sign at the beginning of the line) and modifying the following line, so it reads:
    protocols = pop3 imap imaps pop3s
  5. Next, enable Dovecot to listen to all network interfaces instead of only the loopback address. Search for the line #listen = *, ::, then modify it so it reads:
    listen = *
  6. Now save and close the file in the usual way before making a backup of the 10mail.conf file and afterwards opening it in your favorite text editor:
    cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10
    mail.conf.BAK
    vi /etc/dovecot/conf.d/10-mail.conf
  7. Scroll down and uncomment (remove # character) the following line, so it reads:
    mail_location = maildir:~/Maildir
  8. Again, save and close the file in the usual way before creating a backup copy and then opening the following file in your favorite text editor:
    cp /etc/dovecot/conf.d/20-pop3.conf /etc/dovecot/conf.d/20
    pop3.conf.BAK
    vi /etc/dovecot/conf.d/20-pop3.conf
  9. Start by uncommenting the following line:
    pop3_uidl_format = %08Xu%08Xv
  10. Now scroll down and amend the following line:
    pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
  11. Save and close the file in the usual way. Now we will allow plain text logins. To do this, make a backup before opening the following file:
    cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10
    auth.conf.BAK
    vi /etc/dovecot/conf.d/10-auth.conf
  12. Change the line #disable_plaintext_auth = yes to state:
    disable_plaintext_auth = no
  13. Save and close the file. In our final configuration setting, we will tell Dovecot to use our self-signed server certificate. Just use your Postfix certificate from another process in this segment or create a new one (otherwise skip this step):
    cd /etc/pki/tls/certs; make postfix-server.pem
  14. Open Dovecot’s standard SSL config file after making a backup of the file:
    cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.BAK
    vi /etc/dovecot/conf.d/10-ssl.conf
  15. Now change the following line (ssl = required) to read:
    ssl = yes
  16. Now change the following two lines to point to your server’s own certificate path:
    ssl_cert = /etc/pki/tls/certs/postfix-server.pem
    ssl_key =
  17. Save and close this file. Next, enable IMAP, IMAPS, POP3, and POP3S ports in our firewall to allow incoming connections on the corresponding ports. For POP3 and IMAP, we need to specify our own firewalld service files, since they are not available in CentOS 7 by default:
    sed 's/995/110/g' /usr/lib/firewalld/services/pop3s.xml | sed 's/ over
    SSL//g' > /etc/firewalld/services/pop3.xml
    sed 's/993/143/g' /usr/lib/firewalld/services/imaps.xml | sed 's/ over
    SSL//g' > /etc/firewalld/services/imap.xml
    firewall-cmd --reload
    for s in pop3 imap pop3s imaps; do firewall-cmd --permanent --add
    service=$s; done;firewall-cmd --reload
  18. Now save and close the file before starting the Dovecot service:
    systemctl start dovecot
  19. Finally, to test our new POP3/SMTP network service, just login on another computer in the same network and run the following commands to use mailx to access the local mailboxes on the remote Postfix server, which is provided by Dovecot with the different access agent protocols. In our example, we want to access the local mailbox of the system user john on our Postfix server with the IP 192.168.1.100 (to login to john’s account, you need his Linux user password) remotely:
    mailx -f pop3://john@192.168.1.100
    mailx -f imap://john@192.168.1.100
  20. Next, to test the secure connections, use the following commands and type yes to confirm that the certificate is self-signed and not trusted:
    mailx -v -S nss-config-dir=/etc/pki/nssdb -f pop3s://john@192.168.1.100
    mailx -v -S nss-config-dir=/etc/pki/nssdb -f imaps://john@192.168.1.100
  21. For all four commands, you should see the normal mailx inbox view of your mailbox with all your mail messages of user john as you would run the mailx command locally on the Postfix server to read local mails.

How Does It Work?

Having successfully completed this process, you have just created a basic POP3/SMTP service, (with or without SSL encryption) for all the valid server users in your network, which will deliver local mails from the Postfix server to the client’s e-mail program. Every local system user can directly authenticate and connect to the mail server and fetch their mail remotely. Of course, there is still much more that can be done to enhance the service, but you can now enable all local system account holders to configure their favorite e-mail desktop software to send and receive e-mail messages using your server.

Note
POP3 downloads the mails from the server on a local machine and deletes them afterwards, whereas IMAP synchronizes your mails with your mail server without deleting them.

So what did we learn from this experience?

We started the process by installing Dovecot. Having done this, we then enabled Dovecot to run at boot before proceeding to make a few brief changes to a series of configuration files. Starting with the need to determine which protocol will be used in the Dovecot configuration file at /etc/dovecot/dovecot.cf here we will use: IMAP, POP3, IMAPS, and POP3S. As with most other essential networking services, after installation they only listen on the loopback device, so we enabled Dovecot to listen to all network interfaces installed in the server. In the 10-mail.conf file we then confirmed the mailbox directory location for Dovecot (with the mail_location directive) as the location Postfix will put them into on receiving mails so Dovecot can find them here and pick them up. Following this, we then opened the POP3 protocol in 20-pop3.conf by adding a fix relating to various e-mail clients (for example, for the Outlook client) using the pop3_uidl_format and pop3_client_workarounds directives. Finally, we enabled plain text authorization by making several changes to /etc/dovecot/conf.d/10-auth.conf. Remember that using plain text authorization with POP3 or IMAP without SSL encryption is considered insecure but because we were concentrating on a local area network (for a group of trusted server users) we should not necessarily see this as a risk. Afterwards, we enabled POP3 and IMAP over SSL (POP3S and IMAPS) by pointing the ssl directives in the 10ssl.conf file to some existing self-signed server certificates. Here we changed ssl = required to ssl=yes to not force the client connecting to the Dovecot service to use SSL encryption, as we do want to give the user the choice to enable encrypted authentication if he likes to but not make it mandatory for older clients. Afterwards, to make our Dovecot service available from the other computers in our network, we had to enable the four ports to allow POP3, IMAP, POP3S, and IMAPS, 993, 995, 110, 143, by using the predefined firewalld service files and creating the missing ones for IMAP and POP3 ourselves. Later, we started the Dovecot service and tested our new POP3/IMAP server using the mailx command remotely. By supplying an -f file parameter, we were able to specify our protocol and location. For using SSL connections, we needed to supply an additional nssconfig-dir option pointing to our local Network Security Services database where certificates are stored in CentOS 7.

Remember, if you happen to encounter any errors, you should always refer to the log file located at /var/log/maillog. Using plain text authorization should not be used in a real corporate environment and POP3/IMAP over SSL should be preferred.

There's more…

In the main process, you were shown how to install Dovecot in order to enable trusted local system users with system accounts to send and receive e-mails. These users will be able to use their existing username as the basis of their e-mail address, but by making a few enhancements you can quickly enable aliases, which is a way to define alternative e-mail addresses for existing users.

To start building a list of user aliases, you should begin by opening the following file in your favorite text editor:
vi /etc/aliases

Now add your new identities to the end of the file, where will be the name of the actual system account:
#users aliases for mail
newusernamea:
newusernameb:

For example, if you have a user called john who currently (only) accepts e-mails at john@centos7.home, but you want to create a new alias for john called johnwayne@ centos7.home, you will write:
johnwayne: john

Repeat this action for all the aliases, but when you have finished remember to save and close the file in the usual way before running the following command: newaliases.

Setting up e-mail software in CentOS

There are a vast number of e-mail clients on the market and by now you will want to start setting up your local users to be able to send and receive e-mails. This isn’t complicated by any means, but in order to have a good starting point you will want to consider the following principles. The format of the e-mail address will be system_username@domainname.home.

The incoming POP3 settings will be similar to the following:
mailserver.centos7.home, Port 110
Username: system_username
Connection Security: None
Authentication: Password/None

For POP3S, just change the port to 995 and use Connection Security: SSL/TLS. For IMAP, just change the port to 143, and for IMAPS use port 993 and Connection Security: SSL/TLS.

The outgoing SMTP settings will be similar to the following:
mailserver.centos7.home, Port 25
Username: system_username
Connection Security: None
Authentication: None

 

 

Working with CentOS virtual FTP users

In this process, you will learn how to implement virtual users in order to break away from the restriction of using local system user accounts. During the lifetime of your server, there may be occasions when you wish to enable FTP authentication for a user that does not have a local system account. You may also want to consider implementing a solution that allows a particular individual to maintain more than one account in order to allow access to different locations on your server. This type of configuration implies a certain degree of flexibility afforded by the use of virtual users. Since you are not using a local system account, it can be argued that this approach gives improved security.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges and a console-based text editor of your choice. It is expected that your server will be using a static IP address and that vsftpd is already installed with a chroot jail and is currently running. This process needs the policycoreutils-python package installed.

The Process

  1. The first step is to login as root on our vsftpd server and create a plain text file called virtual-users.txt that maintains a list of usernames and passwords of the virtual users. To do this, type the following command:
    vi /tmp/virtual-users.txt
  2. Now add your usernames and corresponding passwords in the following way:
    virtual-username1
    password1
    virtual-username2
    password2
    virtual-username3
    password3

    Note
    Repeat this process as required for every user you need but, for obvious reasons, maintain a good password policy and do not use the same virtual-username more than once.

  3. When you have finished, simply save and close the file in the usual way. Then, proceed to build the database file by typing the following command:
    db_load -T -t hash -f /tmp/virtual-users.txt /etc/vsftpd/virtualusers.db
  4. Having done this, we will now create the PAM file that will use this database to validate the virtual users. To do this, type the following command:
    vi /etc/pam.d/vsftpd-virtual
  5. Now add the following lines:
    auth required pam_userdb.so db=/etc/vsftpd/virtual-users
    account required pam_userdb.so db=/etc/vsftpd/virtual-users
  6. When you have finished, save and close the file in the usual way. Open the main vsftpd configuration file in your favorite text editor as follows:
    vi /etc/vsftpd/vsftpd.conf
  7. Now, in the opened file, search for the line pam_service_name=vsftpd and disable it by adding a # sign at the beginning of the line so that it reads as follows:
    #pam_service_name=vsftpd
  8. Scroll down to the bottom of the file and add the following lines by customizing the value for local_root to suit your own specific needs—this will be the base directory in which all your virtual users will live in (for example, we will use /srv/virtualusers/$USER as shown here):
    virtual_use_local_privs=YES
    guest_enable=YES
    pam_service_name=vsftpd-virtual
    user_sub_token=$USER
    local_root=/srv/virtualusers/$USER
    hide_ids=YES
  9. Now create a subfolder for each virtual user you defined in a previous step in your /tmp/virtual-users.txt file within the directory that you stated with the local_root directive. Remember to delegate the ownership of this folder to the FTP user. To keep up with our /srv/virtualusers example, we will use the following commands to do this in an automatic way (again, customize the /srv/virtualusers directory if needed):
    for u in `sed -n 1~2p /tmp/virtual-users.txt`;
    do
    mkdir -p /srv/virtualusers/$u
    chown ftp: /srv/virtualusers/$u
    done
  10. Now we need to inform SELinux to allow read/write access to our custom local_root directory outside of the typical /home directory:
    setsebool -P allow_ftpd_full_access on
    semanage fcontext -a -t public_content_rw_t "/srv/virtualusers(/.*)?"
    restorecon -R -v /srv/virtualusers
  11. Next, restart the FTP service as follows:
    systemctl restart vsftpd
  12. For security reasons, remove the plain text file now and protect the generated database file with this:
    rm /tmp/virtual-users.txt chmod 600 /etc/vsftpd/virtual-users.db

How Does It Work?

Having followed the previous process, you will be now able to invite an unlimited number of virtual users to access your FTP service. The configuration of this feature was very simple; your overall security has been improved and all access is restricted to a defined local_root directory of your choice. Please note that this usage of virtual users will disable your system users’ login to the FTP server from the first process.

So what did we learn from this experience?

We began this process by creating a new temporary text file that will contain all our usernames with the corresponding passwords in plain text. We then added all the required usernames and passwords one after another sequentially separated by newlines. Having done this for each of our virtual users, we then saved and closed the file before proceeding to run the db_load command that is installed on CentOS 7 by default. This can be used to generate a BerkeleyDB database out of our text file, which will be used for the FTP user authentication later in this process. Having completed this step, our next task was to create a Pluggable Authentication Modules (PAM) file at /etc/pam.d/vsftpd-virtual. This reads the previous database file to provide authentication from it for our vsftpd service using a typical PAM configuration file syntax (for more, see man pam.d). Then, we opened, modified, and added new configuration directives to the main vsftpd configuration file at /etc/vsftpd/vsftpd.conf in order to make vsftpd aware of our virtual users’ authentication via PAM.

The most important setting was the local_root directive that defines the base location where all your user directories will be placed for your virtual users. Don’t forget to put the $USER string at the end of your path. You were then prompted to create the relevant virtual hosting folder for every virtual user you have defined in the text file before.

Since virtual users are not real system users, we had to assign the FTP system user to take full ownership of the files for our new FTP users. We used bash for loop to automate the process for all our users defined in the temporary /tmp/virtual-users.txt file. Next, we set the proper SELinux boolean to allow virtual users access to the system and also the right context on our /srv/virtualusers directory. Applying all these changes was simply a matter of restarting the vsftpd service using the systemctl command.

Afterwards, we removed the temporary user text file because it contains our passwords in plain text. We protected the access to the BerkleyDB database file by removing all access other than root. If you update, add, or remove FTP users on a regular basis, it’s better to not delete this temporary plain text /tmp/virtual-users.txt file but rather put it in a safe place such as the /root directory. Then, you should also protect this using chmod 600. Then, you can rerun the db_load command whenever you make a change to this file to keep your users up-to-date. If you need to add new users at a later point, you have to create new virtual user folders for them as well (Please rerun the commands from step 9). Run the restorecon -R -v /srv/virtualusers command afterwards.

You can now test your new virtual user accounts by logging in to the FTP server using your newly created accounts from this process.