Monday, March 16, 2015

RHEL7: How to get started with Systemd.

Presentation

As the Systemd now replaces SysVinit, it is time to get familiar with it and learn new commands.
Systemd is quicker because it uses fewer scripts and tries to run more tasks in parallel (Systemdcalls them units).
The Systemd configuration is stored in the /etc/systemd directory.

Boot process

Systemd primary task is to manage the boot process and provides informations about it.
To get the boot process duration, type:
# systemd-analyze
Startup finished in 422ms (kernel) + 2.722s (initrd) + 9.674s (userspace) = 12.820s
To get the time spent by each task during the boot process, type:
# systemd-analyze blame
7.029s network.service
2.241s plymouth-start.service
1.293s kdump.service
1.156s plymouth-quit-wait.service
1.048s firewalld.service
632ms postfix.service
621ms tuned.service
460ms iprupdate.service
446ms iprinit.service
344ms accounts-daemon.service
...
7ms systemd-update-utmp-runlevel.service
5ms systemd-random-seed.service
5ms sys-kernel-config.mount
To get the list of the critical chain of tasks during the boot process (any additional delay of these tasks would cause an increase of the overall boot time), type:
# systemd-analyze critical-chain
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

multi-user.target @6.167s
└─mariadb.service @2.661s +3.505s
  └─network.target @2.649s
    └─network.service @2.168s +478ms
      └─NetworkManager.service @1.993s +174ms
        └─firewalld.service @826ms +1.162s
          └─basic.target @822ms
            └─sockets.target @821ms
              └─dbus.socket @820ms
                └─sysinit.target @813ms
                  └─systemd-update-utmp.service @806ms +6ms
                    └─auditd.service @747ms +58ms
                      └─local-fs.target @742ms
                        └─boot.mount @709ms +32ms
                          └─systemd-fsck@dev-disk-by\x2duuid-497a43ab\x2d33b0\x2
                            └─dev-disk-by\x2duuid-497a43ab\x2d33b0\x2d4153\x2d9f
To get the list of the critical chain for a particular service (here firewalld), type:
# systemd-analyze critical-chain firewalld.service
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

firewalld.service +1.162s
└─basic.target @822ms
  └─sockets.target @821ms
    └─dbus.socket @820ms
      └─sysinit.target @813ms
        └─systemd-update-utmp.service @806ms +6ms
          └─auditd.service @747ms +58ms
            └─local-fs.target @742ms
              └─boot.mount @709ms +32ms
                └─systemd-fsck@dev-disk-by\x2duuid-497a43ab\x2d33b0\x2d4153\x2d9
                  └─dev-disk-by\x2duuid-497a43ab\x2d33b0\x2d4153\x2d9f8d\x2d7788
To get the list of the critical chain for a particular target (here basic.target), type:
# systemd-analyze critical-chain basic.target | grep target
basic.target @822ms
└─sockets.target @821ms
    └─sysinit.target @813ms
          └─local-fs.target @742ms
To get the list of the dependencies, type:
# systemctl list-dependencies
default.target
├─abrt-ccpp.service
├─abrt-oops.service
...
├─tuned.service
├─basic.target
│ ├─firewalld.service
│ ├─microcode.service
...
├─getty.target
│ ├─getty@tty1.service
│ └─serial-getty@ttyS0.service
└─remote-fs.target
To get the list of dependencies for a particular service (here sshd), type:
# systemctl list-dependencies sshd.service
To get the list of dependencies for a particular target (here graphical.target), type:
# systemctl list-dependencies graphical.target | grep target
graphical.target
└─multi-user.target
  ├─basic.target
  │ ├─paths.target
  │ ├─slices.target
  │ ├─sockets.target
  │ ├─sysinit.target
  │ │ ├─cryptsetup.target
  │ │ ├─local-fs.target
  │ │ └─swap.target
  │ └─timers.target
  ├─getty.target
  └─remote-fs.target
