Restart graphical user interface in Linux

To help you better understand how to restart the GUI in Linux, here are some background information about how the GUI works in Linux:

If you are familiar with Windows, you know that the graphical Windows interface is tightly integrated into Windows. If you start a Windows computer, you automatically start the graphical user interface (GUI). First the Windows logo is twirling around, and then you are presented with the login screen. Only recent server versions of Windows have the option to be installed without graphical user interface. It is called "Server Core", and even in this mode Windows displays a very basic graphical surface that has only a terminal window. This desktopless installation option was a big deal for Windows, as the GUI is so tightly integrated into the operating system. Also there was no adequate command line interface to control and configure all Windows functions. Therefore Microsoft put great effort into making the PowerShell just as "powerful" as the graphical Windows interface.

Linux follows a completely different approach. By default if you start Linux, only the basic command line interface is started. You are presented with a text login screen, and after you login you see the command prompt of your shell in text mode.

The GUI in Linux is built on top of this minimal system. It is made up of a couple of processes that are launched by the root user and the user that is currently logged in. The starting point for the GUI is a program called the "display manager". The display manager starts the display server and presents you with a graphical login screen. After successful login it starts your desktop environment and your programs like web browser or email client.

So here is the chain of events that start your Linux desktop:

1display managerStarts x-server and displays graphical login screen. After successful login, the desktop environment will be startedGDM, LightDM, KDM, SDDM, etc.
2desktop environmentStarts its window manager and runs user programs.Gnome, Unity, KDE, etc.
3window managerDetermines the look-and-feel of your GUI and is responsible for any 2D / 3D effects.Mutter, Compiz, KWin, etc.

The display server is the actual component that is responsible for drawing pixels on the screen and communicates with graphics card, mouse and keyboard under a graphical environment. Therefore it needs to be present both before and after graphical login. Notice that this is not the case for the desktop environment nor the window manager. They are only started after successful login. As of today the by far most popular display server is the x-server (also known as X11 or server), although it will probably be replaced soon by other display servers like Wayland or Mir. When it comes to 2D- and 3D effects, this is performed by the window manager.

While there is a tight integration of desktop environment and window manager, you can use any display manager to start your favorite desktop environment. Usually there is an option on the login screen to tell the display manager which desktop environment to start after successful login. That might be useful if you accidentally installed and activated another login manager. Let's say you are running Gnome with the GDM display manager. After installing a KDE program, the dependencies of the program package pulled in the whole QT libraries along with the KDM display manager. The next time you login you are presented with the KDM display manager. This is actually no big deal. Just select the GNOME desktop environment from the options menu of KDM. After typing in username and password GNOME will be started.

Here is a list of desktop environments with their default display manager:

Desktop EnvironmentDefault Display Manager
KDEKDM (obsolete) / SDDM

How does Linux know which display manager to start if there are more than one installed?
The file /etc/X11/default-display-manager contains the full path of the default display manager to start.

Back to the original question: How do you restart the graphical user interface of Linux without rebooting the whole computer? The answer is easy: Just restart the display manager.

As we have seen earlier, the display manager is actually the starting point for the whole GUI. By shutting down the display manager, all graphical processes will be stopped too. Here is an example how to stop SDDM (run as root):

$ sudo killall sddm

SDDM will be restarted automatically. With other display managers you may have to start them manually as root.

There is also a way to bypass the display manager. If you are already logged in as a regular user in text mode, you can also start the desktop environment manually. E.g. for KDE you would type in:

$ /usr/bin/startkde

Always make sure to start the desktop environment as a non-privileged user, not as root. Otherwise all programs will be running with root privileges, which is something you should avoid at all costs. If you want to start individual programs with root privileges (e.g. WireShark), there are tools like "kdesudo" that launch a program under the root user.

Important things to note:

  • Unlike Windows there is a strict separation of the graphical user interface and the basic system in Linux.
  • The display manager is started by the root user. It is the entry point for the graphical user interface.
  • The desktop environment is run by a non-privileged user, typically the user that logs into the display manager.
  • In general you can use any display manager to start any desktop environment. You can use GDM to start KDE, or SDDM to start GNOME.
  • To restart the graphical user interface, you need to restart the display manager.

Pinentry not working over SSH with x11forwarding (Thunderbird with Enigmail)

