CentOS Linux
CentOS
The Community ENTerprise Operating System, or CentOS, is a popular Linux environment. It's derived from and is fully compatible with Red Hat Enterprise Linux. And while Red Hat is only available through a subscription service, CentOS is available freely. CentOS is community supported. Which means that instead of requiring professional service contracts to get help and support. Community members ranging from professional software engineers who work for Red Hat, to system administrators in the industry, to Linux enthusiasts around the world, provide support to CentOS users through a variety of means, including chatrooms and web forums.
CentOS used to be an independent project, but in 2014, the project joined up with Red Hat officially. CentOS version numbers, mirror those of Red Hat Enterprise Linux. But releases tend to lag behind a few weeks to a few months. The CentOS team needs this time to remove Red Hat branding, and rebuild everything from Red Hat's source code. Being an enterprise class operating system, CentOS 7 will enjoy updates for five years.
Filesystem Hierarchy Standard (FHS)
CentOS, along with many UNIX-like systems, follow a standard called the Filesystem Hierarchy Standard, or FHS. It defines locations, permissions, and file names, for system and other files. This standard makes it possible for users and programs to find what they're looking for in consistent places. More information about the standard is available at pathname.com/fhs.
root directory (/)
The most important directory, and the one on which everything else is based, is the root directory, represented with a slash. It's the highest level on the hierarchy, meaning that everything else is contained within it, or is under it. You've probably seen the slash representing root in absolute file paths. Under the root directory, there are a number of other directories with special purposes for the system.
bin directory (/bin)
The bin
directory which contains the command binaries, or compiled programs that make the command line environment usable. These include change directory, copy, the bash shell itself, grep, awk and a lot more. bin
is actually a symbolic link, or sym link, to the usr/bin
directory. A symbolic link is a pointer to somewhere else in the file system. The files we'd expect to find in bin
are really in usr/bin
. In this case, to maintain compliance with the Filesystem Hierarchy Standard, the file system will behave as though bin
is a real directory.
boot directory (/boot)
Next, there's boot
, which is where the software that allows the system to start up lives. Among other things, it contains the boot loader, called grub, and the Linux kernel itself. Unless you're doing some pretty specific and advanced things, you won't spend any time in here.
dev directory (/dev)
/dev
is where the system devices are. It contains references to hardware and software resources on the system. And you won't spend much time in here either, but you'll see /dev
as part of paths that you'll use for various tasks. For example, you might see scripts that send output to dev null which is a software device that sends data nowhere. Data written here isn't saved and it just goes away. Dev random and dev u random are random number generators that can be used for various purposes. If you're working with disks, you'll see things like dev sda and dev sda1. This represents serial disk A, the first hard drive, and serial disk A slice 1, the first slice or partition of serial disk A.
etc directory (/etc)
This is the nerve center of your system. the /etc
directory
holds system configuration files, and if you make changes to the system,
you'll probably do so in here. On CentOS, a lot of the configuration files
that you'll work with are inside /etc/sysconfig
. A
"configuration file" is defined as a local file used to control the operation
of a program; it must be static and cannot be an executable binary.
home directory (/home)
The /home
directory is where user home directories live. Home
folders keep each user's personal files separate from each other. And this
folder acts as the default landing spot, or working directory, when a
non-root user, connects via ssh, or ftp.
lib directory (/lib)
/lib
media directory (/media)
The /media
directory serves as a mount point for removable
media.
mnt directory (/mnt)
The /mnt
directory is where the system mounts temporary file
systems.
opt directory (/opt)
/opt
provides a space for software packages to set up their
own folder structure. If you work with third party packages and tools,
you might find yourself working in here.
proc directory (/proc)
The /proc
directory contain some system and process information.
root directory (/root)
/root
is the home folder for the root user.
run directory (/run)
The /run
directory contain some system and process information.
/run
also contains information about running processes on the
system.
sbin directory (/sbin)
/sbin
is where system binaries live.
srv directory (/srv)
/srv
holds information about files for various services.
sys directory (/sys)
And /sys
shows information from the proc
directory
in a different format.
tmp directory (/tmp)
The /tmp
directory contains temporary files, and can be cleaned
out when the system restarts.
usr directory (/usr)
The /usr
directory provides another place for applications to
live.
The /usr/
directory is for files that can be shared across
multiple machines. The /usr/
directory is often on its own
partition and is mounted read-only. At a minimum, the following directories
should be subdirectories of /usr/
:
- bin/
- etc/
- games/
- include/
- kerberos/
- lib/
- libexec/
- local/
- sbin/
- share/
- src/
- tmp -> ../var/tmp/
/usr/
directory, the bin/
subdirectory
contains executables, etc/
contains system-wide configuration
files, games/
is for games, include/
contains C
header files, kerberos/
contains binaries and other
Kerberos-related files, and lib/
contains object files and
libraries that are not designed to be directly utilized by users or shell
scripts. The libexec/
directory contains small helper programs
called by other programs, sbin/
is for system administration
binaries (those that do not belong in the /sbin/
directory),
share/
contains files that are not architecture-specific,
src/
is for source code.
var directory (/var)
The /var
directory is a standard subdirectory of the root
directory that contains variable files to which the system writes data
during the course of its operation.
/var
is specific for each computer; that is, it is not shared
over a network with other computers, in contrast to many other high-level
directories. Its contents are not included in /usr
because
situations can occur in which it is desired to mount /usr
as
read-only, such as when it is on a CDROM or on another computer.
/usr
, which is generally the largest directory (at least on a
newly installed system) and is used to store application programs, should
only contain static data.
- cache/ - contains cached data from application programs
- games/ - contains variable data relating to games in /usr
- lib/ - contains dynamic data libraries and files
- lock/ - contains lock files created by programs to indicate that they are using a particular file or device
- log/ - contains log files
- run/ - contains PIDs and other system information that is valid until the system is booted again. Most likely, this is symbolically linked to /run. The /run idea is a relatively new idea/standard.
- spool/ - contains mail, news and printer queues
Configuring Networking using DHCP
You can do a quick check to see if you have Internet connectivity by pinging a commonly available Internet resource, such as one of Google's public DNS servers. Of course, that's not foolproof, depending on your network policies, but it works for most people.
The network configurations are stored in the
/etc/sysconfig/network-scripts
folder. There is a file for each
interface. Let's work with the first Ethernet interface on the system. In
the example, it is ifcfg-en01
. If you are using a virtual
machine, it might be different. To edit the file, enter
vi ifcfg-en01
.
Restart the network interface with:
service network restart
And that'll bring up the Ethernet interface, with a new configuration. I can type:
ip a ip address
and I can see that now I have an IP address on this network. 192.168.1.3. I can type:
ping 8.8.8.8
This will ping Google's DNS server again. And now I have network connectivity and I can also route to the Internet.
Now, since we're configuring a server and we don't usually want servers floating all over the network, you might be wondering how to set up a static IP address, instead of a dynamic one, that could change across reboots. There's two ways to go about this. The first is to reserve a particular IP for this system on the network's DHCP server. That's usually done using the hardware ID, or a MAC address of the system's ethernet adapter. That makes your network's reservations manageable from a central location, and helps to avoid address conflicts. It can make large rollouts easier too, since the reservations can be set up ahead of time.
The other way, is to set it up manually in the network configuration script. Let's take a look at that. I'll open up the network configuration file again, with viifcfg-en01, and I'll make a few changes to it. I'll go into insert mode by pressing i, and I'll change a BOOTPROTO from DHCP to static. I'll make sure that ONBOOT is set to yes. Then I'll add a few lines. First, I'll add IPADDR, for IP address, equals 192.168.1.201. I know that on my network, the DHCP range is from .2 to .200. So, this .201 address is outside that scope and it won't conflict with DHCP at all. Then I'll add a netmask, and in my case, it's 255.255.255.0. I'll also add a gateway, and that'll be the IP address of my router 192.168.1.1.
So, this is all we need to specify a static IP address. But, since we are not participating in DHCP, we're not going to be handed a DNS server for name resolution. So, I need to explicitly set what that server is going to be. So, I'll write DNS1 equals 8.8.8.8. That's Google's public DNS server, and that's going to be the first one that I use. If I had others, I can type DNS2 equals 8.8.4.4 for example, and just continue with the numbering scheme.
I'll press Escape+colon+WQ, to write the file to disk, and then, I'll restart the network service to bring up the ethernet interface with the new settings. Of course, this shouldn't be a problem since I'm connected locally, but if you're connected remotely, keep in mind this might disconnect you. So, if there's a problem with your network configuration, like if you chose an IP that's already in use, you'll need to go log into your box locally to fix it. I'll type service network restart. And they'll check out my IP address info, with IP, space a.
Here, I can see that I have 192.168.1.201. And let's see if it works. I'll ping a DNS server. That seems to work. And I'll ping something that needs name resolution. And that seems to work as well.
Setting the Host Name
During the installation process, I didn't change the system's host name, or the name that this computer has internally. Out of the box, the system is called localhost, which isn't terribly useful when you have more than one system that you're connecting to. If you have three terminal windows up and they all say localhost, how do you know at a glance which system you're using? If you set up a service like Mail that uses the host name, how easily do you tell where a message came from? A host name should be useful and memorable. It needs to be 64 characters or less, and can only contain alphanumeric characters and dashes.
To see your current host name, use:
hostname localhost.localdomain
There's a wide range of opinions out there on what constitutes a good name.
Some people like to name systems after famous scientists, chemical
elements, or Lord of the Rings references. Some use some kind of
notation that describes information about the server encoded in a way that
makes sense to somebody. I like to use mythological characters. So, I'll
call this server Apollo. To set the host name, I'll edit the file
/etc/hostname
. And change localhost.localdomain
to Apollo
.
vi /etc/hostname
I'll save and exit, and then I'll open up the hosts file.
vi /etc/hosts
I need to add an entry here too, to map the new host name to the loopback address.
127.0.0.1 Apollo
I'll save and quit. And then I'll need to restart the system.
shutdown -r now
Now here at the login screen, I can see that it says Apollo login, instead of local host login.
Connecting Remotely with SSH
Let's switch over to connecting to the server remotely, using Secure SHell, or SSH. SSH sets up an encrypted secure terminal or command line session between your computer and a remote computer that's set up as an SSH server. SSH can use either a username and password, or a cryptographic key as a login, to authenticate you and allow you access to the system. The first time you connect to an SSH server, your system will ask you if you trust the fingerprint of the remote server. The fingerprint is a cryptographic signature, generated by the SSH server, to confirm that it's the same machine time and again.
If you just set up a new server, your system won't know about it. So you can say 'yes'. When you accept the signature, it'll be stored on your computer, and checked each time you connect to the server in the future. If you've been connecting to a server with SSH for a while, and the signature suddenly changes, you'll want to investigate a little bit more. It's usually the sign of a change in the remote system, either malicious or harmless. But that's a topic for a whole other course.
Mac
Connecting to an SSH server is pretty easy if you have the software for it. On Mac OS X and Linux that software comes in the form of the SSH program that's already part of the operating system. You get to it by opening up a terminal window.
Here on my Mac, I'll type ssh root@ the IP address of my server which is 192.168.1.201. Here it's asking me to accept the fingerprint. I'll type 'yes' to accept it. And I've added this system to my list of known hosts. I'll type my password, and I'm connected to my server.
If you're using a cloud hosted solution, or another configuration that you use key access for. You'll need to follow the process for your environment to get connected. I can type exit to disconnect, and I'm back into command line on my Mac. When I accepted that fingerprint, my system wrote a line into the file known host, which is in my home folder. In a folder called .ssh. If at some point in the future, I replace my CentOS server with a different machine with the same IP address, I won't be able to connect via SSH until I delete this line and this signature from my known host file.
Virtual Machine
One quick note for those of you working in a virtual machine. In order to be able to connect via SSH, you might need to forward a port from your virtual machine to your actual machine. The method for doing this varies based on the software you're using. But here in VirtualBox, all I need to do is get the IP address. Which for my virtual machine is 10.0.2.15. Then go into the settings, and change the network settings, to add a port forwarding rule. The host IP will be 127.0.0.1, which is the local host address for my Mac. And I'll use the port 2222. The guest IP will be 10.0.2.15, port 22, which is where SSH runs. I'll close out of there and switch over to my terminal. To connect to my virtual machine, I'll type ssh, and the user name root@localhost instead of the IP address of my virtual machine because I mapped that port over to my local host. And then -oPort=2222. I'll enter root's password. And I'm connected.
Windows
On Windows it's a little more complicated, since SSH doesn't come pre-installed. You can download a program called PuTTY.
Over here on my PC, I have browsed to putty.org. The first link here takes me to the PuTTY Download Page. And I'll click on putty.exe to download it. I'll choose Save. And then I'll open up my Downloads folder. Instead of being a zip file or something like that, this is the PuTTY executable. So I can move it to my desktop if I want to keep it there, if I need to use it frequently. I'll open it up, and here in the Host Name box, I'll type the IP address of my server. That's 192.168.1.201.
SSH operates on port 22 so I'll leave that alone, and I'll hit Open. I'm being prompted to accept the host key. So I'll hit Yes. And I'll log in as root. Then I'll type my password. And I'm connected.
Connected
I'm connected now but again I'm using the root user, and that's not something I want to do all the time. root has unquestioned access to the system. Not only do I not want to accidentally do something without being prompted about it, I don't anyone from the outside to be able to have this level of access to my computer. To increase security we'll set up a less privileged account and disable remote access by the root user. If we do need to use root's power we'll connect with that unprivileged user and escalate our privileges only when needed.
Create a User
First I'll create a user. I'll go over this process in a little bit more depth later on when I talk about users and groups, but for now I'll type:
useradd scott
Next, I'll create a home folder and a hidden folder that SSH expects within
that home folder. Normally, this is two commands but I can use the
-p
flag with the mkdir
command to tell the system
to create folders as necessary. I'll type:
mkdir -p /home/scott/.ssh
Then I'll take a look at what it did. I'll type:
ls -lah /home/scott
I see that not only was my home folder created, but also that
.ssh
folder was created. Among other things, setting up this
home folder will guarantee that I have a place to land when I log in, and
I'll have a space to store any user-specific data that I might have. I have
both a home folder and a .ssh
folder, along with some things
that the system makes for me including my bash profile. Now I'll set up a
password for myself. I'll type:
passwd scott
I'll enter a strong password and confirm it. Now I have a user that I can
log into this box with but right now it won't be able to use the
sudo
command to borrow root's privileges. Not everyone gets to
use the sudo
command. Those who do are listed in the file
/etc/sudoers
. This is a text file but it's very important that
it not contain any errors. To ensure that there are no errors, it's
recommended that you never edit this sudoers
file directly.
I'll clear
the screen.
There's a special program to edit this file which validates the file before it saves it. To get there I'll type the following:
visudo
I need to add a line a little ways down the file. If you're not familiar
with the VI environment, don't worry, this won't hurt much. I can use the
arrow keys to go down a bit or I can search here in VI by typing
/(ALL)
because I know that appears on the line I need to edit.
Hit Enter and here it is.
I need to add a line under it, and I'll press i
to go into the Insertion mode. I'll type the following:
[username] [tab] ALL=(ALL) [tab] ALL
To exit from Insertion mode, save the file and quit the editor, type:
[Esc] :wq
VI or VIM is a very popular text editor, and if you're doing system administration tasks it's very important to know how to use it. Okay, I've created a user, given it a home folder and a .ssh folder, set a password, and edited myself to the list of users that can use the sudo command to act as root.
Now I log out of the root SSH connection. Now I'll log back in with my new user. I'll type "ssh" and my username with the IP address of my server. And I'll type in my password. Now I can see I'm connected as that user instead of root. Let's test out my sudo powers. I'll type "su" which is the command to switch user. If I don't specify a user after the command this system assumes I mean root. If I specify a user like "su scott" it'll ask to authenticate to that user.
And then I switch to being that user. But for now let's switch to root. I'll type "su" and then I'll type root's password. Great! It looks like my sudo privileges work. I'll type exit to go back to my user. Now I can connect to my Santos machine with a non-root user and user root's privileges when I need to. As a final step I'll disable the ability of the root user to log in via SSH. I'll edit the SSH configuration file with "sudo vi /etc/ssh/sshd_config".
The first time I use sudo I get a little bit of a warning from the system. I'll type my password and here I am in the SSH configuration file. I look for a value called "permit root login". I go into Insert mode, I'll uncomment it, and I'll change the value from "yes" to "no". I'll hit Escape, save the file, and quit. Now I'll restart the SSH service with "service sshd restart".
Yep, looks like I forgot to use sudo. I'll type "sudo !!" which is a bash shortcut for the last command. Effectively this says "sudo service sshd restart". I'll disconnect my SSH session with Exit. Now I'll try to connect as root. I'll type in my password. And I have permission denied.
Installing and Updating Software
Chances are, if you're setting up a CentOS server, you'll want to install some software. CentOS uses the yum package manager, which stands for Yellowdog Updater, Modified, to install and manage software. Under the hood, yum uses RPM packages, which are named for RedHat Package Manager. Because CentOS is based on RedHat, it inherits RedHat's package management scheme. In this movie, I'll go over some of the options available to you using yum. First, let's install some software. The minimal CentOS install doesn't come with a package that I think is really useful, called wget. wget makes it easy to download files like installation packages from the web. If I type wget at the command line, I can see it's not installed. So, to install it on my system, I'll type:
sudo yum install wget
When I do, yum goes and checks for the fastest repository, sets up the install, and resolves dependencies, meaning it checks to see if what I'm asking to install needs any additional software to work. After it's ready to go, I get a summary of what will be installed and from where.
I see that yum will be installing one package, how much will be downloaded, and how much disk space will be taken up when it's done. Next, I have to type y to continue. If I just hit Enter, the updater exits. Then yum downloads, checks, and installs the software I asked for. Yum asks if I trust the official signing key from CentOS, which I do, so I'll press Y. Now when I type wget, I can see that it's installed. I can search the repository to see if something matches using yum search. I'll clear the screen, and then I'll type:
yum search zip
I know that I want to be able to use zip archives later in the course, so I'll need a program that can handle them. And, sure enough, there's a few here that look promising. I'll install zip and unzip. I'll type sudo yum install zip unzip. I can list as many packages at the command line as I want. yum's asking if this is okay. I'll hit y. And I've installed two different packages. There's a couple more commonly used commands for yum. Let's take a look at updating software. yum check-update, shows me what's updated, compared to what's installed on my system.
To update the openssl package, I can type sudo yum update openssl. Or, I can install all of the suggested updates, by just using the update command by itself. With sudo yum update. Updating is one of those processes that can take a while. So we'll fast forward a little bit. The info command lets me find out a little bit more about a package. I'll type, yum info nano. And I can see a little bit of information about the nano package, which is a text editor. list searches the repository for any package matching a term. I'll type, yum list python.
Here I have one result, and it shows that it's installed. If I type:
yum list gcc
I can see that the gcc package is available but not installed. I can use the search command to look for a term in descriptions of packages. I'll type, yum search python. And here's a lot more results then before. I can see scipy, a set of Python libraries. Python only appears in the description, not the name. This is a great way to explore packages and see what's out there. And if you install something you don't want, you can remove it with yum remove, followed by the package name. I'll type:
sudo yum remove zip
But I want that one back.
sudo yum install zip
Next, let's take a look at installing larger groups of packages to more easily change the system's role.
Yum allows you to install packages by group, as well as individually, you can explore what groups are available with:
yum grouplist
You can either install the base environments that were available during the setup process, or add some other groups such as Development Tools and Security Tools. To find out more about a group you can use the group info command. I'll type yum group info and then Basic Web Server which appears in the available environment groups, I'll make sure to put quotes around that.
I can see that there are some optional groups too, again these are what are available in the installation environment. I can just tack them on to the end of my command to install them. I'll type sudo yum group install and group name and some of the optional packages too, php and load-balancer. And if I decide I don't want this package installed anymore, I can remove it with the group remove command, I'll write yum groupremove Basic Web Server php load-balancer.
There's a group update command available as well if you need to update just the packages installed as part of a group.
Packages from other sources
While the CentOS repositories have a lot of software available, you may want to install something that's not included in them. There's a number of third party repositories out there that you can add to your system. I want to install a package called seeker, which provides some benchmark information about hard disks and I know it's available from a popular third-party repository called RepoForge, also known as RPMForge. Luckily, RPMForge is a website, provides instructions for adding that repository to my system. First, I'll download the RPM package for my architecture, x86, using wget, I'll copy the link using my browser, switch over to the terminal and download the file.
Then I'll import the public key for this repository so yum can verify the software that it installs. I can use this key to verify the RPM I just downloaded. I'll write sudo, and paste the command and it looks like the signature is okay. And now, I can use the command with a dash i-flag, to install the RPM I downloaded. I'll type sudo then paste rpm -i and the name of the rpm file. I'll clear the screen and then I can type yum list seeker, the package that I want to install that I know is not available in the base repository and there it is.
http://wiki.centos.org/AdditionalResources/Repositories/RPMForge
I can see that it's available from the RPMForge repository. Just like packages from the base repository, I can type:
yum info [package name]
This will display some more information, now I'll go ahead and install it. I'll type the following:
sudo yum install seekerOkay. I'll clear the screen again and then I'll run seeker. This will run a quick benchmark on my internal disk. I got about fourteen thousand seeks per second, that's not too bad for my little SSD.
Transferring Files with SFTP
We've used wget to download a file from the web to the server, wget is perfect for this kind of thing and for
our purposes here there's not much more to talk about for it but if you type
man wget
you can check out all of the options. However,
wget
is less useful for sending files from a local computer to
the server. Luckily, by virtue of having SSH set up on the server, we can
use SFTP, or SSH File Transfer Protocol, to transfer files back and forth
without any additional set up.
While you can use SFTP at the command line, many people choose to use graphical clients for file transfer. I've downloaded and installed Cyberduck free client from cyberduck.io, there's an installer for Mac and for Windows. I have Cyberduck here opened on my Mac, and also a finder window, opened to the website folder of the exercises files. These are some files for a website that we'll use later on in the course but I need to get them from my computer to my server. What I'll do here in my SFTP client, is go to the quick connect bar and type in sftp:// to tell the system that we're using the SFTP protocol, and then my username at then IP address of my server, 192.168.1.201.
I'll press enter and tell the system that I want to always accept the key and here I am in my home folder. You can see the RPMForge file that we downloaded just a minute ago and, I'll right click and create a new folder. I'll call this one website, I can open that up and see that it's empty. And switch back to Finder, select all of the files, and just drag them right into that folder. The program gives me a transfer window to show me the progress and, this is already completed. It was only 4.2 megabites worth of files.
So if I switch over to my Terminal window and see that I'm here in my own folder. If I type ls to list the files in the folder, I can see I have the folder website. I can navigate into that with cd. I'll type cd website and I can type ls dash l to see the files in this folder in a list format and that's it. If I need to transfer files to the server, I have an easy way of doing it and I can use that same method to copy files from the server to my local computer.
Introducing SELinux
A whole lot of people's first interaction with SELinux, starts out with head scratching and frustration, and ends with shutting it off completely. But SELinux is an important part of the security of your server, and it's worth taking a little time to understand. SELinux, or Security Enhanced Linux, was originally developed by the National Security Agency to provide access control security policies for Linux installations. Unlike the standard security scheme of users, groups, and permissions, SELinux tags every file and resource on the system to add a more granular security system with lots of advantages.
This tagging is based on the idea that when a process in Linux runs, it inherits the rights and privileges of the user or process that started it up. For most things this makes a lot of sense. If I open a text editor, the text editor has access to the same files I have access to. It can write to my home folder and it can edit files that I've created. But this can get a little more tricky with system processes like a web server or a file server. Most of these file servers get started by the root user, or by the system acting as the root user. Because they need to access resources like network ports, system files or devices.
What happens in the case where someone uploads malicious software that hijacks these system processes? Or the programs themselves get replaced with maliciously crafted versions? You can envision a scenario where a malicious agent replaces the executable for the web server. Suddenly that compromised version of the web server could publish your whole user folder online. SELinux strives to prevent this using the granular tagging system I mentioned earlier. Setting what it calls security contexts on files and resources.
With SELinux, you can tag files as being within the context for the web server process. And regardless of the regular permissions of a file, if it's not tagged with a web service context, the web server can't access it. In this chapter I'll show you how SELinux works at a high level. And then in later movies, we'll see SELinux in action. And see how to correctly change the context of processes and files, so we can benefit from the protection that SELinux affords us. This type of security topic could be a whole course in itself.
So I won't go into a lot of depth here. And for most installations, you won't need to go into any kind of depth either. SELinux mostly stays out of the way. The only time you'll run up against it in the normal course of administering your server, is when there's a risk of security problems.
The standard Linux access control mechanism using Users, Groups and Permissions is a model that's called Discretionary Access Control or DAC. SELinux uses a security model called MAC or Mandatory Access Control which labels to objects on the file systems to provide more granular access control. It operates as a separate security layer from the DAC system, maintaining its own list of security permissions. As of version 2.6, this capability was built into the Linux kernel. SELinux has three operating states, or modes.
Enforcing, Permissive, and Disabled. Enforcing does exactly what it sounds like, it enforces the SELinux policies granting and preventing access to resources in accordance with its rules. Permissive still checks requests for resources but only logs exceptions, still allowing operations to continue. If a resource access request is in violation of the policy, a message is written to the audit log. When the SELinux state is set to disabled SELinux doesn't participate at all in system security.
The enforcing and permissive modes have two operating policies, strict and targeted. In strict mode all activity on the system is subject to the SELinux operating policy. In the targeted mode the policy is only enforced on specific known processes including HTTPD, named, ENTPD, S and MPD, and others. By and large, you won't be bothered by the targeted policies but if you are you may need to edit the policies to seek your requirements. Whiting custom policies is beyond the scope of this course, so we'll take a look at what's included out of the box.
You can see your systems current SELinux status by typing sestatus, mine is set to enabled using the targeted and enforcing policies. That's the default configuration for CentOS 7 and most Linux distributions. As I've mentioned before SELinux sets a label or security context on every file, process and resource on the system. You can see the security context of files with ls and -Z flag. What we're looking for here is this part. The security context is listed as a few values divided by colons.
The first field is the User Context, the next is the Role Context, the third is the Type Context and the last is the MLS or Multi Level Security Context. This example is from a user's home folder, by default things created in the user's home folder have a user home type context. They also have an unconfined user context. Unconfined means that it's out of the scope for SELinux's protection when you're using the targeted policy. If I take a look over at the var folder with ls -Z, I can see that the contents have a user context of system_u, and their type context varies.
SELinux uses type enforcement, role based access control and multi-level security to determine whether an action is permitted. Type enforcement is the most common method used to determine the result of a security policy. Role based access control and multi-level security aren't used in the targeted mode. Processes also have a context and we can discover what that context is, by using the capital Z flag with a ps command. All right, ps axZ. If a process type context doesn't match the type context of a file its trying to access and there are policies in place for the process and the policies are being enforced, then the process won't be allowed to access the file.
We'll see an example of that later in the movie about setting up a web server.
SELinux has many policies already configured for well-known processes. But sometimes, these need to allow a little bit of latitude or configuration. To enable this, SELinux has a set of options called booleans, which turn on or off specific aspects of enforcement. These operate within the larger scope of whether a process can access files. An example of this, which I'll show you later on in the movie about setting up a file share with SMB, determines whether SMB can share home folders or not.
That setting doesn't affect the bigger question of whether SMB can share files marked with the correct permissions and contexts. But since SELinux follows the principle of least privilege, if a file is otherwise able to be shared by SMB, and it's inside a user home folder, and the boolean for home folder sharing is turned off, then that file won't be able to be shared.
There's a few commands you'll use when working with SELinux. First there's set enforce. Set enforce sets whether the enforcing or permissive mode is active. As we saw before my system is set to enforcing with a command setenforce zero I can set it to permissive and I can set it back to enforcing with setenforce 1. This change only persists until the systems rebooted. So to make a permanent change you need to edit the etc sys config SELinux file.
Alright sudo vi etc/sysconfig/seLinux. This SELinux line here, is where you set the state permanently. It's best to leave the SELinux type down here, to target it. There's two commands I'll use later in the course to work with security context, chcon which changes the context of files and folders, and we'll see that in the web server movie, and setsebool, which I'll use in the samba movie to change the boolean value. If things aren't working the way you expect them to, it's a good idea to see if SELinux is involved.
You can switch a SELinux into permissive mode and check out the audit log with au report dash dash avc to see what's going on. If you see a lot of denied messages, that's your first clue as to where to look.
If you just want SELinux to go away and leave you alone you can do that in two ways. The first way is to turn off enforcement for the current session. This can be done by:
sudo setenforce zero
This will set SELinux into permissive mode until the system is restarted, to turn it off for good there's a bit more work involved. You need to edit the SELinux configuration file with:
sudo vi /etc/sysconfig/selinux
And set the SELinux line to either permissive or disabled, depending on your preferences, then don't reboot the system. When the system comes back up, the status of SELinux will be disabled, I'm going to turn mine back on though because SELinux is there for a reason, and it's better to configure it properly.
Firewall
CentOS 7 comes with firewall software called Firewalld. The purpose of Firewalld is to replace the need for iptables and improve the management of security by enabling configuration changes without stopping the current connections. Firewalld runs as a daemon that allows for rules to be added and changed instantly and it uses network zones to define a level of trust for any and all associated network connections. For the troubleshooter, this does provide a range of flexible options but, more importantly, it is necessary to understand that, while a connection can only be a part of a single zone, a zone can be used across many network connections.
To check to see if it is installed, use:
rpm -qa | grep firewalld
firewalld-0.3.9-14.el7.noarch
To look at the current configuration, use:
rpm -qc firewalld
/etc/dbus-1/system.d/FirewallD.conf /etc/firewalld/firewalld.conf /etc/firewalld/lockdown-whitelist.xml /etc/sysconfig/firewalld
The main, most important configuration file is the
/etc/firewalld/firewalld.conf
file.
To know whether firewalld is currently running, you can type:
firewall-cmd --state
running
You can also use the systemctl command to see if it is running:
systemctl status firewalld
* firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2016-07-26 18:46:29 PDT; 2h 4min ago Main PID: 963 (firewalld) CGroup: /system.slice/firewalld.service `-963 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid Jul 26 18:46:13 hdcentos systemd[1]: Starting firewalld - dynamic firewall daemon... Jul 26 18:46:29 hdcentos systemd[1]: Started firewalld - dynamic firewall daemon.
To list the predefined zones, you can use:
sudo firewall-cmd --get-zones
block dmz drop external home internal public trusted work
These zones can be defined as:
- block: In this zone, only network connections initiated within this system are possible as all incoming network connections are rejected with an
icmp-host-prohibited
message - dmz: This is the demilitarized zone
- drop: In this zone, incoming network packets are dropped (with no reply), and only outgoing network connections are possible
- external: This zone is used on external networks with masquerading enabled and only selected incoming connections are accepted
- public: This zone is used in areas where you do not trust the other computers; only selected incoming connections are accepted
- trusted: In this zone, all network connections are accepted
- work/home/internal: This zone is used in environments where you mostly trust the other computers on the network; again, only selected incoming connections are accepted
However, by extending this command, we can also discover what the default zone is by typing:
firewall-cmd --get-default-zone
public
The value of this can be updated with the following syntax:
firewall-cmd --set-default-zone=<new-zone-name>
Taking this one step further, we can extend this command to provide not only a list of zones, but also network interface information like this:
firewall-cmd --get-active-zones
public interfaces: eno16777736
Unless you have a very complicated network setup, you probably won't use most of these. Common zones to modify are drop, block and public.
I'll set up a few rules in the public zone to allow access to various services. To find out what the current zone is, I'll type:
sudo firewall-cmd --get-active-zone
You should see output similar to this:
public interfaces: eno16777736
The public zone is active on my system. To see what's currently running in that zone, use the following command:
sudo firewall-cmd --zone=public --list-all
You should see output similar to this:
public (default, active) interfaces: eno16777736 sources: services: dhcpv6-client samba ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules:
The output shows that IPV 6 DHCP client is running and SSH is running. That's how I have been able to connect via SSH so far. Any other service that is uses will be blocked.
There's two ways to add rules to the firewall, either explicitly or by service name. I need to allow access through port 80 for the web server I'll setup shortly. To do this explicitly, I'll type:
sudo firewall-cmd --zone=public --add-port=80/tcp
You should see output similar to this:
success
To make the rule permanent, use:
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
The permanent flag allows this rule to persist across reboots. Without it, the rule is active only until the system restarts. Since the permanent flag has been set, restart the firewall to make the change stick. Use the following command:
sudo service firewalld restart
You should see output similar to this:
Redirecting to /bin/systemctl restart firewalld.service
Now, I'll check out the rules, by typing:
sudo firewall-cmd --zone=public --list-all
You should see output similar to this:
public (default, active) interfaces: eno16777736 sources: services: dhcpv6-client samba ssh ports: 80/tcp masquerade: no forward-ports: icmp-blocks: rich rules:
Port 80/tcp is now open.
To remove that rule, use the following command:
sudo firewall-cmd --zone=public --remove-port=80/tcp
You should see output similar to this:
success
I need to add the --permanent
flag here, so it removes it from
the permanent settings. Since this is a change to the permanent settings,
restart the firewall daemon again.
sudo service firewalld restart
And I'll check to see that that port's closed. And sure enough, it is.
rules can be added by specifying a service. To see a list of services, use:
firewall-cmd --get-services
RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind rsyncd samba samba-client smtp ssh telnet tftp tftp-client transmission-client vdsm vnc-server wbem-https
Let's add the http service and make it permanent. Remember to restart the service.
sudo firewall-cmd --zone=public --add-service=http --permanent sudo service firewalld restart sudo firewall-cmd --zone=public --list-all
And now, instead of only port 80 on TCP being open, I see that I've added HTTP to the services that the firewall knows about. That will allow the access that the HTTP server needs to serve web pages. If I wanted to remove the service rule, I'd just use the remove service flag.
sudo firewall-cmd --zone=public --remove-service=http --permanent sudo service firewalld restart sudo firewall-cmd --zone=public --list-all
That's the basics of adding and removing individual ports and services using firewalld. There's a lot that can be done with the firewall. To see a list of all the firewalld options, use the command:
sudo firewall-cmd --help
You should see output similar to this:
Usage: firewall-cmd [OPTIONS...] General Options -h, --help Prints a short help text and exists -V, --version Print the version string of firewalld -q, --quiet Do not print status messages Status Options --state Return and print firewalld state --reload Reload firewall and keep state information --complete-reload Reload firewall and loose state information --runtime-to-permanent Create permanent from runtime configuration Permanent Options --permanent Set an option permanently Usable for options maked with [P] Zone Options --get-default-zone Print default zone for connections and interfaces --set-default-zone=<zone> Set default zone --get-active-zones Print currently active zones --get-zones Print predefined zones [P] --get-services Print predefined services [P] --get-icmptypes Print predefined icmptypes [P] --get-zone-of-interface=<interface> Print name of the zone the interface is bound to [P] --get-zone-of-source=<source>[/<mask>] Print name of the zone the source[/mask] is bound to [P] --list-all-zones List everything added for or enabled in all zones [P] --new-zone=<zone> Add a new zone [P only] --delete-zone=<zone> Delete an existing zone [P only] --zone=<zone> Use this zone to set or query options, else default zone Usable for options maked with [Z] --get-target Get the zone target [P] [Z] --set-target=<target> Set the zone target [P] [Z] IcmpType Options --new-icmptype=<icmptype> Add a new icmptype [P only] --delete-icmptype=<icmptype> Delete and existing icmptype [P only] Service Options --new-service=<service> Add a new service [P only] --delete-service=<service> Delete and existing service [P only] Options to Adapt and Query Zones --list-all List everything added for or enabled in a zone [P] [Z] --list-services List services added for a zone [P] [Z] --timeout=<timeval> Enable an option for timeval time, where timeval is a number followed by one of letters 's' or 'm' or 'h' Usable for options maked with [T] --add-service=<service> Add a service for a zone [P] [Z] [T] --remove-service=<service> Remove a service from a zone [P] [Z] --query-service=<service> Return whether service has been added for a zone [P] [Z] --list-ports List ports added for a zone [P] [Z] --add-port=<portid>[-<portid>]/<protocol> Add the port for a zone [P] [Z] [T] --remove-port=<portid>[-<portid>]/<protocol> Remove the port from a zone [P] [Z] --query-port=<portid>[-<portid>]/<protocol> Return whether the port has been added for zone [P] [Z] --list-icmp-blocks List Internet ICMP type blocks added for a zone [P] [Z] --add-icmp-block=<icmptype> Add an ICMP block for a zone [P] [Z] [T] --remove-icmp-block=<icmptype> Remove the ICMP block from a zone [P] [Z] --query-icmp-block=<icmptype> Return whether an ICMP block has been added for a zone [P] [Z] --list-forward-ports List IPv4 forward ports added for a zone [P] [Z] --add-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]] Add the IPv4 forward port for a zone [P] [Z] [T] --remove-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]] Remove the IPv4 forward port from a zone [P] [Z] --query-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]] Return whether the IPv4 forward port has been added for a zone [P] [Z] --add-masquerade Enable IPv4 masquerade for a zone [P] [Z] [T] --remove-masquerade Disable IPv4 masquerade for a zone [P] [Z] --query-masquerade Return whether IPv4 masquerading has been enabled for a zone [P] [Z] --list-rich-rules List rich language rules added for a zone [P] [Z] --add-rich-rule=<rule> Add rich language rule 'rule' for a zone [P] [Z] [T] --remove-rich-rule=<rule> Remove rich language rule 'rule' from a zone [P] [Z] --query-rich-rule=<rule> Return whether a rich language rule 'rule' has been added for a zone [P] [Z] Options to Handle Bindings of Interfaces --list-interfaces List interfaces that are bound to a zone [P] [Z] --add-interface=<interface> Bind the <interface> to a zone [P] [Z] --change-interface=<interface> Change zone the <interface> is bound to [Z] --query-interface=<interface> Query whether <interface> is bound to a zone [P] [Z] --remove-interface=<interface> Remove binding of <interface> from a zone [P] [Z] Options to Handle Bindings of Sources --list-sources List sources that are bound to a zone [P] [Z] --add-source=<source>[/<mask>] Bind <source>[/<mask>] to a zone [P] [Z] --change-source=<source>[/<mask>] Change zone the <source>[/<mask>] is bound to [Z] --query-source=<source>[/<mask>] Query whether <source>[/<mask>] is bound to a zone [P] [Z] --remove-source=<source>[/<mask>] Remove binding of <source>[/<mask>] from a zone [P] [Z] Direct Options --direct First option for all direct options --get-all-chains Get all chains [P] --get-chains {ipv4|ipv6|eb} <table> Get all chains added to the table [P] --add-chain {ipv4|ipv6|eb} <table> <chain> Add a new chain to the table [P] --remove-chain {ipv4|ipv6|eb} <table> <chain> Remove the chain from the table [P] --query-chain {ipv4|ipv6|eb} <table> <chain> Return whether the chain has been added to the table [P] --get-all-rules Get all rules [P] --get-rules {ipv4|ipv6|eb} <table> <chain> Get all rules added to chain in table [P] --add-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>... Add rule to chain in table [P] --remove-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>... Remove rule with priority from chain in table [P] --remove-rules {ipv4|ipv6|eb} <table> <chain> Remove rules from chain in table [P] --query-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>... Return whether a rule with priority has been added to chain in table [P] --passthrough {ipv4|ipv6|eb} <arg>... Pass a command through (untracked by firewalld) --get-all-passthroughs Get all tracked passthrough rules [P] --get-passthroughs {ipv4|ipv6|eb} <arg>... Get tracked passthrough rules [P] --add-passthrough {ipv4|ipv6|eb} <arg>... Add a new tracked passthrough rule [P] --remove-passthrough {ipv4|ipv6|eb} <arg>... Remove a tracked passthrough rule [P] --query-passthrough {ipv4|ipv6|eb} <arg>... Return whether the tracked passthrough rule has been added [P] Lockdown Options --lockdown-on Enable lockdown. --lockdown-off Disable lockdown. --query-lockdown Query whether lockdown is enabled Lockdown Whitelist Options --list-lockdown-whitelist-commands List all command lines that are on the whitelist [P] --add-lockdown-whitelist-command=<command> Add the command to the whitelist [P] --remove-lockdown-whitelist-command=<command> Remove the command from the whitelist [P] --query-lockdown-whitelist-command=<command> Query whether the command is on the whitelist [P] --list-lockdown-whitelist-contexts List all contexts that are on the whitelist [P] --add-lockdown-whitelist-context=<context> Add the context context to the whitelist [P] --remove-lockdown-whitelist-context=<context> Remove the context from the whitelist [P] --query-lockdown-whitelist-context=<context> Query whether the context is on the whitelist [P] --list-lockdown-whitelist-uids List all user ids that are on the whitelist [P] --add-lockdown-whitelist-uid=<uid> Add the user id uid to the whitelist [P] --remove-lockdown-whitelist-uid=<uid> Remove the user id uid from the whitelist [P] --query-lockdown-whitelist-uid=<uid> Query whether the user id uid is on the whitelist [P] --list-lockdown-whitelist-users List all user names that are on the whitelist [P] --add-lockdown-whitelist-user=<user> Add the user name user to the whitelist [P] --remove-lockdown-whitelist-user=<user> Remove the user name user from the whitelist [P] --query-lockdown-whitelist-user=<user> Query whether the user name user is on the whitelist [P] Panic Options --panic-on Enable panic mode --panic-off Disable panic mode --query-panic Query whether panic mode is enabled
Setting up a Web Server
Let's take a look at setting up a basic web server. It's pretty easy to
get Apache running on CentOS in large part because basic web server is a
base configuration that can be installed with yum groupinstall
.
I'll type:
sudo yum groupinstall "Basic Web Server"
Earlier, I copied files from my exercise files over to the server. I put
them in the website directory and now I need to move those over to the
/var/www/html
, which is the web root for Apache on this system.
To do that, I'll type:
sudo cp -R /home/[username]/website/* /var/www/html
Now if I type ls -l /var/www/html
, I can see that I've copied
those files over.
I'll make sure that the apache user is the owner of these files using
chown
to change the ownership recursively or down in to each
folder with -r
and setting the user and group both to Apache.
Then I'll start up the web server with the following command:
sudo service httpd start
I'll switch over to my web browser, and I'll type in my IP address. Well, that's not what I expected to see, I'm seeing this page because Apache can't find my index file. Let's investigate that, this website has an index.HTM file and Apache is configured to look for index.HTML as the default index file.
Let's change that, I'll edit the Apache configuration file. It's:
sudo vi etc/httpd/conf/httpd.conf
I'll look for a section called directory index. Here I can see it's looking for index.html. So, I'll go in to insert mode by pressing I, and type index.htm as well. Now Apache will look for both of these files and serve up whichever one it finds first. I'll save the file by hitting Escape, :wq.
Since I changed the configuration, I need to restart the Apache service, I'll do that with sudo service httpd restart. Now, I'll switch back to my web server and reload my page. All right, it looks like my site's working now. I'd like to take this opportunity to show you what happens if the SELinux security context isn't set quite right. I'll switch back over to my terminal, and to save a little bit of typing, I'll change directory into /var/www/html.
If I type ls -Z to show the security context of the files here, I'll see
that they're all set to httpd_sys_content. I'll use the chcon
command that I mentioned earlier to change the context of one of these
folders. I'll write sudo chcon -R, for recursive, and then dash t to set
the type context. And I'll set the context to something to user underscore
home underscore t, which is the context that anything created in a home
folder would have and I'll reply that to the underscore CSS directory.
Now if I type LS dash Z again I can see that the security context has been changed. I'll switch back over to the web page, and I'll reload and I can't see any of my CSS. All the other content's there because the HTTP server can read that, but it can't access the CSS folder. I'll switch back to my terminal. I can see a little bit of what's going on if I type sudo aureport --avc. I can see down here that HHTPD is trying to access something with a user home type context, there is a mismatch there and I can verify that by typing ps axZ.
I can see here that httpd
is running with the
httpd
type context. If I switch SELinux into permissive mode and
reload my website everything works as expected, I'll turn in forcing back on
and I'll change the context of my CSS folder like to what it should be and
when I reload my page, it works just like normal.
Sharing a Folder with SMB
A common task for servers is providing a place where people can store and share files. Let's take a quick look at how to set up CentOS to serve a folder, using the widely used SMB protocol. First, I'll install the samba-client, I type:
sudo yum install samba samba-client
Once it is installed, I'll edit the Samba configuration file to add a shared folder. I'll type:
sudo vi /etc/samba/smb.conf
Notice that there's some notes about SELinux toward the top of the file, the note about the home folders here will come in handy later on. I'll scroll to the bottom of the file and add a new entry. In square brackets I'll specify the name of the file share and then I'll add a comment and I'll set the path to share. In this case it'll be home and my user folder. I'll tell the system the valid users of this folder include me, I'll say it's not public, I'll say it is writable, It's not printable and I'll set the permissions mask for any files that are created.
[scott] comment = a folder for scott path = /home/scott valud users = scott public = no writable = yes printable = no create mask = 0755
Then, I'll save the file and as the configuration file recommends, I'll run
the testparm
command to test the parameters:
sudo testparm
Looks like my service file is valid. The user that I specified in the configuration file is called a samba user and I need to set up a samba password for that user in my system. I'll do that with the following command:
sudo smbpasswd -a username
I'll start up Samba with:
sudo service smb start
I need to make sure the clients can connect to system on the port that Samba uses, so let's add a firewall rule. I'll type:
sudo firewall-cmd --zone=public --add-service=samba --permanent
Notice that the service name here is samba and not smb. Also note the use of the --permanent
flag. Since the --permanent
flag is being used, the firewall service must be restarted.
sudo service firewalld restart
The samba daemon is one of the services that the targeted SELinux monitors and, by default, a boolean flag called samba_enable_home_dirs
is turned off. To set the flag to true, use the command:
sudo setsebool -P samba_enable_home_dirs on
The process to change this flag can take a while.
Mac Connection
Now let's try to connect the file share, here on my Mac, I got to connect to server under the go menu and finder, and type in smb://192.168.1.201, the IP address of my server. I'm prompted to log in, and I'll type in my username, and my password. Here's my home folder. Here's the website that I uploaded and the file that I downloaded from RPMForge. I can create a folder, too and if I list my home folder I can see that it was, in fact, created.
PC Connection
Over here on my PC, I can hit Start+R and bring up a run dialog. I'll type the following:
\\[LinuxIPAddress]\[ShrName]
I will be prompted to enter the username and password for the server and here it is. Here's the folder that I created for my Mac and I can create another folder if I want to or I could copy files or I could delete them as I like.
Linux to Another Server/Client
To connect from your server to a Samba share on another server or client, ensure that you have the appropriate software available:
sudo yum install cifs-utils
A mount point is required. This is a place on my Linux file system where the remote server's files will be available. I'll type:
sudo mkdir /mnt/my_share
I've already configured a Windows PC and a Mac work station to share a folder using Samba. And I know the username and password for each share. First, I'll connect to my Windows machine. I'll use:
sudo mount -t cifs -o user=Rodney //192.168.1.174/Samba /mnt/my_share
When prompted, enter the password. Once the password is entered, it should be mounted. To verify, use the command:
ls -l /mnt/my_share
We can see the PC Windows' folder that was connected to. It is possible to see
what's inside the PC Windows' folder. When the shared folder is no longer
needed, the umount
command is used to remove the share. Note
that if you are currently in the /mnt/my_share
directory,
the following command will not work.
sudo umount /mnt/my_share
Note: If you get a message that indicates that the target is busy
, use the command to force it out:
sudo umount -l /mnt/my_share
Connecting to an SMB share on a Mac is a little bit different. The connection string is almost the same, but I need to add the nounix
option after my username. I'll write:
sudo mount -t cifs -o=macusername,nounix //192.168.1.2/sharedrive /mnt/my_share
Type in the password, and now I can take a look at what's in that shared folder.
ls -l /mnt/my_share/
Looks like everything's blank, let me try that again.
ls -l /mnt/my_share/
Now it works. That's a bug that I've come across when I connect to Mac file servers. And now that I'm done with this I can type:
sudo umount /mnt/my_share
Make it Permanent
It can get tedious to mount a shared folder every time you reboot. Luckily,
we can tell system to mount our folder whenever it starts up. Linux has a
file called fstab
which tells the system what file systems to
mount when it starts. To edit it, I'll open it up in vi.
sudo vi /etc/fstab
The formatting in this file requires a little structure. So, let's write our fstab
entry one field at a time. The first field is the file
system to be mounted.
In the case of the entries already here, you can see /dev/mapper/centos-root and the boot and swap partitions as well. I'll enter, //192.168.1.2, and then the share name. In this case I'm connecting to my Mac. The second field indicates where I'm going to mount the remote file system in my local file system. I can see that for centos-root it's mounted at /, or the root of my file system. And mine is going to be /mnt/my_share. The third field is the type.
In the case of the existing ones, there's a few XFS listings and one for swap. Just like before, I'll use CIFS. The fourth field defines options for mounting the file system. That's where I'll put my credentials and options for connecting. I'll put in user, equals and then my user name. And because I don't have the opportunity to enter a password when the system starts up, I have to specify the password for the share here as well. I'll type pass, equals and I'll type in my password.
And because I'm connecting to a Mac server, I need the nounix directive as well. If you're connecting to a Windows Samba share, you won't need this. The fifth field indicates whether the system should dump the file system or back it up. Usually, this relates to a tape backup system, and you should just leave this at 0. The sixth column indicates whether to check the file system on startup. Just leave that one at 0, because our remote server is responsible for checking the file system under the share. This machine isn't. I'm done, so I'll hit Esc and type :wq, to write the file and save it.
And now I'll reboot. When the system's available again, I'll reconnect and type my password correctly, and then I'll take a look and see what's in the folder that I mounted my share point at. Again, because I'm connected to a Mac server, I need to do the ls command twice for things to actually show up. But it's mounted there. That's pretty handy. Obviously, having the password stored in clear text in the fstab file isn't optimal. The system security will protect you to some degree, but sudoers will be able to read this file.
You might consider setting up a user on your file server with a password that doesn't match anything you use personally.
GUI
Let's take a look at setting up a graphical user environment. I'm going to use the yum Groupinstall command to set up the Gnome desktop base configuration. But before I do that I need to make one change to my system. At the time of recording, there was a version conflict between one of the packages in the Gnome desktop install set, and a package in the RPMForge Repository. To avoid that going forward, I'll remove the RPMForge Repository. I'll type sudo, yum, groupinstall, gnome desktop.
This will download almost 600 megabytes of software. And when it's all installed, it'll take up an additional 1.8 gigabytes on my system. This'll take a while so we'll speed up the video. But you might want to go get another cup of coffee. After the installation finishes I'll restart my computer and switch over to looking at the actual screen of the device. Because of the software that we've installed, I need to agree to some licensing information. That comes up in this text interface here. And to accept the license, I'll press 2, Enter, and then select 2 to say that I accept the license agreement.
Then I'll type C to continue, and C to continue again. I'll log in. And I'll type, startx. And now I have a graphical user interface. I'll click through the welcome screens. And then I'll click start using CentOS Linux. In the next movie I'll show you around this interface.
Here on the CentOS desktop, we can go up to the top left corner, and click Applications. Here, there's a couple different categories of applications. There's Favorites, which are things that I've most recently used. Accessories, like a calculator, clocks, file browser, and gedit, a text editor. Documentation including a link to the help, if you need to get back there. Some Internet tools, including the Firefox web browser, the LibreOffice productivity suite. Under the Sundry category there is a couple useful things. Like an application to manage the firewall and network connections, and print settings if you have a printer.
There's System Tools, with some things like Software Update and a system monitor. The System Monitor shows you your file systems, resources that are currently being used on the system, and a handy listing of processes that are currently running. Under Utilities you'll find a disk usage analyzer, a program that'll tell you some more information about your disks, and a terminal. Up in the top right corner, there's a volume control, a link to some network settings, and there's a clock with a calendar. Here under the User menu, I can see that I'm logged in as root.
I can change my user settings. I can log out, power off the system. Or if there's updates, I can install updates and restart. I'm going to log out because in the next movie, we'll be switching over to the terminal.
Since this computer's a server, it's not likely that it's going to have a display, a mouse and a keyboard attached to it at all times. So what happens then, if we need to use the desktop environment? For that, I'll install software called VNC, or Virtual Network Computing. I'll write sudo yum install tigervnc-server. Since VNC the network service, we need to tell the firewall about it. I'll write sudo, firewall, cmd zone equals public, add service, equals vnc-server and It'll make it permanent.
And then, since I've made a change to the firewall, I need to restart it, sudo service firewalld restart. I'll clear the screen then to start up the VNC server, I'll type vncserver. I need to specify a password for my user to connect to the VNC server. It won't prompt me for a username and password, it will only identify me by the password I provided. So I'll type one in, and I see that the vnc server has created some files.
One of them is the log file. Let's take a look at that, I'll write cat home/scott/.vnc/apollo\:1.log, down here toward the bottom, I can see that it's listing for VNC connections on port 5901. 5901 will be associated with my users desktop, when I connect to that the port and provide it my password. It'll start up my x session or my desktop session. If another user needs to run VNC, they'll run their own process on their own port, the next user would be port 5902, then 5903, and so on and so forth, so I'll switch over to the Mac VNC viewer, which is built in, I can go to Go, connect to server, and type in the address of my VNC server, vnc://192.168.1.201 port 5901, then I'll type in the password and here's my desktop, let's maximize that.
I can browse around. Here you can see my home folder and all of the files that are inside of my home folder. You'll notice that this is a little bit laggy and that's because it's over the network. So of course you don't want to be watching movies or doing photo editing over this kind of thing but it's handy if you need to use a graphical user interface on your server. I can close this window and I can come back here and I can reconnect because the process is still running. As you see, the window stayed up, my session on the server hasn't changed even though I disconnected from it earlier.
If the system restarts, however, this session will go away.
One of the handiest tools for trouble shooting the start up process of your system is called systemd-analyze. It can show you how long the system took to start up. And you can break that information down further by process. I'll write systemd-analyze blame. Here's a list of all of the start up services, and the amount of time that they took to execute. I'll press q to exit that. You can also have systemd-analyze, generate a timeline of your boot process, with a plot option. I'll write systemd-analyze, plot, and then redirect the output of that to a file called startup.svg.
I can switch over to my FTP client, and I can grab that file and put it here on my desktop. Then I'll switch over to a program that can open SVG files, in my case I'll use Chrome, and I'll open it up. Down here there's a network process that took seven seconds to start up. If you guessed that was my system waiting for my Samba share to mount, you'd be right.
It can be handy to check out the messages that applications and the system write to log files. I'll change directory over to var log where these log files are stored. Let's take a look at what's here, there's a log for yum, and it shows everything that the package manager has done. There's also secure log, which shows security events, including uses of sudo on the system There's also messages where a lot of information shows up from processes that don't have their own specific log files.
And you can take a look at the audit log. Either manually, in audit, audit log or in a much more readable way, through the aureport tool. Aureport by itself shows you some statistics, like successful and failed authentications, AVC and MAC events from SELinux, and more You can dive deeper into each of these areas with particular flags. For example, sudo, aureport, avc shows you information from the avc log.
And aureport-c gives you a list of configuration changes on the system. You can find more flags in the man page, by typing man, aureport, and then pressing space bar to page down. If you're having a problem with something, chances are it'll show up in a log. And log entries are usually a great place to start tracking down solutions.
If your system is getting sluggish, it might be time to look for greedy processes or space constraints. You can a look at disk resources with the df command. I like to use the h flag, because it returns numbers in human readable formats, Gigabytes instead of blocks. Here I can see I have 3.7 Gigabytes used on my root file system, which has a total size of 27 Gigs, leaving me 23 Gigabytes available. Of course, I don't have control over the rest of these file systems here. But it's nice to be able to see how much space is used on my root file system.
Using the top command, you can see what resources processes are using. This shows system CPU, memory and swap usage, as well as all of the processes on the system. There's a bunch of key commands you can use with top and you can see them by pressing h. There are way more than I can go into here, but I encourage you to explore them. There are some flags you can use with top, as well, which you can learn about from the man page. I'll write man top. And press space bar to scroll down a few pages. For now, I'll use the u flag to see my users activity.
I'll write top dash u, and my username. There's not a whole lot going on here. There's 2 SSHD sessions, one from this computer and one from another computer. SFTP server, because I still have Cyberduck running in the background, and bash, because I'm using bash at the command line. I'll start up a resource hungry process. I'll write yes and pipe that to /dev/null and write an ampersand. This basically writes the letter y as fast as the system will let it. Yes is a utility that you can use in scripts to answer in the affirmative.
The output's being directed to dev/null, so the system won't save it or store it or do anything with it. It just goes off into nothingness. The ampersand tells the system to run the command in the background and return me to the command line. So now if I type top -u and my username, I can see that yes command. It's taking almost 100% of the CPU, and that's 100% of one core. This system has two cores, so you can see on the third line, %Cpus usage or us is about 50%. The other 50% is over in idle, toward the middle of the screen.
If I don't want that process running anymore I can hit k
to kill
a process. I'll enter the process ID, in this case - 2728, for that yes
command. And then verify, and it kills that process, freeing up my CPU
resources.
As I mentioned earlier, CentOS is supported by the community. A great way to get in contact with that community, if you have questions or need help with anything, is to visit centos.org/forums. Here you can find discussion boards, for both general questions and version specific things. Including general support, software support, hardware support, networking, and security support.