Journal analysis
In addition, Systemd handles the system event log, a syslog daemon is not mandatory any more.
To get the content of the Systemd journal, type:
# journalctl
To get all the events related to the crond process in the journal, type:
# journalctl /sbin/crond
Note: You can replace /sbin/crond by `which crond`.
To get all the events since the last boot, type:
# journalctl -b
To get all the events that appeared today in the journal, type:
# journalctl --since=today
To get all the events with a syslog priority of err, type:
# journalctl -p err
To get the 10 last events and wait for any new one (like “tail -f /var/log/messages“), type:
# journalctl -f
Control groups
Systemd organizes tasks in control groups. For example, all the processes started by an apache webserver will be in the same control group, CGI scripts included.
To get the full hierarchy of control groups, type:
# systemd-cgls
├─user.slice
│ └─user-1000.slice
│ └─session-1.scope
│ ├─2889 gdm-session-worker [pam/gdm-password]
│ ├─2899 /usr/bin/gnome-keyring-daemon --daemonize --login
│ ├─2901 gnome-session --session gnome-classic
. .
└─iprupdate.service
└─785 /sbin/iprupdate --daemon
To get the list of control group ordered by CPU, memory and disk I/O load, type:
# systemd-cgtop
Path Tasks %CPU Memory Input/s Output/s
/ 213 3.9 829.7M - -
/system.slice 1 - - - -
/system.slice/ModemManager.service 1 - - - -
To kill all the processes associated with an apache server (CGI scripts included), type:
# systemctl kill httpd
To put resource limits on a service (here 500 CPUShares), type:
# systemctl set-property httpd.service CPUShares=500
Note1: The change is written into the service unit file. Use the –runtime option to avoid this behavior.
Note2: By default, each service owns 1024 CPUShares. Nothing prevents you from giving a value smaller or bigger.
To get the current CPUShares service value, type:
# systemctl show -p CPUShares httpd.service
Service management
Systemd deals with all the aspects of the service management. The systemctl command replaces the chkconfig and the service commands. The old commands are now a link to the systemctl command.
To activate the NTP service at boot, type:
# systemctl enable ntpd
Note1: You should specify ntpd.service but by default the .service suffix will be added.
Note2: If you specify a path, the .mount suffix will be added.
Note3: If you mention a device, the .device suffix will be added.
To deactivate it, start it, stop it, restart it, reload it, type:
# systemctl disable ntpd
# systemctl start ntpd
# systemctl stop ntpd
# systemctl restart ntpd
# systemctl reload ntpd
Note: It is also possible to mask and unmask a service. Masking a service prevents it from being started manually or by another service.
To know if the NTP service is activated at boot, type:
# systemctl is-enabled ntpd
enabled
To know if the NTP service is running, type:
# systemctl is-active ntpd
inactive
To get the status of the NTP service, type:
# systemctl status ntpd
ntpd.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)
If you change a service configuration, you will need to reload it:
# systemctl daemon-reload
To get the list of all the units (services, mount points, devices) with their status and description, type:
# systemctl
To get a more readable list, type:
# systemctl list-unit-files
To get the list of services that failed at boot, type:
# systemctl --failed
To get the status of a service (here httpd) on a remote server (here rhel7.example.com), type:
# systemctl -H root@rhel7.example.com status httpd.service
To get all the configuration details about a service (here httpd), type:
# systemctl show httpd
Id=httpd.service
Names=httpd.service
Requires=basic.target
Wants=system.slice
Conflicts=shutdown.target
Before=shutdown.target
After=network.target remote-fs.target nss-lookup.target systemd-journald.socket
Description=The Apache HTTP Server
LoadState=loaded
ActiveState=inactive
...
ExecMainPID=0
ExecMainCode=0
ExecMainStatus=0
Targets/Run levels
Systemd also deals with targets. A target is a grouping mechanism allowing several services to start at the same time. The list of services associated with a particular target is stored in a directory named with the target name and the suffix “.wants”. In some way, targets replace run levels but they are more general.
To move to maintenance mode, type:
# systemctl rescue
Note: There is also an emergency target only available when set up in the kernel boot line (systemd.unit=emergency.target) and for critical situations.
To move to the level 3 (equivalent to the previous level 3), type:
# systemctl isolate runlevel3.target
Or:
# systemctl isolate multi-user.target
To move to the graphical level (equivalent to the previous level 5), type:
# systemctl isolate graphical.target
To set the default run level to non-graphical mode, type:
# systemctl set-default multi-user.target
To set the default run level to graphical mode, type:
# systemctl set-default graphical.target
To get the current default run level, type:
# systemctl get-default
graphical.target
To stop a server, type:
# systemctl poweroff
Note: You can still use the poweroff command, a link to the systemctl command has been created (the same thing is true for the halt and reboot commands).
To reboot a server, suspend it or put it into hibernation, type:
# systemctl reboot
# systemctl suspend
# systemctl hibernate

Linux standardization

Systemd‘s authors have decided to help Linux standardization among distributions. ThroughSystemd, changes happen in the localization of some configuration files.

Miscellaneous