Using Thunderbird with Enigmail over SSH sometimes does not work because you cannot input the passphrase for your private GPG key. Starting pinentry-qt / pinentry-gnome3 / pinentry-gtk2 does not work. Here is a workaround. You can cache the passphrase with gpg-agent before starting Thunderbird. Enigmail will then use the cached passphrase because it runs only gpg2 commands in a subshell in order to encrypt or sign messages.

Connect to the server using x11forwarding:

$ ssh -Y server

Note your DISPLAY environment variable:

$ echo $DISPLAY

Unset / delete the DISPLAY environment variable:


Export GPG_TTY environment variable for gpg:

export GPG_TTY=$(tty)

Make sure that gpg-agent is running:

$ ps aux | grep gpg-agent
user 2058 0.0 0.0 168068 2228 ? Ss Nov10 0:07 gpg-agent --homedir /home/user/.gnupg --use-standard-socket --daemon

Insert the passphrase for your GPG key in gpg-agent by signing a dummy message. Make sure that you enter your passphrase in the pinentry tui not the gpg command prompt.

$ echo test | gpg2 --use-agent -s

The passphrase you are about to enter should be cached by gpg-agent. The cache lifetime is controlled by settings in ~/.gnupg/gpg-agent.conf . Now set the DISPLAY environment variable again to run Thunderbird. Use the value from previous command.

export DISPLAY=localhost:10.0

Start Thunderbird. You should now be able to sign and encrypt email messages with Enigmail without having to enter your gpg passphrase again because it is already cached by gpg-agent.

thunderbird &



PAM authentication per application (Debian 8 Jessie)

PAM is the default authentication mechanism in Linux. It is very flexible and powerful, and even allows you to configure different authentication options for each application. In this example we will use the PAM module "pam_listfile" which is already included in the standard package "libpam-modules".

The application name has to match the name of the file under /etc/pam.d . So for example for application "abc" you have the following PAM configuration file /etc/pam.d/abc :

auth required onerr=fail item=group sense=allow file=/etc/group.allow
@include common-auth
@include common-account
@include common-password
@include common-session

The first line only authenticates users that are member of any group listed in /etc/group.allow. The contents of /etc/group.allow may only contain a single line and looks like this:


This will allow only members of the group "abc_group" to login to application "abc". After adding the new configuration files, make sure to always test your PAM settings with pamtester:

# id bob
uid=1003(bob) gid=1003(bob) groups=1003(bob)
# pamtester abc bob authenticate
pamtester: Authentication failure
# usermod -aG abc_group bobpamtester abc bob authenticate
pamtester: successfully authenticated

First the user "bob" is not member of the group "abc_group". pamtester fails to authenticate the user even if you provide the right password. Then after adding "bob" to the group "abc_group" authentication succeeds.



Connect to OpenLDAP server with Perl

This little code example in Perl shows how to connect to an OpenLDAP server using the ldaps protocol. It tries several servers and uses the first one it can connect to.

use strict;

use Net::LDAP;
use Net::LDAP::Extension::WhoAmI;
# LDAPS is basically the same as the LDAP-Module using ldaps:// URIs
#use Net::LDAPS;

my $userName = 'USERNAME';
my $passWord = 'PASSWORD';

my @Servers = ("server1", "server2", "server3");
my $ldap = undef;

