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:
- By default, only the last 1000 commands are saved. If there are more, the older ones will be removed and replaced with new ones.
- There are no dates for the execution of commands, only their list in the order of execution.
- The file with the list of commands is updated after the session. If you use parallel sessions, some of the commands will be lost.
- 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! 🙂