Published on

Red Hat Administration

Authors
  • Name
    Jackson Chen
Login to a Remote System
# ssh with login credential
ssh remoteuser@remotehost

# Login to remote system without password, using public key authentication
ssh -i mypub.pem remoteuser@remotehost

Note:
1. The user has using ssh-keygen to generate private key and public key
2. Private key keep on user homedrive
3. The user public key is stored in the user account on the remote host
# The term describes the name of the program to run
    command

# The term describes the part of the command line that adjust the behavior of a command
    option

# The term describes the part of the command line that specifies the target that the command should operate on
    argument
# To type more than one command on a single line, use
    semicolon ;     # ";" is a member of a class of characters called metacharacters in bash

# Display file type
    file /etc/chrony.conf   # display chrony.conf file type
# head, tail - display the beginnign and the end of a file
    -n      # Specify a different number of lines,  tail -n 10
    -l      # number of lines
    -w      # number of words
    -c      # number of characters
Press Ctrl+A    # Jump to the begining of the command line
Press Esc+.     # "." is required, to copy the last argument of the previous command
date        # display current time and date, Tue Aug 06 10:57:25 PM PDT 2022
date +%R    # display the current time in 24 hour clock time,  20:58
# To count the number of lines, words and bytes in the file
    wc filename     # word count
    ls | wc -l      # file count


# To run the most recent command in the command history
    !!

Managing files from the command line
# Significant Linux directories
Directory       Purpose
---------------------------------
/boot   File to start the boot process
/dev    Special device files that system uses to access hardware
/etc    system specific configuration files
/home   Home directory
/root   Home directory for superuser "root"
/run    runtime data for processes taht started sine the last boot.
        # The content will be deleted on reboot, non persistent data
/tmp    A world-writable for tempoary files
        # files that are not accessed, changed or modified for 10 days will be deleted
/usr    Installed software, shared libraries
    /usr/bin    # user commands, regular commands and utilities
    /usr/sbin   # system administration commands
    /usr/local  # locally customized software
/var    system specific variable should persist between boots

Linux file systems, including ext4, XFS, GFS2, and GlusterFS, are case-sensitive.

The prompt displays the tilde character (~) when your current working directory is your home directory.

The ls command has multiple options for displaying attributes on files.

-l  long listing format
-a  all files, including hidden files
-R  recursive, to include the contents of all subdirectories
cd -    # Return you to the working directory before the current working directory
cd ../..    # change the working directory up two levels from the current directory
cd ..       # change to the parent directory
# Create missing parent directory
mkdir -p ParentDir/dir1
ls -lR ParentDir/   # show folder structure and files in each folder

# copy parent director, and sub-directories and contents to "." current working directory
cp -r ../ParentDir/ .   
cp -r ~/Dir1  ~/Dir2  .     # copy Dir1 and Dir2 directoreis and their contents to the current working directory

# Rename file, could move and rename file
mv -v oldfilename /newdir/newfilename

# Delete folders and contents "-r"
rm -r Dir1 Dir2 Dir3
# create hard link (another file name) that points to an existing file
ln  existingfile    /tmp/existingfile-hardlink.txt

# Verify two files are hard links
ls -il existingfile  /tmp/existingfile-hardlink.txt 

Note:  
    a. Hard link only with regular file, can NOT link to directory or special file
    b. both files need to be on the same file system

df  -Th     # list file system and file system type
df /dir1 -Th    # list director, and file system type

# verify link count
    ls -l existingfile    /tmp/existingfile-hardlink.txt    # The link count should be 2
# Create symbolic link
# Create symoblic link between two files
ln -s existingfile /tmp/existingfile-symboliclink.txt

# create symbolic link point to directory
ln -s /usr/local/bin   /home/user1/binlink     

Note:
    a. symbolic link can point to a directory
    b. To navigate to the real directory path, rather than the symoblic link directory, use "-P" option
        cd -P /home/user1/binlink
            pwd
            /usr/local/bin  # it will show the real directory

# Verify the symbolic link
    ls -l existingfile /tmp/existingfile-symboliclink.txt   # using "-l" option
Note:
    a. When the orginal regular file is deleted, the target is gone, but the symbolic link still exist
        it becomes "dangling symbolic link"
# vi Editor
v               # enter visual mode, where multiple characters might be selected for text manipulation
shift+v         # line mode, upper case "V"
ctrl+v          # block mode

u       undo the most recent edit
x       delete a single character
vim configuration file
# vim Configuration files
/etc/vimrc      # entire system
~/.vimrc        # specific user

# Example configuration
# set default tab stop (ts) to two space while editing YAML file
# display line numbers while editing file (set number)
autocmd FileType yaml setlocal ts=2
set number
# discard error
    2>/dev/null

>stdfile>2>errorfile    # output to 2 different files
>>samefile>2>&1     # ouput and error to the same file

# Variable
short_hostname=$(hostname -s)
    # hostname will return the FQDN name 
Match File Names with Shell Expansions

The Bash shell has multiple ways of expanding a command line, including pattern matching, home directory expansion, string expansion, and variable substitution. Perhaps the most powerful of these ways is the path name-matching capability, historically called globbing. With the Bash globbing feature, sometimes called wildcards, it is easier to manage many files. By using metacharacters that "expand" to match file and path names that are sought, commands act on a focused set of files at once.