# Code = 34, Name: LDAP_INVALID_DN_SYNTAX (dn is not a full path)
# Code = 48, Name: LDAP_INAPPROPRIATE_AUTH (empty dn or password)
# Code = 49, Name: LDAP_INVALID_CREDENTIALS (wrong dn or password)
sub lErr {
  my $mesg = shift;
  printf STDERR "Error: %s\n", $mesg->error();
  printf STDERR "Error Code: %s\n", $mesg->code();
  printf STDERR "Error Name: %s\n", $mesg->error_name();
  printf STDERR "Error Text: %s", $mesg->error_text();
  printf STDERR "Error Description: %s\n", $mesg->error_desc();
  printf STDERR "Server Error: %s\n", $mesg->server_error();

foreach my $server (@Servers) {
  $ldap = Net::LDAP->new("ldaps://$server:636",
  verify => 'require',
  inet4 => 1,
  timeout => 3,
  cafile => '/etc/ssl/certs/ldap_slapd_cacert.pem' );

  if($ldap) {
    print "Ok connecting to $server\n";
  else {
    print "Error connecting to $server: $@\n";

if($ldap) {
  print "Now connected to " . $ldap->host() . "\n";
else {
  exit -1;
my $mesg = $ldap->bind("uid=$userName,ou=People,dc=example,dc=com",
  password => "$passWord");
if($mesg->is_error()) {
  exit $mesg->code;

# Using $ldap->bind again after $ldap->unbind doesn't work

There is also an option to connect to an array of servers with only one function call. It basically does the same thing: Looping through a list of servers and use the first successful connection. But you have to be careful, there is a known bug if "verify" is set to "optional" (s.


Certificate Authorities (CA) in Google Chrome / Chromium and Firefox on Linux

Firefox ships with its own set of root CAs ("Builtin Object Token" as the Security Device in advanced preference settings). Here is the list of all root CAs included in Firefox along with their fingerprints:

Builtin root CAs are hardcoded in /usr/lib/firefox/ . You can see a list of all CAs in Firefox preferences (advanced settings).

CAs marked as "Software Security Device" are usually intermediate certificates that are downloaded from websites and stored locally. These CAs that are not builtin are either stored on a PKCS#11 compatible smartcard attached to your PC/laptop or saved to your home directory:
certutil -d $HOME/.mozilla/firefox/xxx.default -L

Chromium / Google Chrome does not ship with its own CA list but uses the CAs from the underlying operating system:

In Ubuntu 16.04 these CAs are hardcoded in /usr/lib/x86_64-linux-gnu/nss/ which is part of the package "libnss3". You should therefore update this package as soon as there is an update available to keep your builtin CA list up-to-date.

CAs that are not builtin and that you installed manually are stored in your home directory:
certutil -d sql:$HOME/.pki/nssdb -L

Important things to note:

  • The security of SSL encrypted websites (https://...) depends on the root CA which is used to sign the website certificate. These CAs are stored locally on your device in different locations based on the browser you are using.
  • There are 2 kinds of CAs:
    1. Builtin CAs that ship with your browser or linux installation. They are stored in shared object files. There is probably no easy way to edit this list unless you change the source files and recompile the package. Nevertheless in both browsers you can remove all trust from a builtin certificate which is basically the same as deleting it.
    2. Manually added CAs are stored in your home directory. You can easily edit that list within the settings of the browser or on the command line.
  • Both Firefox and Chromium / Google Chrome use NSS certificate databases to store manually added CAs that are not builtin. But they use different directories. Maybe you could use symbolic links to point both directories to the same database. That way both browsers would be using the same manual CA list.Currently Firefox uses by default the legacy dbm database version (cert8.db, key3.db) and Chromium / Google Chrome uses by default the new SQLite database version (cert9.db, key4.db). There seems to be an environment variable NSS_DEFAULT_DB_TYPE that makes Firefox use the new SQLite database version as well (s.
  • Neither Firefox nor Chromium / Google Chrome are using CAs from the package "ca-certificates".

How to download Twitter videos (animated GIFs)

There are 2 types of Twitter videos: animated GIFs and real videos. This post is about animated GIFs. They have the text "GIF" printed on them when they are not playing.

To download animated GIFs there doesn't seem to be an easy way in Google Chrome unless you use an extension.

In Firefox:

  • open the tweet
  • right click on the video
  • choose "This Frame" -> "Page Info"
  • Under "Media" choose the mp4-file and click "Save As..."



Password encryption in OpenLDAP

Passwords in OpenLDAP are SSHA encrypted by default (salted SHA1).

Changing it to SHA512:

olcPasswordHash: {CRYPT},{SSHA}
olcPasswordCryptSaltFormat: "$6$%.16s"

This will still accept already existing passwords that are SSHA encrypted. New passwords will be SHA512 encrypted.

For this to work, the GNU C library has to support SHA512:
- /etc/login.defs: ENCRYPT_METHOD SHA512
- man pam_unix (should include sha512)

SHA512 passwords for LDAP can be generated with slappasswd:

slappasswd -c '$6$%.16s'



Secure download of RHEL ISO installation images

You will probably download the RHEL ISO image from within the Red Hat Customer Portal and therefore use an encrypted HTTPS connection (download URL is The SHA-256 checksums for the ISO images are on the download page.

Red Hat also provides a page with all GPG keys they use for signing their software packages. In Customer Portal, go to "Security" -> "Product Signing (GPG) Keys)" (

There are download links for the public keys ( The keys are also available on the keyserver . So you can use the following command to import the main Red Hat key into your GPG keyring:

# gpg --recv-keys fd431d51
# gpg --fingerprint -k fd431d51

Compare the fingerprint of the Red Hat public key with the fingerprint on the Customer Portal website. You cannot use the GPG key for verifying the ISO files, but it is useful for e.g. verifying RPM package updates that you can download directly from Red Hat websites and that are not installed the usual way via an official yum repository.



iSCSI connection states in Open-iSCSI

This is the iSCSI connection state if the underlying network interface changes from "UP BROADCAST RUNNING MULTICAST" to "UP BROADCAST MULTICAST".

Log entries showing that the network interface has no longer the state "RUNNING":

Jul 3 14:17:31 host kernel: [974138.571169] bnx2 0000:08:05.0 eth2: NIC Copper Link is Down
Jul 3 23:05:05 host kernel: [1005760.957474] sd 10:0:0:0: rejecting I/O to offline device
... previous message repeats many times ...

Checking iSCSI connection state:

# iscsiadm -m session -P1
iSCSI Connection State: TRANSPORT WAIT
iSCSI Session State: FREE
Internal iscsid Session State: REOPEN

Log entry once the network interface state is back to "RUNNING":

Jul 4 06:56:31 host kernel: [1034019.191222] bnx2 0000:08:05.0 eth2: NIC Copper Link is Up, 1000 Mbps full duplex

Checking iSCSI connection state again:

# iscsiadm -m session -P1
iSCSI Connection State: LOGGED IN
iSCSI Session State: LOGGED_IN
Internal iscsid Session State: NO CHANGE

The output of "iscsiadm -m session -P1" can be used for monitoring the iSCSI connection e.g. in a simple Nagios or Icinga Perl script.


HSTS with Apache and Chrome

  • HSTS (HTTP Strict Transport Security) prevents your browser from visiting a website over an unencrypted "http://..." url. Instead you have to use the encrypted "https://..." url, otherwise your browser refuses to load the website.
    Either the webserver of the website you are visiting suggests the use of HSTS to your browser by sending an additional HTTP header, or you manually configure a certain website yourself in your browser.
  • Apache requires the module mod_headers to make the necessary changes to the HTTP headers.
  • Add this to your Apache vhost configuration:
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    For a description of all options see RFC:
    The "preload" option is not part of the RFC. It just signals that you want your site to be added to the browser builtin list of HSTS sites (see below). If you do not plan to get listed, you may omit this option.
  • Visit the site at least once using HTTPS in your Chrome browser ("trust on first use"). The HSTS configuration of the site (provided by the Apache STS header) will be added to an internal Chrome list. HSTS really depends on this internal browser list. Webservers only send an additional HTTP header that webbrowsers may or may not honor.
  • Add, delete or check websites in your Chrome browser:
    Changes take place immediately without having to restart Chrome.
    You can add sites even if they don't send the special STS header.
    You can combine those entries with PKP (Public Key Pinning) by providing fingerprints for all accepted public keys of a website.
  • Chrome ships with a builtin list of sites that require HSTS. If you run a large public website, you might want to get included in that list:
    These builtin sites get listed as "static_..." in your internal Chrome browser list. All other sites (added manually or by honoring the STS header) get listed as "dynamic_...".
  • You cannot delete site entries from the builtin list (assuming that you use the official Chrome browser and that it has not been manipulated).
  • This is the message you get in Chrome when HSTS is violated on a website (in this case the certificate of has expired and therefore Chrome refuses to establish the HTTPS connection):
You cannot visit right now because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later.

Important things to note:

  • Even for HSTS enabled sites, you may still be able to type in the "http://..." URL in the browser address bar. Chrome automatically recognizes the URL and redirects you to the corresponding "https://..." URL.
    This is different from traditional HTTP redirects, because no unencrypted traffic is sent over the network. The redirection already takes place in the browser.
    The downside of this behaviour is that it makes it hard for people to identify if a website is using HSTS or simply redirects all traffic from HTTP/port 80 to HTTPS/port 443 (HTTP status codes 3xx).
  • Many browser plugins now offer the same functionality (redirect some or all website addresses to HTTPS URLs).
  • Maybe some day HTTPS URLs become the default in webbrowsers. If you type a URL in the address bar, or select a URL without the leading "http(s)://", the browser first redirects you automatically to the HTTPS URL. Only if there is no connection possible, you will receive a warning message and get redirected to the HTTP URL. Let's make HTTPS the default in browsers and accept HTTP only for a small number of exceptions.
    No green lock icon for SSL encrypted websites, just red unlock icons for unencrypted websites.