Advanced CentOS 7 Server Configuration – Tips and Tricks

Advanced configuration of the CentOS 7 server

This can be a web server, a VPN server, a monitoring server etc. Let’s talk about the initial settings of the CentOS 7 system, which increase the security and convenience of working with the server. Please note that in the 7th version of the system there have been some changes compared to previous versions.

To configure almost any server you need to perform a series of standard steps that differ little in different situations. Whatever functionality you have prepared, you will have to set the correct time and enable its auto-update. Without installing network settings, I can’t imagine the work of a modern server at all. No example comes to mind. The same set of settings almost on the machine is performed after installation. I want to share with you – what I first of all setup and install on any new CentOS 7 server.

  • Install package patches and upgrades

yum upgrade

  • Install Nano editor

yum install -y nano

  • Install Midnight Commander

For ease administration I always install Midnight Commander. Immediately for it I turn on the syntax highlighting of all files that are not explicitly indicated in the /usr/share/mc/syntax/ Syntax file with syntax for sh and bash scripts. This universal syntax is normally suitable for configuration files, which most often have to work on the server. Overwriting the unknown.syntax file. It is this template that will be applied to .conf and .cf files, since no syntax is explicitly associated with them.

yum install mc

cp /usr/share/mc/syntax/sh.syntax /usr/share/mc/syntax/unknown.syntax

  • Install network and system utilities.

yum install net-tools

yum install bind-utils

  • Disable SELinux if you don’t know how to configure it yet.

nano /etc/sysconfig/selinux

change value
SELINUX = disabled
For the changes to take effect, reboot:

reboot

  • Configure the network in CentOS

To do this, open the file /etc/sysconfig/network-scripts/ifcfg-eth0

nano /etc/sysconfig/network-scripts/ifcfg-eth0

In the IPADDR field, enter your IP address, in NETMASK the network mask, in the GATEWAY gateway, DNS1 address of the DNS server. Save the file and restart the network to apply the settings:

/etc/init.d/network restart

  • Change Time zone settings and time sync

You can check time on the server with this command:

date

To change the time zone, you need to select the appropriate time zone file in /usr/share/zoneinfo. In case you have Berlin time zone, do the following:

mv /etc/localtime /etc/localtime.bak

ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime

you can also use this command:

timedatectl set-timezone Europe/Berlin

CentOS 7 has a chrony time synchronization utility. In the standard installation, it must be installed in the system, in the minimum it is not. For time synchronization, you can use the more familiar program that is present in almost all unix distributions – ntp. Install the ntp time synchronization utility and disable chrony:

systemctl stop chronyd

systemctl disable chronyd

yum install ntp

Sync the time:

/usr/sbin/ntpdate pool.ntp.org

Let’s start the synchronization daemon and write its startup to autoload:

systemctl start ntpd

systemctl enable ntpd

ln -s '/usr/lib/systemd/system/ntpd.service' '/etc/systemd/system/multi-user.target.wants/ntpd.service'

Do not use both time synchronization daemon – chrony and ntp at the same time.

  • Adding Repositories

To install various software, you need to connect the repositories in CentOS. The most popular is EPEL. Let’s add it to our CentOS server:

yum install epel-release

  • Store command history in bash_history

It will be useful to make some changes to the standard command history saving mechanism. It often helps out when you need to remember one of the previously entered commands. The default settings have some limitations that are inconvenient. Here is a list of them:

  1. By default, only the last 1000 commands are saved. If there are more, the older ones will be removed and replaced with new ones.
  2. There are no dates for the execution of commands, only their list in the order of execution.
  3. The file with the list of commands is updated after the session. If you use parallel sessions, some of the commands will be lost.
  4. Absolutely all commands are saved, although there is no point in keeping some of them.

The list of recently executed commands is stored in the user’s home directory in the .bash_history file (period in front of file). It can be opened by any editor. For a more convenient list output, you can enter the following command in the console:

history

You will see the numbered list. You can quickly find a specific command by filtering only the necessary lines, for example like this:

history | grep yum

Correct the listed disadvantages of the standard settings for storing command history in CentOS 7. To do this, edit the .bashrc file, which is located in the same directory as the history file. Add the following lines to it:

export HISTSIZE=10000
export HISTTIMEFORMAT="%h %d %H:%M:%S "
PROMPT_COMMAND='history -a'
export HISTIGNORE="ls:ll:history:w:htop"

The first parameter increases the file size to 10,000 lines. You can edit for more, although usually it’s enough. The second parameter indicates that it is necessary to save the date and time of the command. The third line forces system immediately save command. In the last line, we create a list of exceptions for those commands that are not required in history. I gave an example of the simplest list. You can add it at your discretion.

To apply the changes, you need to log out and reconnect or execute the command:

source ~/.bashrc

  • Automatic system update

To maintain server security at the proper level, it is necessary to regularly update it — both the kernel itself with the system utilities and the other packages. You can do it manually, but for more efficient work it is better to automate routine actions. It is not necessary to install updates automatically, but at least to check their appearance. I usually follow this strategy.

To automatically check for updates, the yum-cron utility will help us. Install it with yum from a standard repository.

yum install yum-cron

After installation, an automatic task is created to run the utility in /etc/cron.daily and /etc/cron.hourly. By default, the utility downloads the updates found, but does not apply them. Instead, an update notification is sent to the local root mailbox. The yum-cron configuration files are located at /etc/yum/yum-cron.conf and yum-cron-hourly.conf. They are well commented.

  • Disable flood messages in /var/log/messages

Create a separate rule for rsyslog, where we list all the message templates that will be cut. We will place this rule in a separate /etc/rsyslog.d/ignore-systemd-session-slice.conf file.

cd /etc/rsyslog.d && nano ignore-systemd-session-slice.conf

if $programname == "systemd" and ($msg contains "Starting Session" or $msg contains "Started Session" or $msg contains "Created slice" or $msg contains "Starting user-" or $msg contains "Starting User Slice of" or $msg contains "Removed session" or $msg contains "Removed slice User Slice of" or $msg contains "Stopping User Slice of") then stop

Save the file and restart rsyslog to apply the settings:

systemctl restart rsyslog

It is necessary to understand that in this case we disable the flood in the log file only on the local server.

  • Install utilities iftop, atop, htop, lsof

iftop shows real-time network interface load, install:

yum install iftop

Two interesting task managers, I use htop most often, but sometimes atop is useful:

yum -y install htop

yum -y install atop

To display information about which files are used by various processes, I advise you to install the lsof utility. It is likely to come in handy sooner or later when you diagnose server operation:

yum install lsof

I recommend to install some other useful programs, which are often necessary, but are absent in the minimal installation – wget, bzip2, traceroute, gdisk:

yum install wget bzip2 traceroute gdisk

  • Firewall configuration

To view the current rules, enter the command:

iptables -L -v -n

In the 7th CentOS version, a new tool called firewalld was developed for managing iptables and all management is done through it. I did not understand why they did it, and I cannot say whether it became more convenient with him or not. For me, it’s more convenient to use the same iptables experience. Migrating from server to server and from distribution to distribution, I simply edit the firewall settings script.

But for some reason, CentOS came up with firewalld, in Ubuntu there is ufw, but it is the same thing – these are utilities for configuring iptables, which is the same in all distributions. I used to manage iptables through a self-written script that I transfer from server to server and edit for specific needs. I will share this script. So first stop and disable firewalld:

systemctl stop firewalld

systemctl disable firewalld

rm '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'

rm '/etc/systemd/system/basic.target.wants/firewalld.service'

Install utilities for iptables:

yum -y install iptables-services

Enable autorun iptables:

systemctl enable iptables

Now we will create the /etc/iptables_rules.sh file

nano /etc/iptables_rules.sh

with the following content (!!!you should add your own WAN_IP in line 8!!!):

#!/bin/bash
#
# Variable declaration
export IPT="iptables"

# WAN interface
export WAN=eth0
export WAN_IP=192.168.100.100

# Clear all chains iptables
$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X

# Set default policies for traffic that does not match any of the rules.
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

# allow local traffic for loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# We allow outgoing connections of the server itself
$IPT -A OUTPUT -o $WAN -j ACCEPT

# The ESTABLISHED status indicates that this is not the first packet in the connection.
# Allow established and related connections
$IPT -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow new, established and related
$IPT -A OUTPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow forwar established and related
$IPT -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT

# Enable packet fragmentation. Required due to different MTU values
$IPT -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# Drop all packets that cannot be identified.
# 
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A FORWARD -m state --state INVALID -j DROP

# Result in linking system resources, so real
# data exchange becomes impossible, we drop it
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP

# Allow ICMP ping
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Open SSH port
$IPT -A INPUT -i $WAN -p tcp --dport 22 -j ACCEPT
# Open DNS port
#$IPT -A INPUT -i $WAN -p udp --dport 53 -j ACCEPT
# Open NTP port
#$IPT -A INPUT -i $WAN -p udp --dport 123 -j ACCEPT

# Logging
# All that is not allowed, but breaking will send in a chain undef

$IPT -N undef_in
$IPT -N undef_out
$IPT -N undef_fw
$IPT -A INPUT -j undef_in
$IPT -A OUTPUT -j undef_out
$IPT -A FORWARD -j undef_fw

# Logging all from undef

$IPT -A undef_in -j LOG --log-level info --log-prefix "-- IN -- DROP "
$IPT -A undef_in -j DROP
$IPT -A undef_out -j LOG --log-level info --log-prefix "-- OUT -- DROP "
$IPT -A undef_out -j DROP
$IPT -A undef_fw -j LOG --log-level info --log-prefix "-- FW -- DROP "
$IPT -A undef_fw -j DROP

# Save all rules above
/sbin/iptables-save  > /etc/sysconfig/iptables

In this config the logs of everything blocked will be written to the file /var/log/messages and there will be a lot of records. In normal operation, these lines need to be commented out, and used only during debugging.

Make the file with the rules executable and run:

chmod 0740 /etc/iptables_rules.sh

/etc/iptables_rules.sh

Check if the rules apply:

iptables -L -v -

  • System mail setup

It is convenient when mail addressed to the local root was sent via an external mail server to the selected mailbox. If this is not done, then it will be locally added to the /var/spool/mail/root file. There may be urgent, important and useful information that you would not want to miss. Let’s set up sending this mail to an external GMail mailbox:

yum install mailx cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain

Edit file /etc/postfix/main.cf and add correct server settings:

nano /etc/postfix/main.cf

## DEFAULT CONFIG BEGIN ######################
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
inet_interfaces = localhost
inet_protocols = all
unknown_local_recipient_reject_code = 550
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5

sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.10.1/samples
readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES
## DEFAULT CONFIG END ######################

# Server name by command hostname
myhostname = ChangeIT
# Here you need to leave only the domain, but in this case it is better to leave the full server name, so that the sender includes the full server name, so it is more convenient to parse the service messages
mydomain = ChangIT.local
mydestination = $myhostname
myorigin = $mydomain
# External SMTP server address
relayhost = smtp.gmail.com:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_generic_maps = hash:/etc/postfix/generic
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may

Edit file /etc/postfix/generic:

nano /etc/postfix/generic

and add correct string [email protected] at the end:

[email protected] [email protected]

Run command:

postmap /etc/postfix/generic

Create a file with user name and password for authorization:

nano /etc/postfix/sasl_passwd

smtp.gmail.com:587 [email protected]:YOURPASSWORD

Create a database file:

postmap /etc/postfix/sasl_passwd

Restart postfix:

systemctl restart postfix

Open standard root aliases located in /etc/aliases, add an external address to which mail addressed to root will be duplicated. To do this, edit the specified file, change the last line:

root: root,[email protected]

Renew aliases:

newaliases

Send test email to any address, it should come from [email protected]:

df -h | mail -s "Disk usage" [email protected]

Check email 🙂

Now all emails addressed to the local root, for example reports from cron, will be duplicated to an external mailbox, and sent via an external mail server with authorization. Your emails will be delivered normally, not getting into spam. Now it is convenient to use local sending in scripts, without setting additional parameters. Everything is already configured, you can use a simple local delivery (just end it to root).

If you need to debug mail settings, open mail log:

tail -n 10 /var/log/maillog

  • Reboot your system

shutdown -r now

Done! 🙂

Stay in the Loop

Get the weekly email from TechLifeTravel that makes reading the news actually enjoyable. Join our mailing list to stay in the loop to stay informed, for free.

LATEST ARTICLES