To get the server hostnames, type:
# hostnamectl
Static hostname: rhel7.example.com
Icon name: computer-laptop
Chassis: laptop
Machine ID: bcdc71f1943f4d859aa37e54a422938d
Boot ID: f84556924b4e4bbf9c4a82fef4ac26d0
Operating System: Red Hat Enterprise Linux Everything 7.0 (Maipo)
CPE OS Name: cpe:/o:redhat:enterprise_linux:7.0:beta:everything
Kernel: Linux 3.10.0-54.0.1.el7.x86_64
Architecture: x86_64
Note: There are three kinds of hostnames: static, pretty, and transient.
“The static host name is the traditional hostname, which can be chosen by the user, and is stored in the /etc/hostname file. The “transient” hostname is a dynamic host name maintained by the kernel. It is initialized to the static host name by default, whose value defaults to “localhost”. It can be changed by DHCP or mDNS at runtime. The pretty hostname is a free-form UTF8 host name for presentation to the user.” Source: RHEL 7 Networking Guide.
To assign the rhel7 hostname permanently to the server, type:
# hostnamectl set-hostname rhel7
Note: With this syntax all three hostnames (static, pretty, and transient) take the rhel7 value at the same time. However, it is possible to set the three hostnames separately by using the –pretty–static, and –transient options.
To get the current locale, virtual console keymap and X11 layout, type:
# localectl
System Locale: LANG=en_US.UTF-8
VC Keymap: en_US
X11 Layout: en_US
To assign the en_GB.utf8 value to the locale, type:
# localectl set-locale LANG=en_GB.utf8
To assign the en_GB value to the virtual console keymap, type:
# localectl set-keymap en_GB
To assign the en_GB value to the X11 layout, type:
# localectl set-x11-keymap en_GB
To get the current date and time, type:
# timedatectl
Local time: Fri 2014-01-24 22:34:05 CET
Universal time: Fri 2014-01-24 21:34:05 UTC
RTC time: Fri 2014-01-24 21:34:05
Timezone: Europe/Madrid (CET, +0100)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: no
Last DST change: DST ended at
Sun 2013-10-27 02:59:59 CEST
Sun 2013-10-27 02:00:00 CET
Next DST change: DST begins (the clock jumps one hour forward) at
Sun 2014-03-30 01:59:59 CET
Sun 2014-03-30 03:00:00 CEST
To set the current date, type:
# timedatectl set-time YYYY-MM-DD
To set the current time, type:
# timedatectl set-time HH:MM:SS
To get the list of time zones, type:
# timedatectl list-timezones
To change the time zone to America/New_York, type:
# timedatectl set-timezone America/New_York
To get the users’ list, type:
# loginctl list-users
UID USER
42 gdm
1000 tom
0 root
To get the list of all current user sessions, type:
# loginctl list-sessions
SESSION UID USER SEAT
1 1000 tom seat0

1 sessions listed.
To get the properties of the user tom, type:
# loginctl show-user tom
UID=1000
GID=1000
Name=tom
Timestamp=Fri 2014-01-24 21:53:43 CET
TimestampMonotonic=160754102
RuntimePath=/run/user/1000
Slice=user-1000.slice
Display=1
State=active
Sessions=1
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0

RHEL7: How to get started with Firewalld

Presentation:-

Firewalld is the new userland interface in RHEL 7. It replaces the iptables interface and connects to the netfilter kernel code. It mainly improves the security rules management by allowing configuration changes without stopping the current connections.
To know if Firewalld is running, type:
# systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Tue 2014-06-17 11:14:49 CEST; 5 days ago
   ...
or alternatively:
# firewall-cmd --state
running
Note: If Firewalld is not running, the command displays not running.
If you’ve got several network interfaces in IPv4, you will have to activate ip forwarding.
To do that, paste the following line in the /etc/sysctl.conf file:
net.ipv4.ip_forward=1
Then, activate the configuration:
# sysctl -p
Although Firewalld is the RHEL 7 way to deal with firewalls and provides many improvements,iptables can still be used (but both shouldn’t run at the same time).

Zone management

Also, a new concept of zone appears: all network interfaces can be located in the same default zone or divided into different ones according to the levels of trust defined. In the latter case, this allows to restrict traffic based on origin zone.
Note: Without any configuration, everything is done by default in the public zone. If you’ve got more than one network interface or use sources (see Source management section below), you will be able to restrict traffic between zones.
To get the default zone, type:
# firewall-cmd --get-default-zone
public
To get the list of zones where you’ve got network interfaces or sources assigned to, type:
# firewall-cmd --get-active-zones
public
interfaces: eth0
To get the list of all the available zones, type:
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
To change the default zone to home permanently, type:
# firewall-cmd --set-default-zone=home
success
Network interfaces can be assigned to a zone in a temporary (until the next reboot or reload) orpermanent way.
To assign the eth0 network interface temporary to the internal zone, type:
# firewall-cmd --zone=internal --change-interface=eth0
success
To assign the eth0 network interface permanently to the internal zone (a file called internal.xmlis created in the /etc/firewalld/zones directory), type:
# firewall-cmd --permanent --zone=internal --change-interface=eth0
success
To know which zone is associated with the eth0 interface, type:
# firewall-cmd --get-zone-of-interface=eth0
internal
To get all the details about the public zone, type:
# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: eth0
  sources: 
  services: dhcpv6-client ssh
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules: 
Note: The –list-all option only displays the permanent settings.
It is also possible to create new zones. To create a new zone (here test), type:
# firewall-cmd --permanent --new-zone=test
# firewall-cmd --reload

