Skip to main content

Resources

Priming the kernel on CentOS

The Linux kernel is a program that constitutes the central core of the operating system. It can directly access the underlying hardware and make it available to the user to work with it using the shell.

In this process, we will learn how to prime the kernel by working with dynamically loaded kernel modules. Kernel modules are device driver files (or filesystem driver files) that add support for specific pieces of hardware so that we can access them.

You will not work very often with kernel modules as a system administrator, but having a basic understanding of them can be beneficial if you have a device driver problem or an unsupported piece of hardware.

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.

The Process

  1. To begin, log in to your system using your root user account, and type the following command in order to show the status of all Linux kernel modules currently loaded:
    lsmod
  2. In the output, you will see all loaded device drivers (module); let’s see if a cdrom and floppy module have been loaded:
    lsmod | grep "cdrom\|floppy"
  3. On most servers, there will be the following output:
    cdrom                     42556        1 sr_mod
    floppy                    69417 0
  4. Now, we want to show detailed information about the sr_mod cdrom module:
    modinfo sr_mod
  5. Next, unload these two modules from the kernel (you can only do this if the module and hardware have been found and loaded on your system; otherwise skip this step):
    modprobe -r -v sr_mod floppy
  6. Check if the modules have been unloaded (output should be empty now):
    lsmod | grep "cdrom\|floppy"
  7. Now, to show a list of all kernel modules available on your system, use the following directory where you can look around:
    ls /lib/modules/$(uname -r)/kernel
  8. Let’s pick a module from the subfolder /lib/modules/$(uname r)/kernel/drivers/ called bluetooth and verify that it is not loaded yet (output should be empty):
    lsmod | grep btusb
  9. Get more information about the module:
    modinfo btusb
  10. Finally, load this Bluetooth USB module:
    modprobe btusb
  11. Verify again that it is loaded now:
    lsmod | grep "btusb"

How it works…

Kernel modules are the drivers that your system’s hardware needs to communicate with the kernel and operating system (also, they are needed to load and enable filesystems). They are loaded dynamically, which means that only the drivers or modules are loaded at runtime, which reflects your own custom specific hardware.

So, what did we learn from this experience?

We started using the lsmod command to view all the currently loaded kernel modules in our system. The output shows three columns: the module name, the amount of RAM the module occupies while loaded, and the number of processes this module is used by and a list of dependencies of other modules using it. Next, we checked if the cdrom and floppy modules have been loaded by the kernel yet. In the output, we saw that the cdrom module is dependent on the sr_mod module. So, next we used the modinfo command to get detailed information about it. Here, we learned that sr_mod is the SCSI cdrom driver.

Since we only need the floppy and cdrom drivers while we first installed the base system we can now disable those kernel modules and save us some memory. We unloaded the modules and their dependencies with the modprobe -r command and rechecked whether this was successful by using lsmod again.

Next, we browsed the standard kernel module directory (for example, /lib/modules/$(uname -r)/kernel/drivers). The uname substring command prints out the current kernel version so that it makes sure that we are always listing the current kernel modules after having installed more than one version of the kernel on our system.

This kernel module directory keeps all the available modules on your system structured and categorized using subdirectories. We navigated to drivers/bluetooth and picked the btusb module. Doing modinfo on the btusb module, we found out that it is the generic Bluetooth USB driver. Finally, we decided that we needed this module, so we loaded it using the modprobe command again.

There's more…

It’s important to say that loading and unloading kernel modules using the modprobe command is not persistent; this means that if you restart the system, all your changes to kernel modules will be gone. To load a kernel module at boot time create a new executable script file, /etc/sysconfig/modules/.modules, where is the name of your choice. There you put in modprobe execution commands just as you would on the normal command line. Here is an example of additionally loading the Bluetooth driver on startup, for example /etc/sysconfig/modules/btusb.modules:

#!/bin/sh
if [ ! -c /dev/input/uinput ] ; then
exec /sbin/modprobe btusb >/dev/null 2>&1
fi

Finally, you need to make your new module file executable via the following line:
chmod +x /etc/sysconfig/modules/btusb.modules

Recheck your new module settings with lsmod after reboot.

To remove a kernel module at boot time for example sr_mod, we need to blacklist the module’s name using the rdblacklist kernel boot option. We can set this option by appending it to the end of the GRUB_CMDLINE_LINUX directive in the GRUB2 configuration file /etc/default/grub so it will look like:

GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap
crashkernel=auto rhgb quiet rdblacklist=sr_mod"

If you need to blacklist multiple modules, the rdblacklist option can be specified multiple times like rdblacklist=sr_mod rdblacklist=nouveau.

Next, recreate the GRUB2 configuration using the grub2-mkconfig command:
grub2-mkconfig -o /boot/grub2/grub.cfg

Finally, we also need to blacklist the module name using the blacklist directive in a new.conf file of your choice in the /etc/modprobe.d/ directory for example:
echo "blacklist sr_mod" >> /etc/modprobe.d/blacklist.conf

 

Downloading CentOS and confirming the checksum on Windows or OS X

In this segment, we will learn how to download and confirm the checksum of one or more CentOS 7 disk images using a typical Windows or OS X desktop computer. CentOS is made available in various formats by HTTP, FTP, or the rsync protocol from a series of mirror sites located across the world or via the BitTorrent network. For downloading very important files from the Internet, such as operating system images, it is considered best practices to validate those files’ checksum, in order to ensure that any resulting media would function and perform as expected when installing. This also makes certain that the files are genuine and come from the original source.

To Start With: What Do You Need?

It is assumed that you are using a typical Windows-based (Windows 7, Windows Vista, or similar) or OS X computer with full administration rights. You will need an Internet connection to download the required installation files and also need access to a standard DVD/CD disk burner with the appropriate software, in order to create the relevant installation disks from the image files. Here, it is assumed that all the downloads will be stored on Windows in your personal C:\Users\ \Downloads folder, or if using an OS X system, in the /Users//Downloads folder.

The Process