Pattern             Matches
----------------------------------------------------------
*                string of zero or more characters.
?               Any single character.
[abc…]          Any one character in the enclosed class (between the square brackets).
[!abc…]         Any one character not in the enclosed class.
[^abc…]         Any one character not in the enclosed class.
[[:alpha:]]     Any alphabetic character.
[[:lower:]]     Any lowercase character.
[[:upper:]]     Any uppercase character.
[[:alnum:]]     Any alphabetic character or digit.
[[:punct:]]     Any printable character that is not a space or alphanumeric.
[[:digit:]]     Any single digit from 0 to 9.
[[:space:]]     Any single white space character, which might include tabs, newlines, carriage returns, form feeds, or spaces.
Tilde Expansion

The tilde character (~), matches the current user's home directory. If it starts with a string of characters other than a slash (/), then the shell interprets the string up to that slash as a user name, if one matches, and replaces the string with the absolute path to that user's home directory. If no user name matches, then the shell uses an actual tilde followed by the string of characters.

[user@host glob]$ echo ~root
    /root
[user@host glob]$ echo ~user
    /home/user
[user@host glob]$ echo ~/glob
    /home/user/glob
Brace Expansion

Brace expansion is used to generate discretionary strings of characters. Braces contain a comma-separated list of strings, or a sequence expression. The result includes the text that precedes or follows the brace definition. Brace expansions might be nested, one inside another. You can also use double-dot syntax (..), which expands to a sequence. For example, the {m..p} double-dot syntax inside braces expands to m n o p.

echo {Sunday,Monday,Tuesday,Wednesday}.log
mkdir ../RHEL{7,8,9}
Variable

Declare variable and value

VARIABLENAME=value
echo $VARIABLENAME

To prevent mistakes due to other shell expansions, you can put the name of the variable in curly braces
    ${VARIABLENAME}
Command Substitution

Command substitution allows the output of a command to replace the command itself on the command line. Command substitution occurs when you enclose a command in parentheses and precede it by a dollar sign ($). The $(command) form can nest multiple command expansions inside each other.

echo Today is $(date +%A).      # Today is Monday.
echo The time is $(date +%M) minutes past $(date +%l%p).
    # The time is 26 minutes past 11AM.
Protecting Arguments from Expansion

Many characters have a special meaning in the Bash shell. To prevent shell expansions on parts of your command line, you can quote and escape characters and strings.

The backslash (\) is an escape character in the Bash shell. It protects the following character from expansion.
Introduction to the Linux Man page

The pages are stored in subdirectories of the /usr/share/man directory

# Common sections of the Linux Manual (man)
Section Content Type            Descripion
------------------------------------------------
1       user commands           both execution and shell programs
2       system calls            kernel routines invoked from user space
3       library functions       provided by program libraries
4       special files           such as device files
5       file formats            For many configuration files and structures
6       Games and screensavers      Historial section for amusing programs
7       conventions, standards      Protocols, file systems
        and miscellaneous
8       system administration       Maintenance tasks
        and prvileged commands      
9       Linux kernel API       Internal kernel calls

Navigate man pages

Command     Result
------------------------------------------------
Spacebar    Scroll forward (down) one screen.
PageDown    Scroll forward (down) one screen.
PageUp      Scroll backward (up) one screen.
DownArrow   Scroll forward (down) one line.
UpArrow     Scroll backward (up) one line.
D           Scroll forward (down) one half-screen.
U           Scroll backward (up) one half-screen.
/string     Search forward (down) for string in the man page.
N           Repeat previous search forward (down) in the man page.
Shift+N     Repeat previous search backward (up) in the man page.
G           Go to the start of the man page. (lowercase g)
Shift+G     Go to the end of the man page. (uppercase G)
Q           Exit man and return to the command shell prompt.

Searh for man pages by keyword

# Use the man command -k options - keyword
    man -k passwd

Read specific section of man page

man 1 su    # Read the su(1) man page
man x su    # where x is between 1 and 9

To locate the binary, source and manual pages for the passwd utility - whereis

whereis passwd

To list man page with detail information "-k"

man -k <information-2-be-search>
    Example: man -k postscript; man -k lpr

Redirect output to a file or program

Usage       Explanation
----------------------------------
> file      Redirect stdout to overwrite a file
>> file     redirect stdout to append to a file
2> file     redirect stderr to overwrite a file
2> /dev/null    discard stderr error message
> file 2>&1     redirect stdout and stderr to overwrite the SAME file
                    or, &> file    
 >> file 2>&1   redirect stdout and stderr to append to the SAME file, or
                    &>> file
2>&1 > file     redirect stderr to the default place for standard output (The terminal window)
                then, redirects only standard output to file
# Concatenateall 3 input files into one file
cat file1 file2 file3 > /tmp/all-files-in-one   

# Save the process output to /tmp/stdoutput, and error messages to /tmp/error file
find /etc -name passwd > /tmp/stdoutput 2 > /tmp/error

# Save process output to /tmp/output, and discard error message
find /etc -name passwd > /tmp/output 2 > /dev/null

# Save output and errors together to /tmp/all-message-output file
find /etc -name passwd &> /tmp/all-message-output

# Append output and errors to the same file /tmp/all-message-output
find /etc -name passwd >> /tmp/all-message-output 2>&1