Source management

A zone can be bound to a network interface (see above) and/or to a network addressing (called here a source).
Any network packet entering in the network stack is associated with a zone.
The association is done according to the following pattern:
– is the packet coming from a source already bound to a zone? (if yes, it is associated with this zone),
– if not, is the packet coming from a network interface already bound to a zone? (if yes, it is associated with this zone),
– if not, the packet is associated with the default zone.
This way, multiple zones can be defined even on a server with only one network interface!
To add a source (here 192.168.2.0/24) to a zone (here trusted) permanently, type:
# firewall-cmd --permanent --zone=trusted --add-source=192.168.2.0/24
success
Note1: Use the –remove-source option to delete a previous assigned source.
Note2: Use the –change-source option to move the source to the new specified zone.
To get the list of the sources bound to a zone (here trusted) permanently, type:
# firewall-cmd --permanent --zone=trusted --list-sources
192.168.2.0/24
To keep track of your configuration (active zones are zones, that have a binding to an interface or source), type:
# firewall-cmd --get-active-zones
public
  interfaces: eth0
trusted
  sources: 192.168.2.0/24

Service management

After assigning each network interface to a zone, it is now possible to add services to each zone.
To allow the http service permanently in the internal zone, type:
# firewall-cmd --permanent --zone=internal --add-service=http
success
# firewall-cmd --reload
Note1: Type –remove-service=http to deny the http service.
Note2: The firewall-cmd –reload command is necessary to activate the change. Contrary to the–complete-reload option, current connections are not stopped.
To get the list of services in the default zone, type:
# firewall-cmd --list-services
dhcpv6-client ssh
Note: To get the list of the services in a particular zone, add the –zone= option.

Service firewall configuration

With the Firewalld package, the firewall configuration of the main services (ftp, httpd, etc) comes in the /usr/lib/firewalld/services directory. But it is still possible to add new ones in the/etc/firewalld/services directory. Also, if files exist at both locations for the same service, the file in the /etc/firewalld/services directory takes precedence.
For example, it is the case of the HAProxy service. There is no firewall configuration associated.
Create the /etc/firewalld/services/haproxy.xml and paste the following lines:
<?xml version="1.0" encoding="utf-8"?>
<service>
 <short>HAProxy</short>
 <description>HAProxy load-balancer</description>
 <port protocol="tcp" port="80"/>
</service>
Assign the correct SELinux context and file permissions to the haproxy.xml file:
# cd /etc/firewalld/services
# restorecon haproxy.xml
# chmod 640 haproxy.xml
Add the HAProxy service to the default zone permanently and reload the firewall configuration:
# firewall-cmd --permanent --add-service=haproxy
# firewall-cmd --reload

Port management

Port management follows the same model as service management.
To allow the 443/tcp port temporary in the internal zone, type:
# firewall-cmd --zone=internal --add-port=443/tcp
success
# firewall-cmd --reload
Note: type –remove-port=443/tcp to deny the port.
To get the list of ports open in the internal zone, type:
# firewall-cmd --zone=internal --list-ports
443/tcp

Masquerading

If your firewall is your network gateway and you don’t want everybody to know your internal addresses, you can set up two zones, one called internal, the other external, and configuremasquerading on the external zone. This way, all packets will get your firewall ip address as source address.
To set up masquerading on the external zone, type:
# firewall-cmd --zone=external --add-masquerade
Note1: To remove masquerading, use the –remove-masquerade option.
Note2: To know if masquerading is active in a zone, use the –query-masquerade option.

Port forwarding

In addition to the masquerading, you can want to use port forwarding.
If you want all packets intended for port 22 to be now forwarded to port 3753, type:
# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753
Note1: To remove port forwarding, use the –remove-forward-port option.
Note2: To know if port forwarding is active in a zone, use the –query-forward-port option.
Also, if you want to define the destination ip address, type:
# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753:toaddr=10.0.0.1

Direct rules

It is still possible to set specific rules by using the direct mode (here to open the tcp port 9000) that by-passes the Firewalld interface:
# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT
success
# firewall-cmd --reload
Note: This last example has been borrowed from Khosro Taraghi’s blog.
To display all the direct rules added, type:
# firewall-cmd --direct --get-all-rules