Regardless of the type of installation files you download, the following techniques can be applied to all the image files supplied by the CentOS project:

  1. Let’s begin by visiting http://www.centos.org in a web browser and navigate to the button link Get CentOS Now. Then click the link list of the current mirrors in the text.
  2. The mirror sites are categorized, so from the resulting list of links, choose a mirror that is geographically near your current location. For example, if you are in London (UK), you can choose a mirror from the EU  and the United Kingdom. Now choose a mirror site by selecting either the HTTP or the FTP link.
  3. Having made your selection, you will now see a list of directories of all the available CentOS versions. To proceed, simply click the appropriate folder that reads 7. Next, you will see an additional list of directories, such as atomic, centosplus, cloud, and so on. We proceed by choosing the isos directory.
  4. CentOS 7 currently only supports the 64-bit architecture, so browse to the only directory available labeled x86_64, which is a container for the 64-bit version.
  5. You will now be presented with a series of files available for download. Begin by downloading a copy of the valid checksum result identified as md5sum.txt.
  6. If you are new to CentOS or are intending to follow this process, then the minimal installation is ideal. This contains the least amount of packages to have a functional system, so choose the following (XXXX is the month stamp of this release):
  7. On a Windows-based system only (on Mac, this tool is already available in the system), visit http://mirror.centos.org/centos/dostools/ in your browser and download the program md5sum.exe.
  8.  Now on Windows, open the command prompt (typically found at Start | All Programs | Accessories | Command Prompt) and type the following commands into the window that will open (press the Enter key at the end of all the lines):
    cd downloads
    dir
  9. On OS X, open the program Finder | Applications | Utilities | Terminal, then type the following commands (press the Enter key at the end of all the lines):
    cd ~/Downloads ls
  10. You should now see all the files in your download folder (including all the downloaded CentOS installation image files, the md5sum.txt file and on Windows, the md5sum.exe program)
  11. Based on the file names shown, modify the following command in order to check the checksum of your downloaded ISO image file. On Windows, type the following} command (change the XXXX month stamp accordingly
    md5sum.exe CentOS-7-x86_64-Minimal-XXXX.iso
  12. On OS X, use instead
    md5 CentOS-7-x86_64-Minimal-XXXX.iso
  13. Press the Return key to proceed and then wait for the command prompt to respond. The response is known as the MD5 sum and the result could look like the following:
    d07ab3e615c66a8b2e9a50f4852e6a77 CentOS-7-x86_64-Minimal-1503-01.iso
  14. Now look at the sum and compare against the relevant listing for your particular image file in md5sum.txt (open in a text editor). If both the numbers match, then you can be confident that you have indeed downloaded a valid CentOS image file. If not, your downloaded file is probably corrupted, so please restart this procedure by downloading the image file again.
  15. When you have finished, simply burn your image file(s) to a blank CD-ROM or DVD-ROM using your preferred desktop software, or create a USB installation media from it, as we will show you in the next recipe in this chapter.

How it works...

So what have we learned from this experience?

The act of downloading a CentOS installation image is just the first step towards building the perfect server. Although this process is very simple, many do forget the need to confirm the checksum. In this segment, we will work with the minimal installation image, but you should be aware that there are other installation options available to you, such as NetInstall, DVD, Everything, and various LiveCDs.

 

Downloading an image and running a container on CentOS

A common misconception is that Docker is a system for running containers. Docker is only a build-tool to wrap up any piece of Linux based software with all its dependencies in a complete filesystem that contains everything it needs to run: code, runtime, system tools, and system libraries. The technology to run Linux containers is called operating-systemlevel virtualization and provides multiple isolated environments built in every modern Linux kernel by default. This guarantees that it will always run the same, regardless of the environment it is deployed in; thus making your application portable. Therefore, when it comes to distributing your Docker applications into Linux containers, two major conceptional terms must be introduced: Docker images and containers. If you ever wanted to set up and run your own WordPress installation, in this process we will show you how to do so the fastest way possible by downloading a pre-made WordPress image from the official Docker hub; we will then run a container from.

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 Docker images. It is expected that Docker has already been installed and is running.

The Process

The official WordPress image from Docker Hub does not contain its own MySQL server. Instead, it relies on it externally, so we will start this process by installing and running a MySQL docker container from Docker Hub.

  1. To begin, log in as root and type the following command by replacing in the following command with a strong MySQL database password of your own choice (at the time of writing, the latest WordPress needs MySQL v.5.7; this can change in the future, so check out the official WordPress Docker Hub page):
    docker run --restart=always --name wordpressdb -e MYSQL_ROOT_PASSWORD= -e MYSQL_DATABASE=wordpress -d mysql:5.7
  2. Next, install and run the official WordPress image and run an instance of it as a Docker container, connecting it to the MySQL container (providing the same string from the previous step):
    docker run --restart=always -e WORDPRESS_DB_PASSWORD=
    -d -name wordpress --link wordpressdb:mysql -p 8080:80 wordpress
  3. Now the MySQL and WordPress container should already be running. To check the currently running containers, type:
    docker ps
  4. To get all the Docker WordPress container settings, use:
    docker inspect wordpress
  5. To check the container’s log file for our WordPress container, run the following command:
    docker logs -f wordpress
  6. Open a browser on a computer in the same network as the server running the Docker daemon and type in the following command to access your Wordpress installation (replace IP address with the one from your Docker server):
    http://:8080/

How Does It Work?

A Docker image is a collection of all the files that make up a software application and its functional dependencies, as well as information about any changes as you modify or improve on its content (in the form of a change log). It is a non-runnable, read-only version of your application and can be compared to an ISO file. If you want to run such an image, a Linux container will be created out of it automatically by cloning the image. This is what then actually executes. It’s a real scalable system because you can run multiple containers from the same image. As we have seen, Docker is really not only the tools you need to work with images and containers but a complete platform as it also provides tools to access already pre-made images of all kinds of Linux server software. This is really the beauty of the whole Docker system because most of the time you don’t have to reinvent the wheel twice trying to create your own docker image from scratch. Just go to the Docker Hub ( https://hub.docker.com ), search for a software you want to run as a container, and when you find it then just use the docker run command, providing the Docker Hub name of the image, and you are done. Docker really can be a life-saver when thinking about all the endless hours trying to get the latest trendy programs to work with all the dependencies you need to compile and trying to get it to install.

So what did we learn from this experience?

We started our journey by using the docker run command which downloaded two images from the remote Docker Hub repos and put them into a local image store (called mysql:5.7 and wordpress) and then run them (create containers out of them). To get a list of all the images downloaded on our machine, type docker images. As we have seen, both run command lines provided the -e command line parameter, which we need to set some essential environment variables that will then be visible within the container. These include the MySQL database we want to run and the MySQL root password to set and access them. Here we see a very important feature of Docker: containers that can communicate which each other! Often you can just stack your application together from different Docker container pieces and make the whole system very easy to use. Another important parameter was -p which is used to create a port mapping from our host port 8080 to the internal HTTP port 80 and opens the firewall to allow incoming traffic on this port as well. --restart=always is useful to make the image container restartable, so the containers automatically get restarted on reboot of the host machine. Afterwards, we introduced you to Docker’s ps command line parameter which prints out all running Docker containers. Here the command should print out two running containers called wordpressdb and wordpress, together with their CONTAINER_ID. This ID is a unique MD5 hash we will use all the time in most of the Docker command line inputs whenever we need to reference a specific container (in this process we referenced by container name which is also possible). Afterwards, we showed you how to print out a container’s configuration by using the inspect parameter. Then, to get the Wordpress container’s log file in an open stream, we used the log -f parameter. Finally, since the -p 8080:80 mapping allows incoming access to our server at port 8080, we could then access our Wordpress installation from any computer in the same network using a browser. This will open the Wordpress installation screen.

Note
Note that if you have any connection problems while downloading any containers from Docker at any time, such as dial tcp: lookup index.docker.io: no such host, restart the Docker service before trying again.

There's more…

In this section, we will show you how to start and stop a container and how to attach to your container.

Stopping and starting a container

In the main process, we used Docker’s run command which is actually a wrapper for two other Docker commands: create and start. As the names of these commands suggest, the create command creates (clones) a container from an existing image and if it does not exist in the local image cache then it downloads it from a given Docker registry (such as the predefined Docker hub), while the start command actually starts it. To get a list of all the containers (running or stopped) on your computer, type: docker ps -a. Now identify a stopped or a started container, and find out its specific CONTAINER_ID. Then we can start a stopped container or stop a running one by providing the correct CONTAINER_ID such as docker start CONTAINER_ID. Examples are: docker start 03b53947d812 or docker stop a2fe12e61545 (the CONTAINER_ID hashes will vary on your computer).

Sometimes you need to remove a container; for example, if you want to completely change its command line parameters when creating from an image. For removing a container, use the rm command (but remember that it has to be stopped before): docker
stop b7f720fbfd23; docker rm b7f720fbfd23

Attaching and interacting with your container

Linux containers are completely isolated processes running in a separated environment on your server and there is no way to log in to it like logging into a normal server using ssh. If you need to access your containers BASH shell then you can run the docker exec command, which is particularly useful for debugging problems or modifying your container (for example, installing new packages or updating programs or files in it). Note that this only works on running containers and you need to know your container’s ID before (type docker ps to find out) you run the following command: docker exec -it CONTAINER_ID /bin/bash, for example docker exec -it d22ddf594f0d /bin/bash. Once successfully attached to the container, you will see a slightly changed command-line prompt with the CONTAINER_ID as hostname; for example, root@d22ddf594f0d:/var/www/html#. If you need to exit your container, type exit.

 

Allowing remote access to a MariaDB server on CentOS

Unless you are running your MariaDB database server to drive some local web applications on the same server hardware, most working environments would be pretty useless if remote access to a database server were forbidden. In many IT surroundings, you will find high-available, centralized dedicated database servers optimized in hardware (for example, huge amounts of RAM) and hosting multiple databases allowing hundreds of parallel connections from the outside to the server. Here in this process, we will show you how to make remote connections to the server possible.

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 expected that a MariaDB server is already installed and running and you have read and applied the Managing a MariaDB database process for an understanding of permissions and how to test (local) database connections.

The Process

In our example, we want to access a MariaDB database server with the IP address 192.168.1.12 from a client computer in the same network, with the IP address 192.168.1.33. Please change appropriately to fit your needs:

  1. To begin, log in as root on your MariaDB database server and open the firewall for the incoming MariaDB connections:
    firewall-cmd --permanent --add-service=mysql && firewall-cmd --reload
  2. Afterwards, we need to create a user account which can connect to our MariaDB server remotely (as we have prevented root from doing this in a further step for security reasons), login your database server using the MariaDB command line interface mysql as user root and type the following MariaDB statement (replacing the XXXX with a password of your choice, also feel free to adjust the username and remote IP of the client who wants to connect to the server—in our case the client has the IP 192.168.1.33—accordingly):
    GRANT SELECT ON mysql.user TO 'johndoe'@'192.168.1.33' IDENTIFIED BY
    'XXXX';
    FLUSH PRIVILEGES;EXIT;
  3. Now we can test the connection from our client computer with the IP address of 192.168.1.33 in our network. This computer needs the MariaDB shell installed (on a CentOS 7 client, install the package mariadb) and needs to be able to ping the server running the MariaDB service (in our example, the IP 192.168.1.12). You can test connecting to the server by using the following command (on success, this will print out the content of the mysql user table):
    echo "select user from mysql.user" | mysql -u johndoe -p mysql -h
    192.168.1.12

How Does It Work?

We started our journey by opening the standard MariaDB firewall port 3306 using the firewalld predefined MariaDB service, which is disabled by default on CentOS 7. After this, we configured which IP addresses were allowed to access our database server, which is done on a database level using the MariaDB shell. In our example, we used the GRANT SELECT command to allow the user johndoe at the client IP address 192.168.1.33 and with the password in quotes 'XXXX' to access the database with the name mysql and the table user to make SELECT queries only. Remember, here you can also apply wildcards in the field using the % sign (which means any characters). For example, for defining any possible hostname combination in a Class C network, you can use the % sign like so 192.168.1.%. Granting access to the mysql.user database and table was just for testing purposes only and you should remove the user johndoe from this access permission whenever you have finished your tests, using: REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'johndoe'@'192.168.1.33';. If you want you can also delete the user DROP USER 'johndoe'@'192.168.1.33'; because we don’t need it anymore.

 

Running a DHCP server on CentOS

If a connection to a network needs to be made, every computer needs a correct Internet Protocol (IP) configuration installed on their system to communicate. Assigning IP client configurations automatically from a central point using the Dynamic Host Control Protocol (DHCP) can make the administrator’s life easier and simplify the process of adding new machines to a network in comparison to the tedious work of manually setting up static IP information on each computer system in your network. In small home-based networks, people often use DHCP servers directly installed in silico on their Internet routers, but such devices often lack advanced features and have only a basic set of configuration options available. Most of the time, this is not sufficient for bigger networks or in the corporate environment, where you are more likely to find dedicated DCHP servers for more complex scenarios and better control. In this process, we will show you how to install and configure a DHCP server on a CentOS 7 system.

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. It is expected that your DHCP server will be using a static IP address; if you do not have one, refer to the process Building a static network connection, Configuring the System. If you plan to send DNS information to the clients through DHCP as well, you should have already applied the process Installing and configuring a simple nameserver, Working with FTP.

The Process

Here in this example, we will configure a DHCP server for a static network interface serving a single network with all its available IP addresses to all the computers connected directly to it (they are all in the same subnet).

  1. First, log in as root and type the following command in order to install the DHCP server packages:
    yum install dhcp
  2. In our example, we will use a network interface with the name, ifcfg-enp5s0f1, to serve our DHCP requests. Next, we need to collect some very important network information, which we will use later for configuring the DHCP server (change the network interface name to fit your own needs):
    cat /etc/sysconfig/network-scripts/ifcfg-enp5s0f1
  3. From this output, we need the following information, so please write it down (most likely, your output will be different):
    BOOTPROTO="static"
    IPADDR="192.168.1.8"
    NETMASK="255.255.255.0"
    GATEWAY="192.168.1.254"
  4. We also need the subnet network address, which can be calculated using the following line:
    ipcalc -n 192.168.1.8/24
  5. This will print the following output (write it down for later):
    NETWORK=192.168.1.0
  6. Now, we will open our main DHCP configuration file, after we make a backup of the original file:
    cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.BAK vi /etc/dhcp/dhcpd.conf
  7. Append the following lines to the end of the file, taking into account your individual network interface’s configuration from the preceding steps (routers = GATEWAY, subnet = NETWORK):
    authoriative;
    default-lease-time 28800;
    max-lease-time 86400;
    shared-network MyNetwork {
          option domain-name            "example.com";
          option domain-name-servers      8.8.8.8, 8.8.4.4;
          option routers                              192.168.1.254;
          subnet 192.168.1.0 netmask 255.255.255.0 {
              range 192.168.1.10 192.168.1.160;
          }
  8. Finally, start and enable the DHCP service:
    systemctl start dhcpd
    systemctl enable dhcpd

How Does It Work?

Here in this process, we showed you how easy it is to set up a DHCP server for a single network. With this, every time a new machine gets added to the network, the computer gets the correct IP information automatically, which it needs in order to connect to the network without any further human action.

So, what did we learn from this experience?

We started this process by installing the DHCP server package because it does not come with CentOS 7 out-of-the-box. Since our DHCP daemon communicates with its clients to assign IP information over a network interface, in the next step we had to choose a network device that would be used for the service. In our example, we selected a device named enp5s0f1. By default, the DHCP server can manage all available IP addresses from the same subnet as the associated network interface. Remember that your primary DHCP server’s network interface must be configured to get its own IP information statically and not through (another) DHCP server! Next, we used the cat command to print out all the interesting lines from our enp5s0f1 network interface configuration file, which we will need for configuring the DHCP server. Afterwards, we used the ipcalc tool to calculate the (subnet) network address for our DHCP server’s network interface. Then, we opened the main DHCP server configuration, started configuring some global settings, and defined a new shared network. In the global settings, we first set our DHCP server to be authoritative, which means it is the only and main responsible DHCP server in the network. Next, we defined default-lease-time to 28800 seconds, which is eight hours, and the max-lease-time to 86400, which is 24 hours. The lease time is the amount of time the DHCP server “rents out” an IP address to a client before it has to sign up again on the DHCP server asking for an extension of the IP. If it is not requesting a renewal of an existing lease at that time, the IP address will be released from the client and put into the pool of free IP addresses again, ready to be served to new machines that want to connect to the network. The client can define the amount of time it wants to lease an IP address by itself. If no time frame has been supplied from the client to the DHCP server, the default lease time will be used.

All subnets that share the same physical network interface should be defined within a shared-network declaration, so we defined this area using square brackets. This is also called a scope. In our example, we only have one network, so we only need one shared-network scope. Within it, we first defined a domain-name option, which will be sent and can be used by clients as their base domain name. Next, we added the domain name servers (DNS) to our configuration. Sending DNS information to the client is not mandatory for the DHCP server but can be useful. The more information a client gets for a given network, the better because fewer manual configuration steps have to be made.

Note
You can send out a lot of other useful information to the client (using DHCP) about the network he is connecting to: gateway, time, WINS, and so on.

Here in our example, we used the official Google DNS servers; if you have already set up your own DNS server, you could also use these addresses here. Next, we specified a routers option, which is another useful piece of information that will be sent out to the clients as well. Afterwards, we specified the most important part of any DHCP server: the subnet scope. Here, we defined our network ranges for assigning IP addresses for clients. We need to provide the subnet network address, its submask, and then the starting and ending IP address range that we want to allow to clients. In our example, we allow host IP addresses from 192.168.1.10, 192.168.1.11, 192.168.1.12 … to 192.168.1.160. If you have more than one subnet, you can use multiple subnet scope directives (called a multihomed DHCP server).

Next, we started the DHCP server and enabled it on boot. Your clients should now be able to get IP addresses dynamically from our new system.

In summary, we have only shown you some very basic DHCP server configuration options to get you started, and there are many more settings available, letting you build very complex DHCP server solutions. To get a better overview of its possibilities, please have a look at the example configuration file provided with the DHCP server documentation at less /usr/share/doc/dhcp-4*/dhcpd.conf.example.

There's more…

In the main process, we configured our basic DHCP server to be able to send complete IP network information to our clients so that they should be able to join our network. To use this server, you need to enable DHCP addressing on your client’s network interfaces. On CentOS clients, please do not forget to use BOOTPROTO=dhcp and remove all static entries such as IPADDR in the appropriate network-scripts ifcfg file (read the process, Building a static network connection, Configuring the System to get you started on network-scripts files). Then, to make a DHCP request, restart the network using systemctl restart network or try to do a reboot of the client system (with the ONBOOT=yes option). Confirm with ip addr list.

 

Priorities in CentOS

In this process, we will investigate the task of preparing YUM to manage additional repositories by installing a plugin known as YUM priorities. YUM has the ability to search, remove, install, retrieve, and update packages from various remote locations. Such features make YUM a powerful tool, but if you ever decide to add an additional third-party repository, there is a chance that conflicts will render the system unstable. Stability is one of the many advantages of using the CentOS operating system, and it is the purpose of this process to show you how this confidence can be maintained while simultaneously allowing for the addition of new repositories.

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.

The Process:

This process will show you how to prepare YUM in order to manage the process of using one or more third-party repositories by installing and configuring YUM priorities:

  1. To begin this process, log in as root and type the following:
    yum install yum-plugin-priorities
  2. Confirm the installation, and when complete type what is shown here:
    vi /etc/yum/pluginconf.d/priorities.conf
  3. You should ensure that this file indicates that the plugin is enabled. It should show the instruction enabled = 1. It is not expected that you will need to change anything in this file, but if you have made any changes, simply save and close the file before proceeding.
  4. We now need to establish a priority value for each repository. This is a numeric value in ascending order, where the highest priority is given the lowest number. To do this, open the following file as shown next:
    vi /etc/yum.repos.d/CentOS-Base.repo
  5. Add the following line at the end of the [base] section:
    priority=1
  6. Now, add the following line at the end of the [updates] section:
    priority=1
  7. And finally, add the following line at the end of the [extras] section:
    priority=1
  8. When complete, save and close the file before running a package update:
    yum update

How Does It Work?

YUM priorities is a simple plugin that enables YUM to decide what repositories will assume the highest priority when installing and updating new packages. Using this plugin will reduce the chance of package confusion by ensuring that any particular package will always be installed or updated from the same repository. In this way, you can add an unlimited number of repositories and enable YUM to stay in control of package management.

So, what did we learn from this experience?

Enhancing YUM with this plugin was simply a matter of installing the yum-pluginpriorities package and ensuring that it was enabled in its configuration file. We then discovered that the priority is set in ascending order, where the lowest values are given precedence over all others. This, of course, serves to simplify the overall process, and for this reason, we ensured that the default repositories were given a value of 1 (priority=1).

This will ensure that the default repositories maintain the highest priority, so when you do decide to add additional repositories you could assign them a priority value of 2, 3, 4… and 10, or more. On the other hand, it should be noted that we only set this value across three main sections: [base], [updates], and [extras]. In simple terms, this was only because the other sections are shown to be disabled. For example, you may have noticed that the [centosplus] section in /etc/yum.repos.d/CentOS-Base.repo include the following line: enabled=0, whereas the [updates] and [extras] sections show this value as enabled=1. Of course, if you intend to activate this repository, you will need to set a priority value for it, but for the purpose of this process, such an action was not required.
Finally, we ran a simple YUM package update in order to activate our revised settings.

So, as we can see, YUM priorities is an extremely flexible package that enables you to determine what repositories take priority when you want to expand your installation options. However, you should always be aware that YUM priorities may not be appropriate for your system, as you are giving it the power to decide what packages are to be ignored, what packages are installed, what packages are updated, and in what order and from which repository you will get them. For most users who tend not to stay away from the typical server functions, this may not be an immediate concern; you may even safely ignore this warning. But if stability and security are an overriding concern, and you do intend to use additional packages from external repositories, then you should give careful consideration to the use of this plugin or at least consider and research the integrity of the third-party repositories used.

 

Customizing CentOS system banners and messages

In this process, we will learn how to display a welcome message if a user successfully logs in to our CentOS 7 system using SSH or console, or opens a new terminal window in a graphical window manager. This is often used to show the user informative messages, or for legal reasons.

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 and a console-based text editor of your choice.

The Process

  1. To begin, log in to your system using your root user account and create the following new file with your favorite text editor:
    vi /etc/motd
  2. Next, we will put in the following content in this new file:
    ###############################################
    # This computer system is for authorized users only.
    # All activity is logged and regularly checked.
    # Individuals using this system without authority or
    # in excess of their authority are subject to
    # having all their services revoked…
    ###############################################
  3. Save and close this file.
  4. Congratulations, you have now set a banner message for whenever a user successfully logs in to the system using ssh or a console.

How it works...

For legal reasons, it is strongly recommended that computers display a banner before allowing users to log in; lawyers suggest that the offense of unauthorized access can only be committed if the offender knows at the time that the access he intends to obtain is unauthorized. Login banners are the best way to achieve this. Apart from this reason, you can provide the user with useful system information.

So, what did we learn from this experience?

We started this process by opening the file, /etc/motd, which stands for a message of the day; this content will be displayed after a user logged in a console or ssh. Next, we put in that file a standard legal disclaimer and saved the file.

There's more…

As we have seen, the /etc/motd file displays static text after a user successfully logs in to the system. If you want to also display a message when an ssh connection is first established, you can use ssh banners. The banner behavior is disabled in the ssh daemon configuration file by default, which means that no message will be displayed if a user establishes an ssh connection. To enable this feature, log in as root on your server and open the /etc/ssh/sshd_config file using your favorite text editor, and put in the following content at the end of the file:
Banner /etc/ssh-banner

Then, create and open a new file called /etc/ssh-banner, and put in a new custom ssh greeting message.

Finally, restart your ssh daemon using the following line:
systemctl restart sshd.service

The next time someone establishes an ssh connection to your server, this new message will be printed out.

The motd file can only print static messages and some system information details, but it is impossible to generate real dynamic messages or use bash commands in it if a user successfully logs in.

Also, motd does not work in non-login shells, such as when you open a new terminal within a graphical window manager. In order to achieve this, we can create a custom script in the /etc/profile.d directory. All scripts in this directory get executed automatically if a user logs in to the system. First, we delete any content in the /etc/motd file, as we don’t want to display two welcome banners. Then, we open the new file, /etc/profile.d/motd.sh, with our text editor and create a custom message, such as the following, where we can use bash commands and write little scripts (use the backticks to run bash shell commands in this file):

#!/bin/bash
echo -e "
##################################
#
# Welcome to `hostname`, you are logged in as `whoami`
# This system is running `cat /etc/redhat-release`
# kernel is `uname -r`
# Uptime is
`uptime | sed 's/.*up ([^,]*), .*/1/'`
# Mem total `cat /proc/meminfo | grep MemTotal | awk {'print $2'}` kB
###################################"

 

CentOS Introduction

CentOS is a community-based enterprise-class operating system. It is available free of charge, and as a fully compatible derivative of Red Hat Enterprise Linux (RHEL), it represents the first choice operating system for organizations, companies, professionals, and home users all over the world who intend to run a server. It's widely respected as a very powerful and flexible Linux distribution and regardless as to whether you intend to run a web server, file server, FTP server, domain server, or a multi-role solution, it is the purpose of this book to deliver a series of turn-key solutions that will show you how quickly you can build a fully capable and comprehensive server system using the CentOS 6 operating system.

Installing and configuring Docker on CentOS

Traditional virtualization technologies provide hardware virtualization, which means they create a complete hardware environment so each virtual machine (VM) needs a complete operating system to run it. Therefore they have some major drawbacks because they are heavyweight and produce a lot of overhead while running. This is where the open-source Docker containerization engine offers an attractive alternative. It can help you build applications in Linux containers, thus providing application virtualization.

This means that you can bundle any Linux program of choice with all its dependencies and its own environment and then share it or run multiple instances of it, each as a completely isolated and separated process on any modern Linux kernel, thus providing native runtime performance, easy portability, and high scalability. Here, in this process, we will show you how to install and configure Docker on your CentOS 7 server.

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 rpm packages and a test Docker image.

The Process

While Docker is available as a package in the official CentOS 7 repository, we will use the official Docker repository to install it on our system instead.

  1. To begin, log in as root and update your YUM packages before downloading and executing the official Docker Linux installation script using the following command:
    yum update && curl -sSL https://get.docker.com/ | sh
  2. Next, enable Docker at boot time before starting the Docker daemon (the first time you start, it will take a while):
    systemctl enable docker && systemctl start docker
  3. Finally, after starting Docker you can verify that it’s working by typing:
    docker run hello-world

How Does It Work?

When installing any software on CentOS 7, most of the time it is very good advice to use the packages available in your official CentOS repository instead of downloading and installing from third-party locations. Hereby installing Docker using the official Docker repository instead, we made an exception. We did this because Docker is a very young project and is evolving fast, and it keeps changing a lot. While you can use Docker for running every Linux application, including critical web servers or programs dealing with confidential data, bugs found or introduced into the Docker program can have severe security consequences. By using the official Docker repository, we make sure we always get the latest updates and patches available as fast as possible right from the developers of this fast-moving project. So anytime you type yum update in the future, your package manager will automatically query and check the Docker repos to see if there is a new version of Docker available for you.

So what did we learn from this experience?

We started this process by logging into our server as root and updated the YUM package’s database. Then we used a command to download and execute the official Docker installation script from https://get.docker.com/ in one step. What this script does is add the official Docker repository to the YUM package manager as a new package source and then automatically install Docker in the background. Afterwards, we enabled the Docker service at boot-time and started it by using systemd. Finally, to test our installation, we issued the command docker run hello-world, which downloads a special image from the official Docker registry to test our installation. If everything went fine, you should see the following success message (output truncated):
Hello from Docker

This message shows that your installation appears to be working correctly.

 

Managing a MariaDB database on CentOS

In this process, we will learn how to create a new database and database user for the MariaDB server. MariaDB can be used in conjunction with a wide variety of graphical tools (for example, the free MySQL Workbench), but in situations where you simply need to create a database, provide an associated user, and assign the correct permissions, it is often useful to perform this task from the command line. Known as the MariaDB shell, this simple interactive and text based-command line facility supports the full range of SQL commands and affords both local and remote access to your database server. The shell provides you with complete control over your database server, and for this reason, it represents the perfect tool for you to start your MariaDB work.

To Start With: What Do You Need?

To complete this process, you will require a working installation of the CentOS 7 operating system. It is expected that a MariaDB server is already installed and running on your server.

The Process

The MariaDB command-line tool supports executing commands in both the batch mode (reading from a file or standard input) and interactively (typing in statements and waiting for the results). We will use the latter in this process.

  1. To begin, log in on your CentOS 7 server with any system user you like and type the following command in order to access the MariaDB server using the MariaDB shell with the main MariaDB administration user called root (use the password created in the previous process):
    mysql -u root -p
  2. On successful login, you will be greeted with the MariaDB command-line interface. This feature is signified by the MariaDB shell prompt:
    MariaDB [(none)]>
  3. In this first step, we will create a new database. To do this, simply customize the following command by substituting an appropriate value for the new value using:
    CREATE DATABASE CHARACTER SET utf8 COLLATE utf8_general_ci;

    Note
    If this is your first introduction to the MariaDB shell, remember to end each line with a semi-colon (;) and press the Enter key after typing each command.

  4. Having created our database, we will now create a MariaDB user. Each user will consist of a username and a password that is completely independent of the operating system’s user. For reasons of security, we will ensure that access to the database is restricted to localhost only. To proceed, simply customize the following command by changing the values ,
    , and to reflect your needs:
    GRANT ALL ON .* TO ''@'localhost' IDENTIFIED BY '
    ' WITH GRANT OPTION;
  5. Next, make the MariaDB DBMS aware of your new user:
    FLUSH PRIVILEGES;
  6. Now simply type the following command to exit the MariaDB shell:
    EXIT;
  7. Finally, you can test the accessibility of your new by accessing the MariaDB shell from the command-line in the following way:
    mysql -u -p
  8. Now back at the MariaDB shell (MariaDB [(none)]>), type the following commands:
    SHOW DATABASES;
    EXIT;

How Does It Work?

During the course of this process, you were shown not only how to create a database, but also how to create a database user.

So what did we learn from this experience?

We started the process by accessing the MariaDB shell as the root user with the mysql command. By doing this, we were then able to create a database with a simple SQL function called CREATE DATABASE, providing a custom name for the field. We also specified utf8 as the character set of our new database together with a utf8_general_ci collation. A character set is how the characters are encoded in the database and a collation is a set of rules for comparing the characters in a character set. For historical reasons and to keep MariaDB backward-compatible with the older server versions, the default character set is latin1 and latin1_swedish_ci, but for any modern databases, you should always prefer to use utf-8 instead as it is the most standard and compatible encoding for international character sets (non-English alphabets). However, this command can be modified to invoke the need to check if a database name is already in use by using: CREATE DATABASE IF NOT EXISTS . In this way, you can then drop or remove a database by using the following command:
DROP DATABASE IF EXISTS ;

Having done this, it is simply a matter of adding a new database user with the appropriate permissions by running our GRANT ALL command. Here we provided with full privileges via a defined
for localhost. As a specific was elected, then this level of permission will be restricted to that particular database and using .* allows us to specify these rules to all the tables (using the asterisks symbol) in this database. The general syntax in order to provide a chosen user with specific permission is:
GRANT [type of permission] ON .

TO ''@'';

For security reasons, here in this process, we limit to localhost but if you want to grant permissions to remote users you will need to change this value (see later). In our example, we set [type of permission] to ALL but you can always decide to minimize the privileges by providing a single or a comma-separated list of privilege-types offered in the following way:
GRANT SELECT, INSERT, DELETE ON .* TO ''@'localhost';

Using the previous technique, here is a summary of the permissions that can be employed:

  • ALL: Allows the value with all available privilege-types
  • CREATE: Allows the value to create new tables or databases
  • DROP: Allows the value to delete tables or databases
  • DELETE: Allows the value to delete rows from tables
  • INSERT: Allows the value to insert rows into tables
  • SELECT: Allows the value to read from tables
  • UPDATE: Allows the value to update table rows

However, once the privileges were granted, the process then showed you that we must FLUSH the system in order to make our new settings available to the system itself. It is important to note that all commands within the MariaDB shell should end in a semicolon (;). Having completed our task, we simply exit the console using the EXIT; statement.

MariaDB is an excellent database system but like all services, it can be abused. So remain vigilant at all times, and by considering the previous advice, you can be confident that your MariaDB installation will remain safe and secure.

There's more…

Creating a restricted user is one way of providing database access but if you have a team of developers who require constant access to a development server, you may wish to consider providing a universal user who maintains superuser privilege. To do this, simply login to the MariaDB shell with your administrator user root, then create a new user in the following way:
GRANT ALL ON *.* TO ''@'localhost' IDENTIFIED BY '
' WITH GRANT OPTION;

By doing this, you will enable to add, delete, and manage databases across your entire MariaDB server (the asterisks in *.* tell MariaDB to apply the privileges to all the databases and all their associated tables found on the database server), but given the range of administrative features, this new user account will restrict all activities to localhost only. So in simple terms, if you want to provide with access to any database or to any table, always use an asterisk (*) in place of the database name or table name. Finally, every time you update or change a user permission, always be sure to use the FLUSH PRIVILEGES command before exiting the MariaDB shell with the EXIT; command.

Reviewing and revoking permissions or dropping a user on CentOS
It is never a good idea to keep user accounts active unless they are used, so your first consideration within the MariaDB shell (login with your administrator user root) will be to review their current status by typing:
SELECT HOST,USER FROM mysql.user WHERE USER='';

Having done this, if you intend to REVOKE permission(s) or remove a user listed here, you can do this with the DROP command. First of all, you should review what privileges the user of interest has by running:
SHOW GRANTS FOR ''@'localhost';

You now have two options, starting with the ability to revoke the user’s privileges as follows:
REVOKE ALL PRIVILEGES, GRANT OPTION FROM ''@'localhost';

Then you may either reallocate the privilege using the formula provided in the main process or alternatively, you can decide to remove the user by typing:
DROP USER ''@'localhost';

Finally, update all your privileges the usual way using FLUSH PRIVILEGES; before exiting the shell EXIT; command.

 

Printing with CUPS in CentOS

Print servers allow local printing devices to be connected to a network and be shared among several users and departments. There are many advantages using such a system, including the lack of a need to buy dedicated printer hardware for each user, room, or department. The Common Unix Printing System (CUPS) is the de-facto standard for print servers on Linux, as well as Unix distributions including OS X. It is built with a typical client/server architecture, where clients in the network send print jobs to the centralized print server that schedules these tasks, then delegates and executes the actual printing on a printer that is locally connected to our printer server or sends the print job remotely to the computer that has the physical connection to the requested printer or to a standalone network printer. If you set up your printers within the CUPS system, almost all Linux and OS X printing application on any client in your network will be automatically configured to use them out-of-the-box, without the need to install additional drivers. Here, in this process, we will show you how to get started with the CUPS printing server system.

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. In this process, we will use the network interface with the IP address, 192.168.1.8, and the corresponding network address of 192.168.1.0/24 to serve the CUPS printer server to our network.

The Process

We begin this process by installing the CUPS printing server software, which is not available by default on a fresh CentOS 7 minimal system:

  1. To do this, log in as root and install the following package:
    yum install cups
  2. Next, create an SSL certificate for the CUPS server, which we will need for secure authentication to the CUPS web application (add a secure password when asked):
    cd /etc/pki/tls/certs make cups-server.key
  3. Now, let’s open the CUPS main configuration file to customize the server (backup first):
    cp /etc/cups/cupsd.conf /etc/cups/cupsd.conf.BAK vi /etc/cups/cupsd.conf
  4. First, to make CUPS available on the entire network, find the following line: Listen localhost:631, than change it to:
    Listen 631
  5. Next, we want to configure access to all normal web pages of the web-based CUPS frontend. Search for the directive (don’t confuse this with other directives such as ) and change the complete block by adding your network address. After changing, the complete block looks like this:

    Order allow,deny
    Allow 192.168.1.0/24
  6. Next, set access permissions for the /admin and /admin/conf Location directives, granting access to the local server only:

           Order allow,deny
            Allow localhost


            AuthType Default Require user @SYSTEM
            Order allow,deny
            Allow localhost
  7. Finally, add our SSL certificate information to the end of the configuration file:
    ServerCertificate /etc/pki/tls/certs/cups-server.crt
    ServerKey /etc/pki/tls/certs/cups-server.key
  8. Close and save the file, then restart the CUPS server and enable it on boot:
    systemctl restart cups.service systemctl enable cups.service
  9. Now, we have to open the CUPS server ports in firewalld so that other computers in the network can connect to it:
    firewall-cmd --permanent --add-service=ipp firewall-cmd --reload
  10. You can test the accessibility of your CUPS server from another computer in your 192.168.1.0/24 network by browsing to the following location (allow a security exception in the browser when asked):
    https://:631
  11. To access the administration area within the CUPS frontend, you need to be on the same server as CUPS is running (on a CentOS 7 minimal installation, please install a window manager and browser), and then use the system user, root, with the appropriate password to login.

How Does It Work?

In this process, we showed you how easy it is to install and set up a CUPS printing server.

So, what did we learn from this experience?

We began our journey by installing the CUPS server package on our server because it is not available on the CentOS 7 system by default. Afterwards, we generated a SSL key-pair, which we will need later in the process (to learn more, read the Generating self-signed certificates process.) It is used to allow the encrypted submission of your login credentials to the CUPS administration web frontend (over secure HTTPS connections). Next, we opened CUPS’s main configuration file, /etc/cups/cupsd.conf, with the text editor of our choice. As you may notice, the configuration format is very similar to the Apache configuration file format. We started changing the Listen address by removing the localhost name, therefore allowing all clients from everywhere in your network (192.168.1.0/24) to access our CUPS server at port 631 instead of allowing only the local interface to connect to the printer server.

Note
By default, the CUPS server has Browsing On enabled, which will broadcast, every 30 seconds, an updated list of all printers that are being shared in the system to all client computers on the same subnet. If you want to broadcast to other subnets as well, use the BrowseRelay directive.

Next, we configured access to the CUPS web interface. This frontend can be used to conveniently browse all available printers on the network, or even install new printers or configure them if you log in with an administrator account. As there are different tasks in the user interface, there are three different directives that can be used to fine-grain its access. Access to all normal web pages can be set using the directive, whereas all administration pages can be managed with and more specifically to change the configuration within the tag. In each of these Location tags, we added different Allow directives, thus granting normal CUPS web pages (such as, browsing all available network printers) from your complete network (for example, 192.168.1.0/24) while accessing the special administration pages is restricted to the server that runs the CUPS service (localhost). Remember, if this is too restrictive for your environment, you can always adjust these Allow settings. Also, there are various other Location types available, such as one that is used for activating our service in additional subnets. Please read the CUPS configuration manual using man cupsd.conf. Next, we configured SSL encryption, thus activating secure https:// addresses for the web interface. Then, we started the CUPS server for the first time and enabled it to start automatically when the server boots up. Finally, we added the ipp firewalld service, thus allowing incoming CUPS client connections to the server.

There's more…

Now that we have successfully set up and configured our CUPS server, it’s time to add some printers to it and print a test page. Here, we will show you how to add two different types of printers to the system using the command line.

Note
Adding or configuring printers can also be done using the graphical web-based CUPS interface.

First, we will install a true network printer that is already available in the same network (in our case, the 192.168.1.0/24 network) as our CUPS server and afterwards a locally connected printer (for example, via USB to our CUPS server or any other computer in the same network).

Note
Why should you want to install an already connected network printer to our CUPS server? CUPS can do much more than just printing: it is a centralized printer server, thus managing to schedule and queuing of printers and their jobs, serving printers in different subnets, and providing unified printing protocols and standards for convenient access on any Linux or Mac client.

How to add a network printer to the CUPS server

To start adding a network printer to our CUPS server, we will use the command lpinfo v to list all the available printing devices or drivers known to the CUPS server. Normally, the CUPS server will automatically identify all locally (USB, parallel, serial, and so on) and remotely available (network protocols such as socket, http, ipp, lpd, and so on) printers from most common printing protocols without any problems. In our example, the following network printer has been successfully identified (the output has been truncated):
network dnssd://Photosmart%20C5100%20series%20%5BF8B652%5D._pdldatastream._tcp.local/

Next, we will install this printer on the CUPS server to put it under its control. First, we need to look for the correct printer driver. As we can see in the last output, it is an HP Photosmart C5100 series printer. So, let’s search for the driver in the list of all currently installed drivers on our CUPS server:
lpinfo --make-and-model HP -m | grep Photosmart

The list does not contain our model C5100, so we have to install an additional HP driver package using:
yum install hplip

Now, if we issue our command again, we can find the correct driver:
lpinfo --make-and-model HP -m | grep Photosmart | grep c5100

Note
For other printer models and manufacturers, there are other driver packages available as well, for example, the gutenprint-cups RPM package.

The correct driver for this printer will be shown as follows:
drv:///hp/hpcups.drv/hp-photosmart_c5100_series.ppd

Now, we have everything ready to install the printer using the following syntax:
lpadmin -p
-v -m -L -E

In our example, we installed it using:
lpadmin -p hp-photosmart -v
"dnssd://Photosmart%20C5100%20series%20%5BF8B652%5D._pdl
datastream._tcp.local/" -m "drv:///hp/hpcups.drv/hp-
photosmart_c5100_series.ppd" -L room123 -E

Now, the printer should be under our CUPS server’s control and should immediately be shared and seen in the entire network from any Linux or OS X computer (on a CentOS 7 minimal client, you will first need to install the cups package as well and enable incoming ipp connections using firewalld’s ipp-client service before any shared network printer information from our CUPS server will become available).

You can later change the configuration of this printer by opening and changing the file at /etc/cups/printers.conf. To actually print a test page, you should now be able to access the printer using its name, hp-photosmart, from any client (on a CentOS 7 minimal client, you would need to install the package cups-client):
echo "Hello printing world" | lpr -P hp-photosmart -H 192.168.1.8:631

How to share a local printer to the CUPS server

If you want to share a local printer physically connected to our CUPS server, just plug in the printer to the system (for example, via USB) and follow the previous process, How to add a network printer to the CUPS server. In the step lpinfo -v, you should see it appear as a usb:// address, so you need to take this address and follow the rest of the steps.

If you want to connect and share a printer on your centralized CUPS server, which is physically connected to any other computer on your CUPS network, install the cups daemon on this other machine (follow all the steps in the main process) and then install the printer driver for it as shown here in this section. This will make sure that the local CUPS daemon will make the printer available on the network, as it would be on our centralized CUPS server. Now that it is available on the network, you can easily add it to our main CUPS server to enjoy all the benefits of a centralized printing server.

Here in this process, we have only scratched the surface and introduced you to the basics of setting up a CUPS server for your network. There is always more to learn, and you can build very complex CUPS server systems managing hundreds of printers in the corporate environment, which is outside the scope of this process.

 

Keeping YUM clean and tidy in CentOS

In this process, we will investigate the role of YUM with regard to ensuring that the working cache remains current. As a part of its typical mode of operation, YUM will create a cache that consists of metadata and packages. These files are very useful, but over time, they will accumulate in size to such an extent that you may find that YUM is acting erratically or not as intended. The frequency of this happening can vary from system to system, but it generally implies that the YUM cache system requires your immediate attention. Such a situation can be quite frustrating, but it is the purpose of this process to provide a quick solution that will serve to assist you in cleaning the cache and restoring
YUM to its original working state.

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.

The Process: 

Before we begin, it is important to realize that, while we are troubleshooting a current problem, this same process can be run as often as required in order to keep YUM in an optimal working state:

  1. We will begin this process by asking YUM to clean any cached package information. To do this, log in as root and type the following:
    yum clean packages
  2. Allow time for your system to respond and when finished, type the following command to remove any cached XML-based metadata:
    yum clean metadata
  3. Again, wait for YUM to respond and when ready, type the following command to remove any cached database files:
    yum clean dbcache
  4. Following this, you will want to clean all the files to confirm the preceding instructions and to ensure that unnecessary disk space is not used. To do this, type the following line:
    yum clean all
  5. Finally, you will want to rebuild the YUM cache by typing what is shown next:
    yum makecache

How Does It Work?

YUM is a very powerful tool that is known for its ability to resolve package dependencies and automate the process of package management, but as with all things, there are times when even the best utilities can get confused and may report errors or behave erratically.

Fixing this issue is relatively simple and the approach outlined in this process will also serve to keep your package manager in a healthy running state for the life of your operating system.

So, what have we learned from this experience?

During its typical operation, YUM will create a cache of metadata and packages that can be found at /var/cache/yum. These files are essential, but as they grow in size, this cache will ultimately serve to slow down the overall use of this utility and may even cause some issues. To address this situation, we started by using the following command to clean the current package-based cache using YUM’s clean packages parameter options. We then followed this by cleaning the metadata cache using the command clean metadata, which will remove any excess XML-based files. YUM uses a SQLite database as a part of its normal operation, so the next step was to remove any remaining database files using the clean dbcache parameters. The next step was to clean all files associated with enabled repositories in order to reclaim any unused disk space: yum clean all. Finally, we restored YUM to its normal working state by rebuilding the cache using the makecache option.

There’s More:

On a typical server, YUM is a great tool that will solve the most complex problems related to package dependencies and package management. However, in instances where you have knowingly mixed incompatible repositories or have used incomplete sources, there is a risk that YUM will not be able to help.

Note
Remember, in this situation, you should consider the following advice to be a temporary remedy only. A tendency to ignore any warnings provided by YUM will only lead to bigger problems later on.
If such instances occur, and if the error is RPM-based, as a temporary fix, you can skip broken packages by using the following command:
yum -y update --skip-broken

This command will allow YUM to continue working by bypassing any packages with errors, but as stated earlier this should be regarded as a temporary fix only. You should always be aware that a system with broken dependencies is not considered to be a healthy system. This situation is to be avoided at all costs, and under these circumstances fixing such errors should become your first priority. 

 

Becoming a CentOS superuser

In this process, we will learn how to provide nominated users or groups with the ability to execute a variety of commands with elevated privileges.

On CentOS Linux, many files, folders, or commands can only be accessed or executed by a user called root, which is the name of the user who can control everything on a Linux system. Having one root user per system may suit your needs, but for those who want a greater degree of flexibility, a solid audit trail, and the ability to provide a limited array of administrative capabilities to a select number of trusted users, you have come to the right place. It is the purpose of this process is to show you how to activate and configure the sudo (superuser do) command.

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. It is assumed that your server maintains one or more users (other than root) who qualify for this escalation in powers. If you did not create a system user account during installation, please do so by first before applying the process. 

The Process

To start this process, we will first test the sudo command with a non-privileged user.

  1. To begin, log in to your system using a non-root user account, then type the following to verify that sudo is not enabled (use your user account’s password when asked):
    sudo ls /var/log/audit
  2. This will print the following error output with , which is the user you are currently logged in with:
    is not in the sudoers file. This incident will be reported.
  3. Now, log out the system user using the command:
    logout
  4. Next, log in as root and use the following command to give the non-root user sudo power (change appropriately):
    usermod -G wheel
  5.  Now, you can test if sudo is working by logging out root again and re-logging in the user from step 1, and then trying again:
    sudo ls /var/log/audit
  6.  Congratulations, you’ve now set a normal user to have sudo powers and can view and execute files and directories restricted to the root user.

How it works...

Unlike some Linux distributions, CentOS does not provide sudo by default. Instead, you are typically allowed to access restricted parts of the system with the root user only. This offers a certain degree of security, but for a multi-user server, there is little to no flexibility unless you simply provide these individuals with full administrative root access permissions. This is not advisable, and for this reason, it was the purpose of this process is to show you how to provide one or more users with the right to execute commands with elevated privileges.

So, what did we learn from this experience?

We started by logging in to the system with a normal user account having no root privileges or sudo powers. With this user, we then tried to list a directory that normally only the root user is allowed to see, so we applied the sudo command on it. It failed, giving us the error that we are not in the sudoers list.

The sudo command provides nominated users or groups with the ability to execute a command as if they were the root user. All actions are recorded (in a file called /var/log/secure), so there will be a trace of all the commands and arguments used.

We then logged in as the true root user and added a group called wheel to the system user that we wanted sudo rights for. This group is used as a special administration group and every member of it is granted sudo rights automatically.

From now on, the nominated user can implement sudo in order to execute any command with elevated privileges. To do this, the user would be required to type the word sudo before any command, for example, they could run the following command:
sudo yum update

They will be asked to confirm their user password (not the root password!), and after successful authentication, the program will be executed as the user root.

Finally, we can say that there are three ways to become root on a CentOS Linux system:

First, to log in as the true user root to the system. Second, you can use the command, su – root, while any normal system user is logged in, giving the root user’s password to switch to a root shell prompt permanently. Third, you can give a normal user sudo rights so that they can execute single commands using their own passwords as if they were the root user while staying logged in as themselves.

Note
sudo (superuser do) should not be confused with the su (substitute user) command, which allows you to switch to another user permanently instead of executing only single commands as you would do being the root user.

The sudo command allows great flexibility for servers that have a lot of users, where one administrator is not enough to manage the whole system.

 

Setting up HTTPS with Secure Sockets Layer (SSL) in CentOS

In this process, we will learn how to add a secure connection to the Apache web server by creating a self-signed SSL certificate using OpenSSL. This is often a requirement for web servers if the sites running on them transfer sensitive data such as credit card or login information from the web browser to the server. In a previous process, you were shown how to install the Apache web server, and with the growing demand for secure connections, it is the purpose of this process to show you how to enhance your current server configuration by teaching you how to extend the features of the Apache web server.

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. It is expected that Apache web server has been installed and that it is currently running. Here we will create a new SSL certificate for Apache. If you want to learn more about it, refer to segment Chapter 6, Providing Security for advice on generating self-signed certificates. As a correct domain name is crucial for SSL to work, we will continue naming our Apache web server’s configured domain name centos7.home to make this process work (change it to fit your own needs).

The Process

Apache does not support SSL encryption by default and for this reason, we will begin by installing the necessary package mod_ssl using the yum package manager.

  1. To begin, log in as root and type the following command:
    yum install mod_ssl
  2. During the installation of the mod_ssl package, a self-signed certificate, as well as the key pair for the Apache web server, are generated automatically; these lack a proper common name for your web server’s domain name. Before we can re-generate our own required SSL files using the Makefile in the next steps, we need to delete those files:
    rm /etc/pki/tls/private/localhost.key /etc/pki/tls/certs/localhost.crt
  3. We are now required to create our intended self-signed certificate and server key for our Apache web server. To do this, type the following command:
    cd /etc/pki/tls/certs
  4. To create the self-signed Apache SSL keypair, consisting of the certificate and its embedded public key as well as the private key, type:
    make testcert
  5. In the process of creating the certificate, first you will be asked to enter a new passphrase and then verify it. Afterwards, you need to type it in again for the third time. As usual, enter a secure password. You will then be asked a number of questions. Complete all the required details by paying special attention to the common name value. This value should reflect the domain name of your web server or the IP address the SSL certificate is for. For example, you may type:
    www.centos7.home
  6. When the process of creating your certificate is complete, we will proceed by opening the main Apache SSL configuration in the following way (after making a backup):
    cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.BAK vi /etc/httpd/conf.d/ssl.conf
  7. Scroll down to the section that begins with and locate the line # DocumentRoot "/var/www/html" within this block. Then activate it by removing the # character, so it reads:
    DocumentRoot "/var/www/html"
  8.  Right below, find the line that reads #ServerName www.example.com:443. Activate this line and modify the value shown to match the common name value used during the creation of your certificate, as follows:
    ServerName www.centos7.home:443
  9. Save and close the file, next we need to enable the HTTPS port in our firewalld to allow incoming HTTP SSL connections over port 443:
    firewall-cmd --permanent --add-service=https && firewall-cmd --reload
  10. Now restart the Apache httpd service to apply your changes. Note that if prompted you have to enter the SSL passphrase you added when you created the SSL test certificate:
    systemctl restart httpd
  11. Well done! You can now visit your server with a secure connection by replacing all the available HTTP URLs we have defined for the server using HTTPS instead. For example, go to https://www.centos7.home instead of http://www.centos7.home.

    Note
    When you browse to this website, you will get a warning message that the signing certificate authority is not known. This exception is to be expected when using self-signed certificates and can be confirmed.

     

How Does It Work?

We began the process by installing mod_ssl using the YUM package manager, which is the default Apache module to enable SSL. The next step was then to go to the standard location where all the system’s certificates can be found in CentOS 7, that is, /etc/pki/tls/certs. Here we can find a Makefile, which is a helper script for conveniently generating self-signed SSL test certificates and which hides away complicated command line parameters for the OpenSSL program from you. Remember that the Makefile currently lacks a clean option and therefore every time we run it, we need to delete any old versions of the generated files from a former run manually, otherwise it will not start doing anything. After deleting the old Apache SSL files, we used make with the testcert parameter, which creates self-signed certificates for the Apache web server and puts them in the standard locations, already configured in the ssl.conf file (the SSLCertificateFile and SSLCertificateKeyFile directives), so we didn’t have to change anything here. During the process, you were asked to provide a password before completing a series of questions. Complete the questions but pay special attention to the Common name. As was mentioned in the main process, this value should reflect either the domain name of your server or your IP address. In the next phase, you were required to open Apache’s SSL configuration file in your favorite text editor which can be found at /etc/httpd/conf.d/ssl.conf. In it we enabled the DocumentRoot directive to put it under SSL control and activated the ServerName directive with an expected domain value that must be the same as the one we defined as our common name value. We than saved and closed the configuration file and enabled the HTTPS ports in our firewall, thus allowing incoming connections over the standard HTTPS 443 port. Having completed these steps, you can now enjoy the benefits of a secure connection using a self-signed server certificate. Just type https:// instead of http:// for any URL address available on your Apache web browser. However, if you are intending to use an SSL Certificate on a production server for members of the public, then your best option is to purchase an SSL certificate from a trusted Certificate Authority.

There's more…

We learned that since our SSL certificate is protected by a passphrase, so whenever we need to restart our Apache web server, we need to enter the password. This is impractical for server restarts as Apache will refuse to start without a password. To get rid of the password prompt, we will provide the passphrase in a special file and make sure it is only accessible by root.

  1. Create a backup of the file that will contain your password:
    cp /usr/libexec/httpd-ssl-pass-dialog /usr/libexec/httpd-ssl-passdialog.BAK
  2. Now overwrite this password file with the following content, replacing XXXX in the following command line with your current SSL passphrase:
    echo -e '#!/bin/bash\necho "XXXX"' > /usr/libexec/httpd-ssl-passdialog
  3. Finally, change the permissions so that only root can read and execute them:
    chmod 500 /usr/libexec/httpd-ssl-pass-dialog
 

Installing a MariaDB database server on CentOS

Supporting over 70 collations, more than 30 character sets, multiple storage engines, and deployment in virtualized environment, MySQL is a mission-critical database server that is used by production servers all over the world. It is capable of hosting a vast number of individual databases and it can provide support for various roles across your entire network. MySQL server has become synonymous with the World Wide Web (WWW), is used by desktop software, extends local services, and is one of the world’s most popular relational database systems. The purpose of this process is to show you how to download, install, and lockdown MariaDB, which is the default implementation of MySQL in CentOS 7. MariaDB is open source and fully compatible with MySQL and adds several new features; for example, a non-blocking client API library, new storage engines with better performance, enhanced server status variables, and replication.

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.

The Process

As the MariaDB Database Management System (DBMS) is not installed by default on CentOS 7, we will start this process by installing the required packages.

  1. To begin, log in as root and type the following command to install the required packages:
    yum install mariadb-server mariadb
  2. When complete, ensure the service starts at boot before starting the service:
    systemctl enable mariadb.service && systemctl start mariadb.service
  3. Finally, begin the secure installation process with the following command:
    mysql_secure_installation
  4. When you first run the previous command, you will be asked to provide a password but as this value has not been set, press the Enter key to represent the value (blank) none.
  5. Now you will be asked a number of simple questions which will help you in the process of hardening your MariaDB DBMS system. It is good advice to choose Yes (Y) to every question for maximum security unless you are already a MariaDB expert and really require a certain feature. 
  6. Finally, test if you can connect and login to the MariaDB service locally using the MariaDB command-line client called mysql. The test passes if the following command outputs all the MariaDB user names together with their associated hosts known to the MariaDB server (enter the administrator root password you set in the last step when prompted):
    echo "select User,Host from user" | mysql -u root -p mysql

How Does It Work?

MariaDB is a fast, efficient, multithreaded, and robust SQL database server. It supports multiple users and provides access to a number of storage engines, and by following a few short steps, you now know how to install, secure, and login to your MariaDB server.

So what did we learn from this experience?

We started the process by installing the necessary package for the MariaDB server (mariadb-server) and also the client shell interface (mariadb) for controlling and querying the server. Having done this, we then proceeded to ensure that the MariaDB daemon (mariadb.service) would start during the boot process before we actually started it. At this point we had a working installation, but in order to ensure that our installation was safe we then invoked the secure installation script in order to guide us through a few simple steps to harden our basic installation. As the basic installation process does not enable us to set a default password for the root user, we did it here as a first step in the script, so we could be certain that no one could access the MariaDB root user account without the required authorization. We then discovered that a typical MariaDB installation maintains an anonymous user. The purpose of this is to allow anyone to login to our database server without having to have a valid user account. It is typically used for testing purposes only, and unless you are in unique circumstances that require this facility, it is always advisable to remove this feature. Following this, and to ensure that the root user could not access our MariaDB server installation, we then opted to disallow remote root access before removing the test database and performing a reload of the privilege tables. Finally, we ran a small test to see if we could connect to the database with the root user and query some data from the user table (which is part of the standard mysql database).

Having completed the steps of the process, we have learned that the process of installing and securing the MariaDB server is very simple. Of course, there are always more things that can be done in order to make the installation useful but the purpose of this process was to show you that the most important part of installing your new database system was to make it secure. Remember, the act of running mysql_secure_installation is recommended for all MariaDB servers and it is advisable regardless of whether you are building a development server or one that is used in a production environment. As a server administrator, security should always remain your top priority.

 

Using secure alternatives to FTP on CentOS

While using FTP is still popular to share data or to transfer files over the network, you must be aware that you are using a very unsecure network protocol that has no protection built into it out-of-the-box. This means that, during network transfer, your data is fully exposed to potential attackers. This is not what you want for transferring sensitive data, such as login credentials, at all. To avoid these potential risks, we will show you in this process how to use and set up two alternatives for securing FTP using FTPS (FTP over SSL or FTP/SSL) or SFTPS (SSH-enabled FTP).

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 and a console-based text editor of your choice. You should already have installed and configured a basic vsftpd server (for details check, Providing Web Services for how to do it). Also, for setting up SFTP, we will need to create some self-signed certificates; if you want to know the details behind it, please read the Generating self-signed certificates process.

The Process

You have to choose beforehand if you want to use SFTP or FTPS. These two methods cannot be applied together, so you have to decide which option to choose first. If you switch between those methods, you need to restore the default configuration file state of vsftpd.conf or sshd_config first.

Securing your vsftpd server with SSL–FTPS
To secure your vsftpd server with SSL-FTPS performs the following steps:

  1. Log in as root and go to the standard certificate location:
    cd /etc/pki/tls/certs
  2. Now, let’s create a SSL key pair consisting of the certificate and its embedded public key, as well as the private key in one file for our ftp-server configuration (remember that the Common name value should reflect the domain name of your FTP server):
    make ftp-server.pem
  3. Change to a more secure file access rule:
    chmod 400 /etc/pki/tls/certs/ftp-server.pem
  4. Now, before working on it, first make a backup of the vsftpd.conf file.
    cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.BAK
  5. Now, enable SSL and add the key pair file that we just created to our vsftpd configuration:
    echo "rsa_cert_file=/etc/pki/tls/certs/ftp-server.pem
    ssl_enable=YES
    force_local_data_ssl=YES
    force_local_logins_ssl=YES
    pasv_min_port=40000
    pasv_max_port=40100" >> /etc/vsftpd/vsftpd.conf
  6. Next, we need to add a new firewalld service file, so open the following:
    vi /etc/firewalld/services/ftps.xml
  7. Put in the following content:


    enable FTPS ports
  8. Finally, reload the firewall, add the ftps service, and restart your vsftpd server:
    firewall-cmd --reload; firewall-cmd --permanent --add-service=ftps;
    firewall-cmd --reload
    systemctl restart vsftpd

Securing your vsftpd server using SSH – SFTP
To secure your vsftpd server using SSL-SFTP perform the following steps:

  1. First, create a group for all valid SFTP users:
    groupadd sshftp
  2. We will work on the sshd main config file, so please make a backup before making any changes:
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.BAK
  3. Now, open the sshd_config file, go to the line containing the Subsystem directive, disable it (which means putting a # sign at the beginning of the line), and add the following line to read as shown:
    #Subsystem sftp /usr/libexec/openssh/sftp-server
    Subsystem sftp internal-sftp
  4. Next, add the following lines to the end of the file to enable SFTP:
    Match Group sshftp
    ChrootDirectory /home
    ForceCommand internal-sftp
  5. Finally, restart the sshd daemon.
    systemctl restart sshd

How Does It Work?

Here in this process, you have learned how to make your file sharing more secure by switching from the standard FTP protocol to using FTP over SSL, or FTP over SSH. Regardless of which option you prefer, SSL is used to encrypt the data during transmitting, which helps you keep your privacy. Which variant you choose is up to you, but remember that SFTP is a bit easier to set up as you do not have to configure additional ports or certificates in your firewall, because everything runs over SSH and this should be enabled by default on most systems.

So, what did we learn from this experience?

We began the process by configuring FTPS. We went into a special directory called /etc/pki/tls/certs, where CentOS stores all its certificates. In it, there is a Makefile, which we used to create a .pem file that contains the public/private key pair and a self-signed certificate that we needed for our FTP server’s configuration. Afterwards, we used chmod to ensure that only the root user can read this file. Then, we appended six lines of code to our main vsftpd configuration file (first, we made a backup of the original file); they are pretty self-explanatory: enable the SSL protocol, use the self-signed certificate, disallow any non-SSL communication, and use a static range of passive control ports. Also, we created a new firewall service that will open these passive control ports that are needed for FTPS.

Afterwards, we configured SFTP using a chroot jail. If setting up SFTP without it, every login user can view the root filesystem, which is very insecure. Configuring SFTP is done completely in the main sshd config file. After making a backup of the original file, we changed the FTP subsystem to internal-sftp, which is a newer ftp server version, has better performance, and runs in the same process. Next, we added three lines to the vsftpd configuration file; only users in the sshftp group are using SFTP and are put into a chroot jail and can only view files up to their home directory. ForceCommand ignores all local settings by the users and enforces these rules here instead. To add new chrooted SFTP users, all you have to do is create a standard Linux user account and add them to the sshftp user group.

There's more…

If you want to test your enabled FTPS server, you need an FTP client that supports “FTP over TLS.” You have to find and enable this option in your FTP client’s settings. Under Linux, you can install the lftp client to test if you can connect to our FTPS server. First, install the lftp package (for example, yum install lftp). Then, configure the client using TLS:
echo "set ftp:ssl-auth TLS
set ftp:ssl-force true
set ftp:ssl-protect-list yes
set ftp:ssl-protect-data yes
set ftp:ssl-protect-fxp yes
set ssl:verify-certificate no" >~/.lftprc

Now, you can connect and test your FTPS server using the following:
lftp -u username

If you want to test your enabled SFTP server, you need the program called sftp:
sftp john@ -p 22

Note
You have to remember that all the changes to sshd_config will be reflected in SFTP as well. So, if you disabled root login or ran SSH over a different port than 22, you have to take it into consideration when you try to log in to SFTP.

 

Using YUM to remove packages in CentOS

In this process, we will investigate the role of using YUM with the intention of removing packages from your server. During the lifetime of your server, it is possible that certain applications and services may no longer be required. In such situations, it is typical that you will want to remove such packages in order to optimize your working environment, and it is the purpose of this process to show you how this is done.

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.

The Process:

This process will show you how to remove one or more packages by invoking the yum remove option. To do this, you will need to log in as the root user and complete the following process:

  1. To remove a single package, replace the package_name value with the appropriate value and type the following:
    yum remove package_name
  2. Wait for the transaction summary and confirmation prompt to be displayed, and then press either the Y key to confirm, or the N key to decline the transaction, as shown next:
    Is this ok [y/d/N]: y
  3. If you have declined the transaction, then no further work is required and you will exit YUM. However, if you have confirmed the transaction, then simply watch the progress of package removal until it is confirmed and prints out a Complete! message.

How Does It Work?

Applications that are no longer required can be removed with YUM. The process is very intuitive and similar to installing a new package, and it only requires you to confirm the name of the packages you want to remove.

So, what have we learned from this experience?

Having invoked the remove command, YUM will search your system to discover the relevant package; and by reading the package headers and metadata, it will also determine what dependencies this will affect. For example, if we wanted to remove a package called wget, we would begin by issuing the remove command like so: yum remove wget. YUM,
in turn, would then locate the package details from your system and obtain a transaction summary that may include any necessary dependencies that are no longer required. The transaction printed out will remain pending until you instruct YUM to remove the package(s) concerned. When confirmed, YUM will complete the transaction, which in return will result in the removal of the package or packages. 

You should take extra care if the summary makes reference to any dependencies as these may be required by other RPMs. If you are concerned that certain dependencies should remain on the system, it is often a good idea to end the current transaction and simply de-activate or disable the software concerned. As with the install command, you can also remove multiple packages at a time, leaving a single space between the package names:
yum remove package_name1 package_name2 package_name3

 

CentOS static network connection building

In this process, we will learn how to configure a static IP address for a new or existing CentOS server.

While a dynamically assigned IP address or DHCP reservation may be fine for most desktop and laptop users, if you are setting up a server, it is often the case that you will require a static IP address. From web pages to e-mail, databases to file sharing, a static IP address will become a permanent location from which your server will deliver a range of applications and services, and it is the intention of this process to show you how easily it can be achieved.

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.

The Process

For the purpose of this process, you will be able to find all the relevant files in the directory, /etc/sysconfig/network-scripts/. First, you need to find out the correct name of the network interface that you want to set as static. If you need to set more than one network interface as static, repeat this process for every device.

  1. To do this, log in as root and type the following command to get a list of all of your system’s network interfaces:
    ip addr list
  2. If you have only one network card installed, it should be very easy to find out its name; just select the one not named lo (which is the loopback device). If you got more than one, having a look at the IP addresses of the different devices can help you choose the right one. In our example, the device is called enp0s3.
  3. Next, make a backup of the network interface configuration file (change the enp0s3 part accordingly, if your network interface is named differently):
    cp /etc/sysconfig/network-scripts/ifcfg-enp0s3/etc/sysconfig/networkscripts/ifcfg-enp0s3.BAK

  4. When you are ready to proceed, open the following file in your favorite text editor by typing what is shown next:
    vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

  5. Now, work down the file and apply the following changes:
    NM_CONTROLLED="no"
    BOOTPROTO=none
    DEFROUTE=yes
    PEERDNS=no
    PEERROUTES=yes
    IPV4_FAILURE_FATAL=yes

  6. Now, add your IP information by customizing the values of XXX.XXX.XXX.XXX as required:
    IPADDR=XXX.XXX.XXX.XXX
    NETMASK= XXX.XXX.XXX.XXX
    BROADCAST= XXX.XXX.XXX.XXX

  7. We must now add a default gateway. Typically, this should be the address of your router. To do this, simply add a new line at the bottom of the file, as shown next, and customize the value as required:
    GATEWAY=XXX.XXX.XXX.XXX

  8. When ready, save and close the file before repeating this step for any remaining Ethernet devices that you want to make static. When doing this, remember to assign a different IP address to each device.

  9. When finished, save and close this file before restarting your network service:
    systemctl restart network

How it works…

In this process, you have seen the process associated with changing the state of your server’s IP address from a dynamic value obtained from an external DHCP provider to that of a static value assigned by you. This IP address will now form a unique network location from which you will be able to deliver a whole host of services and applications. It is a permanent modification, and yes, you could say that the process itself was relatively straightforward.

So, what have we learned from this experience?

Having started the process by identifying your network interface name of choice and creating a backup of the original Ethernet configuration files, we then opened the configuration file located at /etc/sysconfig/network-scripts/ifcfg-XXX (with XXX being the name of your interface, for example, enp0s3). As being static no longer requires the services of the network manager, we disabled NM_CONTROLLED by setting the value to no. Next, as we are in the process of moving to a static IP address, BOOTPROTO has been set to none, as we are no longer using DHCP. To complete our configuration changes, we then moved on to add our specific network values and set the IP address, the netmask, broadcast, and the default gateway address.

In order to assist the creation of a static IP address, the default gateway is a very important setting in as much as it allows the server to contact the wider world through a router.

When finished, we were asked to save and close the file before repeating this step for any remaining Ethernet devices. Having done this, we were then asked to restart the network service in order to complete this process and to enable our changes to take immediate effect.

 

Securing Apache in CentOS

Even though the Apache HTTP server is one of the most mature and safe server applications included in CentOS 7, there is always room for improvement and a large number of options and techniques are available to harden your web server’s security even more. While we cannot show the user every single security feature as it is outside of the scope this book, in this process, we will try to teach what is considered to be good practice when it comes to securing your Apache web server for a production system.

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 Apache is installed and currently running, and that your server supports one or more domains or subdomains.

The Process

Most of the security options and techniques have to be set up in the main Apache configuration file, so we will begin this process by opening it in our favorite text editor.

Configuring httpd.conf to provide better security

  1. To begin, log in as root and open the main Apache config file:
    vi /etc/httpd/conf/httpd.conf
  2. Now go to your main document root. To do so, search the directive called:
  3. Within the beginning and closing tags find the line Options Indexes FollowSymLinks, then disable (comment out) this line by putting a # in front of it, so it reads:
    # Options Indexes FollowSymLinks
  4. Now scroll down to the end of the configuration file and insert the following line one line before the line # Supplemental configuration. We do not want our server to leak any detailed information through the header, so we type:
    ServerTokens Prod
  5. Afterwards, reload the Apache configuration to apply your changes:
    apachectl configtest && systemctl reload httpd

Removing unneeded httpd modules

Even the most stable, mature, and well-tested programs can include bugs and cause vulnerabilities, as the latest news about the Heartbleed bug in OpenSSL or Shellshock in Bash have shown, and the Apache web server is no exception. Therefore, it is often beneficial to remove all unneeded software to limit the functionality, and thus the likelihood of security problems in your system. For the Apache web server, we can remove all unneeded modules to increase security (this can also increase performance and memory consumption). Let’s start this process by reviewing all the currently installed Apache modules.

  1. To show all currently installed and loaded Apache modules, type as user root:
    httpd -M
  2. All the modules outputted by the preceding command are loaded into the Apache web server by special configuration files in the /etc/httpd/conf.modules.d folder where they are grouped together by their primary target into the following files:
    00-base.conf, 00-dav.conf, 00-lua.conf, 00-mpm.conf, 00-proxy.conf, 00ssl.conf, 00-systemd.conf, 01-cgi.conf, 10-php.conf
  3. So instead of going through all the modules individually, this file structure in the conf.modules.d folder can make our life much easier because we can disable/enable whole groups of modules. For example, if you know that you will not need any Apache DAV modules because you will not provide any WebDAV server, you can disable all DAV-related modules by renaming the extension of the 00-dav.conf configuration file since only files with the ending .conf are read and loaded automatically by Apache. In order to do so, type:
    mv /etc/httpd/conf.modules.d/00-dav.conf /etc/httpd/conf.modules.d/00dav.conf.BAK
  4. Afterwards, reload the Apache configuration to apply your changes to the modules directory:
    apachectl configtest && systemctl reload httpd
  5. If you need more fine-grained control, you can also enable/disable single modules in all the configuration files in this directory as well. For example, open 00-base.conf in your favorite text editor and disable a single line by adding a # to the beginning of the line of choice you want to disable. For example:
    # LoadModule userdir_module modules/mod_userdir.so
  6. If you decide to use some disabled modules files later, just rename the .BAK file to the original file name or remove the # in a specific module config file before reloading httpd once again.

Protecting your Apache files

Another really simple way to increase the security of your Apache web server is to protect your server-side scripts and configurations. In our scenario, we have one user (root) who alone is responsible and maintains the complete Apache web server, websites (for example, uploading new HTML pages to the server), server-side scripts, and configurations. Therefore, we will give him/her full file permissions (read/write/execute). The apache user still needs proper read and execute permissions to serve and access all Apache related files, thus minimizing the risk that your Apache web server is exposing some potential security risks to other system users or can get compromised through HTTP hacks. Do this in two steps:

  1. First we will change or reset the ownership of the complete Apache configuration directory and the standard web root directory to owner root and group apache:
    chown -R root:apache /var/www/html /etc/httpd/conf*
  2. Afterwards, we will change the file permissions so no one other than our dedicated apache user (and also root) can read those files:
    chmod 750 -R /var/www/html /etc/httpd/conf*

How Does It Work?

We began this process by opening the main Apache configuration file httpd.conf to change settings for our main Apache root web content directory /var/www/html. Here we disabled the complete Options directive which included the Indexes as well as the FollowSymLinks parameter. As we have learned, if you request a directory instead of a file from the Apache server, index.html or the index.htm file within this directory will be sent automatically. Now the Indexes option configures the Apache web server in such a way that if no such file can be found in the requested directory, Apache will auto-generate a listing of the directory’s content, as if you had typed ls (for list directory) in that directory on the command line, and show it to the user as a HTML page. We don’t want this feature in general because it can expose secret or private data to unauthorized users and a lot of system administrators will tell you that indexing is considered to be a security threat in general. The FollowSymLinks directive should also not be used in production systems because if you make a mistake with it, it can easily expose parts of the file system, such as the complete root directory. Finally, we add another measurement to increase the server’s base security and this is done by disabling the server version banner information. When the Apache web server generates either a web page or an error page, valuable information, for example the Apache server version and the activated modules, is sent automatically to the browser and a possible attacker can gain valuable information about your system. We stopped this from happening by simply setting ServerTokens to Prod. Afterwards, we showed you how to disable Apache modules to reduce the general risk of bugs and exploitations of your system. Finally, we showed how to adjust your Apache file permissions which can also be a good general protection.

There are lots of other things to consider when it comes to hardening your Apache web server but most of these techniques, such as Limiting HTTP request methods, TraceEnable, setting cookies with HttpOnly and secure flags, disabling the HTTP 1.0 protocol or SSL v2, or modifying the HTTP header with useful security-related HTTP or custom headers such as X-XSS-Protection, are much more advanced concepts and can restrict a general purpose Apache web server too much.

 

Building a secondary (slave) DNS server on CentOS

To guarantee high-availability in your network, it can be useful to operate more than one DNS server in your environment to catch up with any server failures. This is particularly true if you run a public DNS server where continuous access to the service is crucial and where it is not uncommon to have five and more DNS servers at once. Since configuring and managing multiple DNS servers can be time-consuming, the BIND DNS server uses the feature of transferring zone files between the nodes so that every DNS server has the same domain resolving and configuration information. In order to do this, we need to define one primary and one or more secondary or slave DNS servers. Then we only have to adjust our zone file once on the primary server which will transfer the current version to all our secondary servers, keeping everything consistent and up-to-date. For a client, it will then make no difference which DNS server they are connecting to.

To Start With: What Do You Need?

To complete this process, you will require at least two CentOS 7 servers in the same network which can see and ping each other. An Internet connection will be required to download and install the BIND server software on all the computers we want to include in our DNS server farm. In this example, we have two servers, 192.168.1.7 which is already installed and configured as a BIND server, and 192.168.1.15 which will be our second BIND server within the subnet 192.168.1.0/24. You should also have read and applied the zone file process from this chapter division and create a forward and reverse zone file because this is what we want to transfer between DNS servers.

The Process

We begin this process by installing BIND on every CentOS 7 computer we want to include in our BIND DNS server cluster. To do this, follow the process, Setting up an authoritative-only DNS server for all the remaining systems. Before we can start, we need to define which server will be our primary DNS server. For simplicity in our example, we will choose the server with the IP address 192.168.1.7. Now let’s make all our DNS server nodes aware of their role.

Changes to the primary DNS server

  1. Let’s log in as root on the primary server and open its main configuration:
    vi /etc/named.conf
  2. Now we define which secondary DNS server(s) will be allowed to receive the zone files at all, write the following command somewhere between the options curly brackets in a new line (we only have one secondary DNS server with the IP address 192.168.1.15, change accordingly):
    allow-transfer { 192.168.1.15; };
    notify yes;
  3. Also, we must allow the other nameservers to connect to our primary nameserver. In order to do this, you need to change your listen-on directive to include the DNS server’s primary network interface (in our example 192.168.1.7 , so change appropriately):
    listen-on port 8053 { 127.0.0.1;192.168.1.7; };
  4. Save and close the file. Now open the new port 8053 in your server’s firewall (or you can create a firewalld service for it )
    firewall-cmd --permanent --zone=public --add-port=8053/tcp --addport=8053/udp;firewall-cmd --reload
  5. Save and close the file. Next, update the zone files we created earlier to include the IP addresses of all the new nameservers we have available in the system. Change both the forward and reverse zone files, /var/named/centos7.home.db and /var/named/db.1.168.192, to include our new secondary DNS server. In the forward zone file, add the following lines (you can also use the nsupdate program to do this) into the appropriate sections:
    NS ns2.centos7.home.
    ns2 A 192.168.1.15
  6. In the reverse zone file, add instead into the appropriate sections:
    NS ns2.centos7.home. 15 PTR ns2.centos7.home.
  7. Finally, restart BIND and recheck the configuration file:
    named-checkconf && systemctl restart named

Changes to the secondary DNS server(s)

For simplicity and to demonstrate, just install named on any server you want to use as a BIND slave (we only show the important configuration here):

  1. Log in to the new server as root, install BIND, and open its main configuration:
    yum install bind; vi /etc/named.conf
  2. Now locate the line include /etc/named.rfc1912.zones;. Immediately following this line, create a space for your work and add the following zones (replace the zone and file names appropriately):
    zone "centos7.home" IN {
        type slave;
        masters port 8053 { 192.168.1.7; };
        file "/var/named/centos7.home.db";
    };
    zone "1.168.192.in-addr.arpa" IN {
         type slave;
         masters port 8053{ 192.168.1.7; };
         file "/var/named/db.1.168.192.db";
    };
  3. Save and close the file. Then fix some incorrect BIND folder permissions and enable named to write into its zone file directory before restarting BIND:
    chown :named /var/named -R; chmod 775 /var/named -R
    setsebool -P named_write_master_zones 1
    named-checkconf && systemctl restart named
  4. Now initiate a new zone transfer using:
    rndc refresh centos7.home.
  5. After waiting a while, to test if our secondary DNS server is working as expected, check if the master zone files have been transferred:
    ls /var/named/*.db
  6. Finally, we can now test if we can query our local domain on the secondary DNS server too:
    dig @127.0.0.1 client2.centos7.home.

How Does It Work?

In this process, we showed you how to set up secondary BIND servers in your network which can help in increasing the stability and availability of your DNS server system.

So what did we learn from this experience?

We started our journey by deciding which of our servers should be the primary and which should be the slave DNS servers. Then we opened the BIND main configuration file on the primary server and introduced two lines of code to configure our server to be the head of our DNS cluster. The allow-transfer directive defines to which clients we want to transfer our updated zone files while the notify yes directive enables automatic transfer when any changes to the zone files happen. If you have got several secondary BIND DNS servers, you can add more than one IP address into the allow-transfer directive, separated by semicolons. Then we opened our zone files we created in a former process and introduced a new line IN NS which defines the IP address of our secondary DNS servers we need to be aware on every DNS node in our system. If we have got multiple servers, then we introduce multiple IN NS lines. Finally, we introduced a small comment to easily check the successful zone file transfer on our secondary servers.

Afterwards, we configured our slave DNS server(s). Here we introduced the same zone file definitions as on the primary server’s BIND configuration, with the exceptions that we used type slave instead of master to denote we are a secondary DNS server and will get a copy of the zone files from the master node by defining the primary DNS server’s IP address using the masters directive (please do not forget that our master BIND is listening on the non-default port 8053 in our example).

Since we had not created or copied the zone files ourselves on the slave DNS server, it was then easy to check if the zone file transfer had been successful after restarting the BIND service using the ls command. Finally, we verified the transferred zone file content by running test queries using dig or nslookup to see if we could resolve the same local hostnames on our secondary DNS server. Remember if you later make changes to your master’s zone files you have to increase their serial number in order that those changes get transferred to all your slaves.