tee command

tee copies it standard input to its standard oupt, and redirects its standard output to the file that are given as arguments to the command.

ls -l /etc  |  tee /tmp/save-output  | less
ls -t  | head -n 10 /tmp/ten-last-changed-files

# list the content of the directory, and also redirect and append the content to a file
# use "-a" option to append
ls -l | tee -a /tmp/append-file
# "ls" command options
https://www.rapidtables.com/code/linux/ls.html

Option      Description
----------------------------------------------
ls -a       list all files including hidden file starting with '.'
ls -d       list directories
    ls -d */    list directories only
ls -i       list file inode index number
ls -l       list with long format, show permissions
ls -lh      list long format with human readable file size
ls -s       list file size
ls -ls      list long format with file size
ls -r       list in reverse order
ls -R       list recursively directory tree
ls -S       sort by file size
ls -t       sort by time & date
ls -X       sort by extension name
ls *        list all subdirectories

ls -d $PWD/*    list file and directories with full path
How to redirect stdout and stderr both through pipeline
# Correct way to redirect both standard output and standard error through a pipeline
find / -name passwd 2>&1 | less
Bash Shell environment

You can use the set command to list all shell variables that are currently set or configured. It lists all shell functions.

# bash shell variables
HISTFILE        # specifies which file to save shell history
                    default:  ~/.bash_history
HISTFILESIZE     # specifies how many commands to save in that file
HISTTIMEFORMAT   # defines the time stamp format for every command in the history
                    This variable does not exist by default
                    To configure:   HISTTIMEFORMAT="%F %T "
# To see the shell environment configuration
    set | less
bash shell prompt

The bash shell prompt is controlled by ps1 variable, see PROMPTING section of the bash(1) man page. Whenever a variable value contains space, tab or a return, the value must be enclosed in either single or double quotation marks.

You can assign any variable that is defined in the shell as an environment variable by marking it for export with the export command.

# Command
EDITOR=vim
export EDITOR

# Set and export a variable in one step
export EDITOR=vim

The PATH environment variable contains a list of colon-separated directories that contain programs. When you run a command, the shell looks for the command in each of those directories in order, and runs the first matching file that it finds.

# Verify PATH variable
echo $PATH

# How to append directories to your PATH variable, such as append /home/user/sbin
export PATH=${PATH}:/home/user/sbin

A login shell is invoke when a user logs in locally via the terminal or remotely via SSH. A non-login shell is invoked from an existing session.

# Configure Bash shell environment
    # whole system
    /etc/profile    # interactive login shell, it also source /etc/bashrc 
                    # global login script   
        /etc/bashrc     # Interactive non-login shell

    # user specific
    ~/.bash_profile     # interactive login shell, it also source ~/.bashrc
                        # create a variable in this file for all your interative shell
        ~/.bashrc   # interactive non-login shell
                        # define a variable in this file for non-login shell (only once after the user login)

# Example ~/.bash_profile
#.bash_profile

# Get the alias and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
# Add PS1 shell variable and it values to the ~/.bashrc file
vi ~/.bashrc

PS1='[\u@\h \t \w] '

# To take effect after change, exit and login using ssh, or run command
    source ~/.bashrc

Manage local users and groups

User accounts are of the following main types

  1. superuser superuser name is root, and has account UID of "0"
  2. system users Used by processes that provide supporting services.
  3. regular users

UID ranges

UID values      comment
-----------------------------------
0           superuser (root)
1-200       system account, assigned to system processes
201-999     Assigned to system processes that do not own files on the system.
            Software that requires unprivilged UID is dynamically assigned UID from this pool
1000+       regular, unprivileged users
# Find user information
id  # Show currently login user information
uid UserLoginName   # find user information for another user, such as  uid test01
cat /etc/passwd     # Mapping of username to uid, defined in database file /etc/passwd

# View process information
ps      # process
ps -a   # "-a" to view all processes with a terminal
ps -au  # "-u" option to view the user that is associated with a process

ps -p processid     # verify processid is running
# Group information
cat /etc/group      # each line contains information about one group, divided into four colon-separated fields

Primary group and secondary groups

Every user has exactly one primary group, and any number of secondary groups. For local users, this group is listed by GID field in /etc/passwd file, GID is the 4th field in /etc/passwd. The primary group owns files that the user creates.

Note:
1. When creating a regular user, a group is created with the same name as the user.
2. This group is the primary group for the user.

Users membership in secondary group is stored in /etc/group file. Users are granted access to files based on whether any of their groups have access, regardless of whether the groups are primary or secondary.

Gain superadmin access

Using sudo command to gain superuser access.

sudo -      # switch to "root" set up the shell environment as it it is a new login as that user
sudo -s     # run shell without interactive as root
sudo -i     # run shell interactively as root
sudo - user02   # switch to user02
su - user02     # switch to user02

# Run as another user
su -c username      # similar to Windows runas utility

# Run the command as privilege user - root
sudo usermod -L user02
sudo tail /var/log/secure   # secure file contains the ssh commands that login users run
sudoers

To configure sudo, update /etc/sudoers file. To avoid problems if multiple administrators try to edit the file at the same time, edit it only with visudo command. visudo editor also validates the file to ensure no syntax errors.

# Verify and udpate - /etc/sudoers
%wheel      ALL=(ALL:ALL)   ALL     

Note:
    %wheel string is the user or group that rule applies to
    % symbol specifies a group
    ALL=(ALL:ALL)  ALL   # run command
        1st ALL     on any host
        2nd ALL     as any user
        3rd ALL     as any other group
        Final ALL   # specfy the users in wheel group can run any command

By default, the /etc/sudoers file also includes the contents of any files in the /etc/sudoers.d directory as part of the configuration file. With this hierarchy, you can add sudo access for a user by putting an appropriate file in that directory.

Placing configuration files under the /etc/sudoers.d directory is convenient. You can enable or disable sudo access by copying a file into the directory or removing it from the directory.

# Example to provide sudoers access for user01
1. Create /etc/sudoers.d/user01 file
2. Update with the following content
user01      ALL=(ALL)       ALL
    Note: 
        it only has 1st, 2nd and final ALL, missing 3rd ALL
        The user can run any command as any user (Can't run as any other group)

# Example to provide sudoers access for group
# Create and update /etc/sudoers.d/group1
%group01    ALL=(ALL)   ALL

# To enable users in the games group to run the "id" command as the "operator" user
# Create and update /etc/sudoers.d/games
%games  ALL=(operator)  /bin/id

# Setup sudo to allow a user to run commands as another user without entering their password
ansible ALL=(ALL)   NOPASSWD: ALL

While obvious security risks apply to granting this level of access to a user or group, system administrators frequently use this approach with cloud instances, virtual machines, and provisioning systems for configuring servers. You must carefully protect the account with this access and require SSH public-key authentication for a user on a remote system to access it at all.

Create Update and Delete user account
# create a user
useradd username    
    It create a user called "username"
    sets up the user's home directory and account information
    creates a private group for the user called "username"
    Note: 
        The user can not login until a password is set
        useradd --help  # for more information
        /etc/login.defs     # defines some of the default options for the user account, such as
                            valid UID numbers and default password aging rules
                            Any valules in this file affect only newly created user accounts.
                            Any change to this file does not affect existing users

useradd username -u uidnumber   # create user with specified UID

# Create a new user and add user to required secondary group
useradd -G RequiredSecGroup newuser

# Set user with password
passwd newuser  # New user can NOT login until password is set

Modify or update the user account

# Modify and update user - usermod

usermod option      Usage
----------------------------------
-a, --append        with -G option to add the secondary group
                    usermod -aG TestGroup01     # add user to TestGroup01 secondary group
-c, --comment COMMENT     # Add the comment texgt
                            usermode username -c "Test User 01"
-d, --home HOME_DIR       # specify a home directory for the user accont
-g --gid GROUP          # specify user primary group
                        usermod username -g "Primary Group 01"
-G --Groups GROUPS      # specify a comma-separated list of secdonary groups for the user account
                        usermod -G "group1,group2"
-L, --lock          # Lock the user account
-m, --move-home     # move the user's hme directory to a new location
                    must use it with the -d option
                    usermod username -m -d New_Home_Dir
-s , --shell SHELL  # specify the user login shell
-U, --unlock        # Unlock the user account
                    usermod username -U
How to prevent service account login - nologin shell

The nologin shell acts as a replacement shell for the user accounts that are not intended to interactively log in to the system. It is good security practice to disable an account from logging in to the system when the account does not require it.

# Set the service account login shell to /sbin/nologin
usermod -s /sbin/nologin serviceaccount

Delete the user account

userdel username    # remmove the username from /etc/passwd
userdel -r username     # remove the user from /etc/passwd and delete the user's home directroy

Manage local groups

# Create local group
groupadd        # without options, it uses the next available GID
        GID_MIN and GID_MAX variables defined in /etc/login.defs

groupadd -r systemgroup01   # "-r" option creates system groups.
        SYS_GID_MIN and SYS_GID_MIN variables defind in /etc/login.defs

# Modify and update groups
groupmod -n groupname groupnewname  # "-n" rename the group
groupmod -g 20000 groupname     # update group with new GID

# Delete the group
groupdel groupname      

Change group membership

# Change user group membership
usermod -g primarygroup user01      # change user primary group
            # By default, user's primary group is the same name as the user name

# Add user to a secondary group
usermod -aG secondargroup user01    # "-aG" append the secondary group

# To view user prmary group
cat /etc/passwd | grep username     # New files created are owned by the primary group

# To view user secondary groups
cat /etc/group | grep username
tail /etc/group     # To view group changes

To tempary change a user primary group, just before the user to create new files, so the new files are associated with the required group.

newgrp group01  # The user primary group will return to the default if logout and login again

To create the /etc/sudoers.d/admin file, and grant admin group full administrative privileges

# echo "%admin  ALL=(ALL)   ALL" >> /etc/soders.d/admin

Manage user password

/etc/passwd file no longer store encrypted user passwords. The encrypted password are stored at /etc/shadow

# Content of /etc/shadow
# Only root has read access
Field                   Comment
---------------------------------------------------------
1st field/username      Name of the user account
2nd field               The encrypted user password
3rd field               The days when the password was last chnage, in UTC time
4th field               Minimum days since the last password change before user can change it again
5th field               Maximum days without a password change before the password expires
6th field               The number of days ahead to warn the user that their password will exire
7th field               Number of days without activity, starting with the days the password expired, before the account is locked
8th field               The day when the account expires. An empty field means the account never expires
last field              Reserve for future use
Format of the encrypted password

The encrypted password field stores three pieces of information

1. The hashing algorithm in use
    6   SHA-512
    1   MD5
    5   SHA-256
2. The salt
    originally chosen at randam
3. The encrypted hash
    the encrypted hash of the user's password, combining the salt, and the unencrypted password, then
    encrypting to generate the password has

Each piece of information is delimited by the dollar ($) character.

To change user password configuration

# Example to defined the user password
chage -m 0 -M 90 -W 7 -I 14 -E 9999 user01
    -m  minimum password age
    -M  Maximum password age
    -W  warning period
    -I  Inactive period
    -E  Expiration period

# To dynamically configure base on today's date
date +%F        # verify today's date, such as 2022-08-20
date -d "+30 days" +%F  # plus 30 days from today
chage -E $(date -d "+365 days" +%F) user01  # set user account expired in 365 days
chage -l user01 | grep "Account expires"    # verify user account expiration

# Set password never expired
chage -I -1 -m 0 -M 99999 -E -1 <username>
How to set password must change on next login
chage -d 0 user01   # set the last day of the password change to 0, so
                    # the user must change password on next login

Control Access to Files

The files have three user categories: user, group and others.

  1. If the user has only read access on a directory, the user can list the name of the files in it. However, the user cannot access other information, such as permissions or time stamps.
  2. If the user has only execute access on a directory, then they cannot list file names in the directory.
  3. Anyone who owns or has write permissions to a directory can remove files on it, regardless of the ownership or permissions on the file itself. You can override this behavior by using the sticky bit permission.

The Linux root user has the equivalent of the Windows Full Control permission on all files. However, SELinux policy can use process and file security contexts to restrict access even to the root user.

# The first character of the long listing is the file type
File Type     Comment
---------------------------------------
-              regular file
d              directory
l              symbolic link
c              character device file
b              block device file
p              name pipe file
s              local socket file

Change file and directory permissions

chmod can be interpreted as "change mode" or change file or folder permissions.

chmod who/what/which file|directory

who is the class of user, if you do not provide a class of user, then the chmod command uses the "all" group as default.

who set     Description
----------------------------------------
u   user    the file owner
g   group   member of the file's group
o   other   users who are not the file owner, nor members of the file's group
a   all     All the three previous groups

what is the operator that modifies the which

what  Operation     Description
----------------------------------------
+       add         adds the permission to the file
-       remove      removes the permissions to the file
=       set exactly Set exactly the provided permission to the file

which is the mode, the specifies the permissions to the files or directories

which         mode        Description
------------------------------------------------
r (4 = 2^2)   read        read access to the file. Listing access to the directory
w (2 = 2^1)   write       write permissions to the file or directory
x (1 = 2^0)   execute     execute permission to the file.
                                Allows to enter the directory, and access files and subdirectories inside the diretory
X         speical execute   Execution permissions for a directory, or execute permissions to a file, if
                              it has at least one of the execute bits set
# To recursively set permissions on the files in a entire directory, "-R"
chmod -R g+rwx /home/user01/dir01

Special execute X option

# all to set execute (search) permission on directories, so directory contents can be accessed,
# without changing permissions on the files
chmod -R g+rwX /tmp/dir01 

Note: If a file has any execute permission set, 
        then the X option sets the specified execute permission on that file too.

Change permissions with the Octal method

# Octal method - xxx (rwx)

Change file and directory user or group ownership

By default, new files have a group ownership that is the primary group of the user that creates the file. In RHEL, a user's primay group is usually a private group with only that uesr as a member. The root user can grant file ownership to any group, but regular users can change the file's group ownership if the user are a member of the destination group.

# Change owner
chown -R user01 dirname     # recursively change the ownership of an entire directory tree

# change owner and group at the same time
chown -R user:group dirname     # syntax  owner:group

# change of group ownership of a directory
chown :groupname  dirname
Special permissions - chmod

Special permissions are a fourth permission type in addition to the basic user, group, and other types. As the name implies, special permissions provide additional access-related features beyond what the basic permission types allow.

# Effects of speical permissions on files and directories
Permissions     Effect on files                 Effect on directories
------------------------------------------------------------------
u+s (suid)      file executes as the user       no effect
                that owns the file, not
                as the user that ran the file
------------------------------------------------------------------
g+s (sgid)      file execute as the group       files created in the directory
                owns the file                   have the group owner to match
                                                the group owner of the directory
------------------------------------------------------------------                                           
o+t (sticky)   no effect                        Users with write access to the directory
                                                can remove only files that they own, 
                                                they can not remove or force saves to files
                                                that other users own

# Example - configure setgid(2),
#   and read, write and execute permission for owner and group,
#   no permission for others
chmod 2770 /tmp/dir01

ls -ld /tmp/dir01   # verify the permissions are set properly

Default file permissions - umask or user file creation mask

On creation, a file is assigned initial permissions. Two things affect these initial permissions. The first is whether you are creating a regular file or a directory. The second is the current umask, which stands for user file-creation mask.

Additionally, the shell session sets a umask to further restrict the initial permissions of a file. The umask is an octal bitmask that clears the permissions of new files and directories that a process creates. If a bit is set in the umask, then the corresponding permission is cleared on new files.

# Example
umask 0002      clears the write bit for other users.
umask 0077      clears all the group and other permissions of newly created files
Note:   The leading zeros indicate that the special, user, and group permissions are not cleared. 
How to verify current shell umask value
# Verify current shell umask value
    umask       # without arguments

The umask clears the permission for new file and directory during the creation.

Note: 
    The default umask values for Bash are defined in the /etc/profile and /etc/bashrc files.

# shell umask is configured at global login script /etc/profile
# Example of /etc/profile umask configuration
    cat /etc/profile
    # Overwrite default umask configuration
    if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
        umask 007
    else
        umask 022
    fi

The shell startup scripts set the default umask for users. By default, if the account's UID is 200 or greater and the username and primary group name are the same, then the account is assigned a umask of 002. Otherwise, the umask is 022.

The root user can change the default umask by adding a local-umask.sh shell startup script in the /etc/profile.d/ directory.

# Example of local-umask.sh file
[root@host ~]# cat /etc/profile.d/local-umask.sh
# Overrides default umask configuration
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
    umask 007
else
    umask 022
fi

Monitor and manage Linux process

Linux process states

# Compare the output of following commands
ps -aux
ps aux


Name      Flag  Kernel defined state name and description
-------------------------------------------------------------------------
Running     R   TASK_RUNNING
                The process is either executing on a CPU or waiting to run
----------------------------------                
Sleeping    S   TASK_INTERRUPTIBLE
                The process is waiting for some condition
            D   TASK_UNINTERRUPTIBLE
                The process is sleeping, does not respond to signals. If process interrupted, it may cause an unpredictable device state.
            K   TASK_KILLABLE
                Identical to the uninterruptible D state, but modified to allow be killed (exit completely)
            I   TASK_REPORT_IDLE
                A subset of state D. It accepts fatal signals.
----------------------------------
Stopped     T   TASK_STOPPED
                The process is stopped (suspended), usually by being signaled by a user or another process.
                The process can be continued (resumed) by another signal to return to running.
            T   TASK_TRACED
                A process that is being debugged.
----------------------------------
Zombie      Z   EXIT_ZOMBIE
                A child process signals to its parent as it exits. All resources except for the process identity (PID) are released.
            X   EXIT_DEAD
                When the parent cleans up (reaps) the remaining child process structure, the process is now released completely.
                This state cannot be observed in process-listing utilities.

The "s" column of the top command, or
the STAT column of the ps command shows the state of each process.

Job and sessions

With the job control shell feature, a single shell instance can run and manage multiple commands.

A job is associated with each pipeline that is entered at a shell prompt. All processes in that pipeline are part of the job and are members of the same process group. You can consider a minimal pipeline to be only one command that is entered at a shell prompt that creates a job with only one member.

Only one job at a time can read input and keyboard-generated signals from a particular terminal window. Processes that are part of that job are foreground processes of that controlling terminal.

A background process of that controlling terminal is any other job that is associated with that terminal. Background processes of a terminal cannot read input or receive keyboard-generated interrupts from the terminal, but are able to write to the terminal. A background job might be stopped (suspended) or it might be running. If a running background job tries to read from the terminal, then it is automatically suspended.

Each terminal runs in its own session, and can have a foreground process and any number of background processes. A job is in only one session, which belongs to its controlling terminal.

The ps command shows the device name of the controlling terminal in the TTY column. Some processes, such as system daemons, are started by the system and not from a controlling terminal. These processes are not members of a job, and cannot be brought to the foreground. The ps command displays a question mark (?) in the TTY column for these processes.

Run Jobs in the Background

Any command or pipeline can be started in the background by appending an ampersand (&) character to the command. The Bash shell displays a job number (unique to the session) and the PID of the new child process. The shell does not wait for the child process to terminate, but instead displays the shell prompt.

# Example to run job in backgroup
sleep 10 &  

# To suspend the running process in terminal shell
    ctrl+z

# To view all jobs
    jobs
    ps jT   # view remaining jobs

# Restart the control job in the background
    bg
    bg %jobnumber       Example  bg %1

# Bring the job to foreground
    fg %jobnumber       Example    fg %1

Kill processes

Use commands to kill and communicate with processes.

Process control with signals

A signal is a software interrupt that is delivered to a process. Signals report events to an executing program. Events that generate a signal can be an error, an external event (and I/O request or an expired timer), or by the explicit use of a signal-sending command or a keyboard sequence.

Signals by their short (HUP) or proper (SIGHUP) name

Signal  Name    Description
----------------------------------------------------------
1       HUP     Hangup
                Reports termination of the controlling process of a terminal, also
                requests process re-initilization (configuration reload) without termination
----------------------------------
2       INT     Keyboard interrupt
                Causes program termination, ctrl+c
----------------------------------
3       QUIT    keyboard quit, similar to SIGINT
                Adds a process dump at termination, ctrl+\ (core dump)
----------------------------------               
9       KILL    kill, unblockable
                Causes abrupt program termination, it cannot be blocked, ignored, or handled
----------------------------------
15      TERM    Terminate
                Cause program termination, it can be blocked, ignore or handled.
                The clean way to ask a program to terminate
----------------------------------
18      CONT    Continue
                Sent to a process to resume if stopped, it cannot be blocked, it always resumes the process.
----------------------------------
19      STOP    Stop
                Unblockable, suspends the process, it cannot be blocked or handled
----------------------------------
20      TSTP    keyboard stop
                Unlike SIGSTOP, it can be blocked, ignored, or handled. ctrl+z

# To kill the process
pkill -SIGSTOP processname
pkill -SIGKILL processname
pkill -SIGCON processname   # resume process

You can signal the current foreground process by pressing a keyboard control sequence

1. to suspend (Ctrl+z)
2. kill (Ctrl+c)
3. core dump (Ctrl+\) the process. 

However, you might use signal-sending commands to send signals to background processes in a different session.

You can specify signals either by name (for example, -HUP or -SIGHUP options) or by number (the related -1 option). Users can kill their processes, but root privilege is required to kill processes that other users own.

The kill command uses a PID number to send a signal to a process. Despite its name, you can use the kill command to send any signal, not just those signals for terminating programs. You can use the kill command -l option to list the names and numbers of all available signals.

How to administrative log out users

Similar to Windows, to terminal login session, use w command to list user logins and their currently running processes.

# To list user login session
    w       # similar to Windows, query session, or query session /computer:servera

All user login sessions are associated with a terminal device (TTY).

Devie name      Description
--------------------------------
pts/N           a pseudo-terminal that is associated with a graphical terminal window or remote login session
ttyN            user is on a system console, alternative console, or another directly connected terminal device

Processes and sessions can be individually or collectively signaled. To terminate all processes for one user, use the pkill command.

# To identify the PID owned by the user
pgrep -l -u username

# To list the login sessions by the user
w -h -u user    # Identify terminal number pts/N or ttyN

pkill -t ttyN/pts/N     # kill the user terminal session
pkill -SIGKILL -t ttyN  # kill the user terminal session

To verify the process tree for the system, or a single user

pstree -p username  # list the process tree of a single user
pkill -p processid        # kill the required processid 
Monitor process activity

Load average is a measurement that Linux kernel provides, to represent the perceived system load for a period of time.

The kernel collects the current load number every five seconds based on the number of processes in runnable and uninterruptible states. This number is accumulated and reported as an exponential moving average over the most recent 1, 5, and 15 minutes.

The uptime command is one way to display the current load average. It prints the current time, how long the machine has been up, how many user sessions are running, and the current load average.

# To display the current load average, and other information
    uptime      
    top     # ? or h        help for interactive keystrokes

# Verify the number of logical cpu
grep "model name" /proc/cpuinfo | wc -l  

Control services and daemons

systemd daemon

The systemd daemon manages the startup process for Linux, including service startup and service management in general. The systemd daemon activates system resources, server daemons, and other processes both at boot time and on a running system.

The first process that starts (PID 1) is the systemd daemon, which provides these features:
•   Parallelization capabilities (starting multiple services simultaneously), 
        which increase the boot speed of a system.
•   On-demand starting of daemons without requiring a separate service.
•   Automatic service dependency management, which can prevent long timeouts. 
        For example, a network-dependent service does not attempt to start until the network is available.
•   A method of tracking related processes together by using Linux control groups.

Service Units

The systemd daemon uses units to manage different types of objects:
•   Service units have a .service extension and represent system services. 
        You can use service units to start frequently accessed daemons, such as a web server.
•   Socket units have a .socket extension and represent inter-process communication (IPC) sockets that systemd should monitor. 
    If a client connects to the socket, then the systemd manager starts a daemon and passes the connection to it. 
    You can use socket units to delay the start of a service at boot time and to start less frequently used services on demand.
•   Path units have a .path extension and delay the activation of a service until a specific file-system change occurs. 
    You can use path units for services that use spool directories, such as a printing system.

To manage units, use the systemctl command. For example, display available unit types with the systemctl -t help command. 
The systemctl command can take abbreviated unit names, process tree entries, and unit descriptions.
systemctl       # without arguments, list units that are both loaded and active

systemctl list-units --type=service     # list currently loaded service units
systemctl list-units --all      # list all service units regardless of the activation state
systemctl list-units --state=load | active | sub

# To display services that are installed either enabled or disabled
systemctl list-unit-files --type=service
View service states

View a unit's status with the systemctl status name.type command. If the unit type is omitted, then the command expects a service unit with that name.

systemctl status sshd.service
systemctl status sshd

Note:
In RHEL 6 and earlier, run command
    service <name> status

systemctl is-active sshd.service
systemctl is-enabled sshd.service
systemctl is-failed sshd.service

Note: 
1. Verify journalctl for troubleshooting the service
2. To view all services that are failed
    systemctl --failed --type=service

systemctl list-units --type=socket --all    # list all socket units, active and inactive

Control system services

Control system daemons and network services with systemctl.

systemctl stop sshd.service
systemctl start sshd.service
systemctl restart sshd.service

# Some services can reload their configuration files without requiring a restart, called service reload
systemctl reload sshd.service

# When unsure whether the service has the function to reload the configuration file change
systemctl reload-or-restart sshd.service
List unit dependencies
systemctl list-dependencies sshd.service
systemctl list-dependencies sshd.service --reverse
Mask and Unmask Services

Masking a service prevents an administrator from accidentally starting a service that conflicts with others. Masking creates a link in the configuration directories to the /dev/null file which prevents the service from starting. To mask a service, use the systemctl command mask option.

systemctl mask sendmail.service
    Created symlink /etc/systemd/system/sendmail.service → /dev/null

# To verify the state of the service
systemctl list-unit-files --type=service
    # It will show the service STATE as "masked"

Attempting to start a masked service unit will fail, use the systemctl unmask command to unmask the service unit.

systemctl unmask sendmail

Enable Services to Start or Stop at Boot

Creating links in the systemd configuration directories enables the service to start at boot. You can create or remove these links by using the systemctl command with the enable or disable option.

# To enable service to start at boot
systemctl enabled sshd.service          # enable the service, but it does not start
systemctl enabled sshd.service --now    # Enable and start the service with one command

systemctl disable sshd.service

This command creates a symbolic link from the service unit file, usually in the /usr/lib/systemd/system directory, to the disk location where the systemd command looks for files, in the /etc/systemd/system/TARGETNAME.target.wants directory.

# Summary of systemctl services commands
systemctl status unit
systemctl stop unit
systemctl start unit
systemctl restart unit
systemctl reload unit
systemctl mask unit
systemctl unmask unit
systemctl enable unit
systemctl disable unit

Configure and secure SSH

The OpenSSH package provides the Secure Shell or SSH protocol. With SSH protocol, systems can communicate in an encrypted and secure channel over an insecure network.

# ssh to remote system
ssh remoteuser@remotehost
SSH host keys

SSH secures communication through public-key encryption. When an SSH client connects to an SSH server, it sends a copy of its public key to the client before logging in. This key helps to set up secure encryption for the communication channel and to authenticate the client's system.

When a user runs the ssh command for connecting to an SSH server, the command checks for a copy of the server's public key in its local known hosts file.

The key might be preconfigured in the /etc/ssh/ssh_known_hosts file, or the user might have the ~/.ssh/known_hosts file that contains the key in their home directory.

If the client has a copy of the key, then the ssh command compares the key from the known hosts server files to the key that it received. If the keys do not match, then the client assumes that the network traffic to the server is compromised and prompts the user to confirm whether to continue with the connection.

# StrictHostKeyChecking parameter
/etc/ssh/ssh_config or ~/.ssh/config        # verify the configuration file
    StrictHostKeyChecking   yes | no        # when set as "yes", it public key do not match, ssh connection will aborts
How to verify the fingerprint of the server's SSH host key
# Run command
    ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub

How to run RHEL as Single User or Maintenance Mode

Single user mode, also referred to as maintenance mode, allows a single super user to recover/repair the system problems.

Maintenance mode uses runlevel1.target or rescue.target on Red Hat (RHEL) 7/8 based systems.

There are two types of Single User mode

# Single User Mode - Recover root password / Emergency Mode
1. Reboot your system. On the GRUB2 boot screen
2. press the "e" key to edit the selected kernel. You need to select the first line, the first one is the latest kernel
3. Depending on your RHEL/CentOS version, find the word “linux16” or “linux”, 
    and press the “End” button on the keyboard to go to the end of the line, 
    and add the keyword “rd.break” as shown in the screenshot below
4. then press “Ctrl+x” or “F10” to boot into single-user mode.
Note:
    This change, mounts your root file system into “read only (RO)” mode. 
    You can check this by running the command below. Also, the output below clearly shows that you are in “Emergency Mode”.
5. To make changes to the “sysroot” file system you need to remount it with READ and WRITE (RW) mode:
    mount -o remount,rw /sysroot
6. Run the below command to change the environment, commonly known as “jailed directory” or “chroot jail” :
    chroot /sysroot
7. Now, the single-user mode is ready to use. 
    Once you have fixed your problem, and to exit the single user mode, perform the following steps.
Note
    CentOS/RHEL 7/8 uses SELinux by default, so create the following hidden file, 
    which will automatically perform a relabel of all files on next boot:
        touch /.autorelabel
8. Finally, run the below command to restart the system. Alternatively, type “exit” command twice to restart your system:
        reboot -f

Single-user mode provides a Linux environment for a single user that allows you to recover your system from problems that cannot be resolved in networked multi-user environment. You do not need an external boot device to be able to boot into single-user mode, and you can switch into it directly while the system is running. To switch into single-user mode on the running system, issue the following command from the command line:

    init 1

In single-user mode, the system boots with your local file systems mounted, many important services running, and a usable maintenance shell that allows you to perform many of the usual system commands. Therefore, single-user mode is mostly useful for resolving problems when the system boots but does not function properly or you cannot log into it.

##### Single User Mode / Maintenance Mode (with known root password)
This mode will be able to run most of the Linux commands

1. Reboot your system. On the GRUB2 boot screen
2. press the "e" key to edit the selected kernel. You need to select the first line, the first one is the latest kernel
3. Depending on your RHEL/CentOS version, find the word “linux16” or “linux”, 
    and press the “End” button on the keyboard to go to the end of the line, 
OR
    press the "a" to append the line
4. Type "single" as a separate word at the end of the line
5. Press Ctrl+x to continue
6. when prompt for root password, enter the root password, and press ENTER
Not:
    The screen shows that you are in rescue mode.
7. You will be able to umount, resize (lvremove, lvcreate logical partitions)
Note:
    Otherwise, you will be getting partition busy, and not able to umount partition
8. After fix the problem, reboot the system by running "reboot"