Skip to main content

Ubuntu

Introduction on Communication Server with XMPP in Ubuntu

Extensible Messaging and Presence Protocol (XMPP) is a communication protocol that provides near-real-time message passing between two or more entities. XMPP is based on XML and transfers data in predefined formats that are known to server as well as client systems. Being an XML-based protocol, you can easily extend XMPP to suit your requirements. It also provides various standard extensions to extend the base functionality of the XMPP server.

In this article, we will learn how to set up our own XMPP server. The main focus will be on implementing a simple chat application. In later recipes, we will also look at a Node.js and socket-based alternative to implementing the messaging server.

We will be working with a popular XMPP server Ejabberd. It is a well-known XMPP implementation supported by ProcessOne. Ejabberd is based on Erlang, a functional programming language specifically designed for soft real-time communication.

Adding group members in Ubuntu

Once you have groups in place, you can add existing users as well as new users to that group. All access rights and permissions assigned to the group will be automatically available to all the members of the group.

Getting ready

You will need super user or root privileges to add a group member to the Ubuntu server.

How to do it…

Follow these steps to add group members:

  1. Here, you can use adduser command with two non-option arguments:
    $ sudo adduser john guest
  2. Enter your password to complete addgroup with root privileges.

How it works…

As mentioned previously, you can use the adduser command to add an existing user to an existing group. Here, we have passed two non-option arguments:

  • john: This is the name of the user to be added to the group
  • guest: This is the name of the group

There's more…

Alternatively, you can use the command usermod to modify the group assigned to the user:

$ sudo usermod -g

To add a user to multiple groups, use the following command:

$ sudo usermod -a -G ,,

This will add to , , and . Without flag –a, any previously assigned groups will be replaced with new groups.

Setting resource limits on LXD containers in Ubuntu

In this recipe, we will learn to set resource limits on containers. LXD uses the cgroups feature in the Linux kernel to manage resource allocation and limits. Limits can be applied to a single container through configuration or set in a profile, applying limits to a group of containers at once. Limits can be dynamically updated even when the container is running.

How to do it…

We will create a new profile and configure various resource limits in it. Once the profile is ready, we can use it with any number of containers. Follow these steps:

Create a new profile with the following command:

$ lxc profile create cookbook

Profile cookbook created

Next, edit the profile with lxc profile edit. This will open a text editor with a default profile structure in YML format:

$ lxc profile edit cookbook

Add the following details to the profile. Feel free to select any parameters and change their values as required:

name: cookbook

config:

boot.autostart: "true"

limits.cpu: "1"

limits.cpu.priority: "10"

limits.disk.priority: "10"

limits.memory: 128MB

limits.processes: "100"

description: A profile for Ubuntu Cookbook Containers

devices:

eth0:

nictype: bridged

parent: lxdbr0

type: nic

Save your changes to the profile and exit the text editor.

Optionally, you can check the created profile, as follows:

$ lxc profile show cookbook

Now, our profile is ready and can be used with a container to set limits. Create a new container using our profile:

$ lxc launch ubuntu:xenial c4 -p cookbook

This should create and start a new container with the cookbook profile applied to it. You can check the profile in use with the lxc info command:

$ lxc info c4

Check the memory limits applied to container c4:

$ lxc exec c4 -- free -m

Profiles can be updated even when they are in use. All containers using that profile will be updated with the respective changes, or return a failure message. Update your profile as follows:

$ lxc profile set cookbook limits.memory 256MB

How it works…

LXD provides multiple options to set resource limits on containers. You can apply limits using profiles or configure containers separately with the lxc config command. The advantage of creating profiles is that you can have various parameters defined in one central place, and all those parameters can be applied to multiple containers at once. A container can have multiple profiles applied and also have configuration parameters explicitly set. The overlapping parameters will take a value from the last applied profile. Also the parameters that are set explicitly using lxc config will override any values set by profiles.

The LXD installation ships with two preconfigured profiles. One is default, which is applied to all containers that do not receive any other profile. This contains a network device for a container. The other profile, named docker, configures the required kernel modules to run Docker inside the container. You can view the parameters of any profile with the lxc profile show profile_name command.

In the previous example, we used the edit option to edit the profile and set multiple parameters at once. You can also set each parameter separately or update the profile with the set option:

$ lxc profile set cookbook limits.memory 256MB

Similarly, use the get option to read any single parameter from a profile:

$ lxc profile get cookbook limits.memory

Profiles can also be applied to a running container with lxc profile apply. The following command will apply two profiles, default and cookbook, to an existing container, c6:

$ lxc profile apply c6 default,cookbook

Updating the profiles will update the configuration for all container using that profile. To modify a single container, you can use lxc config set or pass the parameters directly to a new container using the -c flag:

$ lxc launch ubuntu:xenial c7 -c limits.memory=64MB

Similar to lxc profile, you can use the edit option with lxc config to modify multiple parameters at once. The same command can also be used to configure or read server parameters. When used without any container name, the command applies to the LXD daemon.

There's more…

The lxc profile and lxc config commands can also be used to attach local devices to containers. Both commands provide the option to work with various devices, which include network, disk IO, and so on. The simplest example will be to pass a local directory to a container, as follows:

$ lxc config device add c1 share disk \

source=/home/ubuntu path=home/ubuntu/shared

See also

Read more about setting resource limits at https://www.stgraber.org/2016/03/26/lxd-2-0-resource-control-412

For more details about LXC configuration, check the help menu for the lxc profile and lxc config commands, as follows:

$ lxc config --help

Installing Network File System in Ubuntu

Network File System (NFS) is a distributed filesystem protocol that allows clients to access remote files and directories as if they are available on the local system. This allows client systems to leverage large centrally shared storage. Users can access the same data from any system across the network. A typical setup for NFS includes a server that runs the NFS daemon, nfsd, and lists (export) files and directories to be shared. A client system can mount these exported directories as their local file system.

In this recipe, we will learn how to install the NFS server and client systems.

Getting ready

You will need two Ubuntu systems: one as a central NFS server and another as a client. For this recipe, we will refer to the NFS server with the name Host and the NFS client with the name Client. The following is an example IP address configuration for the Host and Client systems:

Host - 10.0.2.60

Client - 10.0.2.61

You will need access to a root account on both servers, or at least an account with sudo privileges.

How to do it…

Follow these steps to install NFS:

First, we need to install the NFS server:

$ sudo apt-get update

$ sudo apt-get install nfs-kernel-server

Create the directories to be shared:

$ sudo mkdir /var/nfs

Add this directory to NFS exports under /etc/exports:

$ sudo nano /etc/exports

Add the following line to /etc/exports:

/var/nfs *(rw,sync,no_subtree_check)

Save and close the exports file.

Now, restart the NFS service:

$ sudo service nfs-kernel-server restart

Next, we need to configure the client system to access NFS shares.

Create a mount point for NFS shares.

Install the nfs-common package on the client side:

$ sudo apt-get install nfs-common

$ sudo mkdir -p /var/nfsshare

Mount the NFS shared directory on the newly-created mount point:

$ sudo mount 10.0.2.60:/var/nfs /var/nfsshare

Confirm the mounted share with the following command:

$ mount -t nfs

Now, change the directory to /var/nfsshare, and you are ready to use NFS.

How it works…

In the preceding example, we have installed the NFS server and then created a directory that will share with clients over the network. The configuration file /etc/exports contains all NFS shared directories. The syntax to add new exports is as follows:

directory_to_share client_IP_or_name(option1, option2, option..n)

The options used in exports are as follows:

rw: This enables read/write access. You can enable read-only access with the ro option.

sync: This forces the NFS server to write changes to disk before replying to requests. sync is the default option; you can enable async operations by explicitly stating async. Async operations may get a little performance boost but at the cost of data integrity.

no_subtree_check: This disables subtree checking, which provides more stable and reliable NFS shares.

You can check the exports documentation for more export options. Use the man command to open the exports manual pages, as follows:

$ man exports

In the preceding example, we have used the mount command to mount the NFS share. Once the client system has restarted, this mount will be removed. To remount the NFS share on each reboot, you can add the following line to /etc/fstab file:

10.0.2.60:/var/nfs /var/nfsshare nfs4 _netdev,auto 0 0

To mount all shares exported by the NFS server, you can use the following command:

$ sudo mount 10.0.2.60:/ /var/nfsshare

There's more…

NFS 4.1 adds support for pNFS, which enables clients to access the storage device directly and in parallel. This architecture eliminates scalability and performance issues with NFS deployments.

See also

NFS exports options at http://manpages.ubuntu.com/manpages/trusty/man5/exports.5.html

Parallel NFS at http://www.pnfs.com/

NFS documentation in manual pages, by using the following command:

$ man nfs

Installing web access for MySQL in Ubuntu

In this recipe, we will set up a well-known web-based MySQL administrative tool—phpMyAdmin.

Getting ready

You will need access to a root account or an account with sudo privileges.

You will need a web server set up to serve PHP contents.

How to do it…

Follow these steps to install web access for MySQL:

Enable the mcrypt extension for PHP:

$ sudo php5enmod mcrypt

Install phpmyadmin with the following commands:

$ sudo apt-get update

$ sudo apt-get install phpmyadmin

The installation process will download the necessary packages and then prompt you to configure phpmyadmin:

Choose to proceed with the configuration process.

Enter the MySQL admin account password on the next screen:

Another screen will pop up; this time, you will be asked for the new password for the phpmyadmin user. Enter the new password and then confirm it on the next screen:

Next, phpmyadmin will ask for web server selection:

Once the installation completes, you can access phpMyAdmin at http://server-ip/phpmyadmin. Use your admin login credentials on the login screen. The phpmyadmin screen will look something like this:

How it works…

PHPMyAdmin is a web-based administrative console for MySQL. It is developed in PHP and works with a web server such as Apache to serve web access. With PHPMyAdmin, you can do database tasks such as create databases and tables; select, insert, update data; modify table definitions; and a lot more. It provides a query console which can be used to type in custom queries and execute them from same screen.

With the addition of the Ubuntu software repository, it has become easy to install PHPMyAdmin with a single command. Once it is installed, a new user is created on the MySQL server. It also supports connecting to multiple servers. You can find all configuration files located in the /etc/phpmyadmin directory.

There’s more…

If you want to install the latest version of phpMyAdmin, you can download it from their official website, https://www.phpmyadmin.net/downloads/ . You can extract downloaded contents to your web directory and set MySQL credentials in the config.inc.php file.

See also

Read more about phpMyAdmin in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/phpmyadmin.html

Install and secure phpMyAdmin at https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-14-04

Introduction on Centralized Authentication Service

When you have a large user base using multiple services across the organization, a centralized authentication service becomes a need rather than a luxury. It becomes necessary to quickly add new user accounts across multiple services when a new user comes in, and deactivate the respective access tokens when a user leaves the organization. A centralized authentication service enables you to quickly respond by updating the user database on a single central server.

Various different services are available to set up centralized authentication. In this article, we will learn how to set up a centralized authentication service using a Lightweight Directory access Protocol (LDAP). A directory is a special database designed specifically for high volume lookups. LDAP directories are tree-based data structures, also known as Directory Information Trees (DIT). Each node in a tree contains a unique entry with its own set of attributes.

LDAP is specifically designed for high volume read systems with limited write activities. These directories are commonly used for storing details of users with their respective access control lists. Some examples include shared address books, shared calendar services, centralized authentication for systems such as Samba, and storage DNS systems. LDAP provides lightweight access to the directory services over the TCP/IP stack. It is similar to the X.500 OSI directory service, but with limited features and limited resource requirements. For more details on LDAP, check out the OpenLDAP admin guide at http://www.openldap.org/doc/admin24/intro.html .

Securing Ubuntu web server

In this recipe, we will learn some steps for securing web server installation.

Getting ready

You will need access to a root account or an account with sudo privileges.

You may need to have a web server stack installed and running.

How to do it…

Follow these steps to secure the web server:

Disable any unwanted modules. You can check all enabled modules with the following command:

$ a2query -m

Disable modules with the following command:

$ sudo a2dismod status

Hide the web server's identity. For Apache, edit /etc/apache2/conf-available/security.conf and set the following values:

ServerSignature Off

ServerTokens Prod

You may want to check other options under security.conf.

Next, disable the Apache server status page:

$ sudo a2dismod status

For Nginx, edit /etc/nginx/nginx.conf and uncomment the following line:

# server_tokens off;

In production environments, minimize the detail shown on error pages. You can enable the PHP Suhosin module and strict mode.

Disable directory listing. On Apache, add the following line to the virtual host configuration:

Options -Indexes

You can also disable directory listing globally by setting Options -Indexes in /etc/apache2/apache2.conf.

Restrict access to the following directories:

Order deny,allow # order of Deny and Allow

Deny from all # Deny web root for all

Disable directory level settings and the use of .htaccess. This also helps improve performance:

AllowOverride None # disable use of .htaccess

Disable the following symbolic links:

Options -FollowSymLinks

You can also install mod_security and mod_evasive for added security. mod_security acts as a firewall by monitoring traffic in real time, whereas mod_evasive provides protection against Denial of Service attacks by monitoring request data and requester IP.

For Apache, you can install mod_security as a plugin module as follows:

$ sudo apt-get install libapache2-modsecurity

$ sudo a2enmod mod-security

On Nginx, you need to first compile mod_security and then compile Nginx with mod_security enabled.

Turn of server side includes and CGI scripts:

Options -ExecCGI -Includes

Limit request body, headers, request fields, and max concurrent connections; this will help against DOS attacks.

Set the following variables on Apache:

TimeOut

KeepAliveTimeout

RequestReadTimeout

LimitRequestBody

LimitRequestFields

LimitRequestFieldSize

LimitRequestLine

MaxRequestWorkers

For Nginx, configure the following variables to control buffer overflow attacks:

client_body_buffer_size

client_header_buffer_size

client_max_body_size

large_client_header_buffers

Enable logging and periodically monitor logs for any new or unrecognized events:

ErrorLog /var/log/httpd/example.com/error_log

CustomLog /var/log/httpd/example.com/access_log combined

Set up HTTPs and set it to use modern ciphers. You can also disable the use of SSL and enforce TLS.

How it works…

In this recipe, I have listed the various options available to make your web server more secure. It is not necessary to set all these settings. Disabling some of these settings, especially FollowSymlinks and AllowOverride, may not suit your requirements or your environment. You can always choose the settings that apply to your setup.

Various settings listed here are available in their respective configuration files, mostly under /etc/apache2 for the Apache web server and /etc/nginx for the Nginx server.

Also, do not forget to reload or restart your server after setting these options.

You should also set your Ubuntu environment to be more secure. You can find more details on securing Ubuntu in article 2Networking.

See also

Installing mod_evasive at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache

Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html

Setting up mod_security at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu

Creating repository with GitLab

Now that we have set up our own Git hosting and created a new user account, we can start using our Git hosting by creating a new Git repository.

Getting ready

This recipe uses the GitLab setup. Make sure that you have followed the previous recipe and installed your GitLab server.

Log in with your user account on the GitLab server. You can choose the admin account, but a normal user account is recommended.

If you need to use SSH to clone and push to your repositories, you will need to set up your SSH key. From the dashboard, click on Profile Settings and then select SSH Keys to add a new SSH key. Check article 2Networking, for more details on how to create an SSH key.

How to do it…

In the previous recipe, we learned how to create a local repository and then push it to the remote. Here, we will first create a remote or hosted repository and then clone it to our local system:

Log in to your GitLab account. You will be greeted with the Welcome screen detailing your projects.

Click on the NEW PROJECT button to create a new repository:

On a new screen, enter the project or repository name in the project path field. Add an optional descriptive message and select the proper checkbox to make your repository public or private:

Next, click on the Create Project button to create a new repository. This will redirect you to the repository page.

A URL for your repository is listed, with some details on how to use your new repository. You can use HTTP URL if you have not set up SSH keys. Additionally, you may need to replace the hostname with the server IP from the repository URL:

Alternatively, you can create a readme file from the GitLab interface itself. Click on the README link to open a file editor in your browser.

When you clone the private repository using its HTTP URL, a local Git daemon will ask you for the username and password details for authentication.

Tuning TCP stack for Ubuntu

Transmission Control Protocol and Internet Protocol (TCP/IP) is a standard set of protocols used by every network-enabled device. TCP/IP defines the standards to communicate over a network. TCP/IP is a set of protocols and is divided in two parts: TCP and IP. IP defines the rules for IP addressing and routing packets over network and provides an identity IP address to each host on the network. TCP deals with the interconnection between two hosts and enables them to exchange data over network. TCP is a connection-oriented protocol and controls the ordering of packets, retransmission, error detection, and other reliability tasks.

TCP stack is designed to be very general in nature so that it can be used by anyone for any network conditions. Servers use the same TCP/IP stack as used by their clients. For this reason, the default values are configured for general uses and not optimized for high-load server environments. New Linux kernel provides a tool called sysctl that can be used to modify kernel parameters at runtime without recompiling the entire kernel. We can use sysctl to modify and TCP/IP parameters to match our needs.

In this recipe, we will look at various kernel parameters that control the network. It is not required to modify all parameters listed here. You can choose ones that are required and suitable for your system and network environment.

It is advisable to test these modifications on local systems before doing any changes on live environment. A lot of these parameters directly deal with network connections and related CPU and memory uses. This can result in connection drops and/or sudden increases in resource use. Make sure that you have read the documentation for the parameter before you change anything.

Also, it is a good idea to set benchmarks before and after making any changes to sysctl parameters. This will give you a base to compare improvements, if any. Again, benchmarks may not reveal all the effects of parameter changes. Make sure that you have read the respective documentation.

Getting ready…

You will need root access.

Note down basic performance metrics with the tool of your choice.

How to do it…

Follow these steps to tune the TCP stack:

Set the maximum open files limit:

$ ulimit -n # check existing limits for logged in user

# ulimit -n 65535 # root change values above hard limits

To permanently set limits for a user, open /etc/security/limits.conf and add the following lines at end of the file. Make sure to replace values in brackets, >:

soft nofile # soft limits

hard nofile # hard limits

Save limits.conf and exit. Then restart the user session.

View all available parameters:

# sysctl -a

Set the TCP default read-write buffer:

# echo 'net.core.rmem_default=65536' >> /etc/sysctl.conf

# echo 'net.core.wmem_default=65536' >> /etc/sysctl.conf

Set the TCP read and write buffers to 8 MB:

# echo 'net.core.rmem_max=8388608' >> /etc/sysctl.conf

# echo 'net.core.wmem_max=8388608' >> /etc/sysctl.conf

Increase the maximum TCP orphans:

# echo 'net.ipv4.tcp_max_orphans=4096' >> /etc/sysctl.conf

Disable slow start after being idle:

# echo 'net.ipv4.tcp_slow_start_after_idle=0' >> /etc/sysctl.conf

Minimize TCP connection retries:

# echo 'net.ipv4.tcp_synack_retries=3' >> /etc/sysctl.conf

# echo 'net.ipv4.tcp_syn_retries =3' >> /etc/sysctl.conf

Set the TCP window scaling:

# echo 'net.ipv4.tcp_window_scaling=1' >> /etc/sysctl.conf

Enable timestamps:

# echo 'net.ipv4.tcp_timestamp=1' >> /etc/sysctl.conf

Enable selective acknowledgements:

# echo 'net.ipv4.tcp_sack=0' >> /etc/sysctl.conf

Set the maximum number of times the IPV4 packet can be reordered in the TCP packet stream:

# echo 'net.ipv4.tcp_reordering=3' >> /etc/sysctl.conf

Send data in the opening SYN packet:

# echo 'net.ipv4.tcp_fastopen=1' >> /etc/sysctl.conf

Set the number of opened connections to be remembered before receiving acknowledgement:

# echo 'tcp_max_syn_backlog=1500' >> /etc/sysctl.conf

Set the number of TCP keep-alive probes to send before deciding the connection is broken:

# echo 'tcp_keepalive_probes=5' >> /etc/sysctl.conf

Set the keep-alive time, which is a timeout value after the broken connection is killed:

# echo 'tcp_keepalive_time=1800' >> /etc/sysctl.conf

Set intervals to send keep-alive packets:

# echo 'tcp_keepalive_intvl=60' >> /etc/sysctl.conf

Set to reuse or recycle connections in the wait state:

# echo 'net.ipv4.tcp_tw_reuse=1' >> /etc/sysctl.conf

# echo 'net.ipv4.tcp_tw_recycle=1' >> /etc/sysctl.conf

Increase the maximum number of connections:

# echo 'net.ipv4.ip_local_port_range=32768 65535' >> /etc/sysctl.conf

Set TCP FIN timeout:

# echo 'tcp_fin_timeout=60' >> /etc/sysctl.conf

How it works…

The behavior of Linux kernel can be fine tuned with the help of various Linux kernel parameters. These are the options passed to the kernel in order to control various aspects of the system. These parameters can be passed while compiling the kernel, at boot time, or at runtime using the /proc filesystem and tools such as sysctl.

In this recipe, we have used sysctl to configure network-related kernel parameters to fine tune network settings. Again, you need to cross check each configuration to see if it's working as expected.

Along with network parameters, tons of other kernel parameters can be configured with the sysctl command. The -a flag to sysctl will list all the available parameters:

$ sysctl -a

All these configurations are stored in a filesystem at the /proc directory, grouped in their respective categories. You can directly read/write these files or use the sysctl command:

ubuntu@ubuntu:~$ sysctl fs.file-max

fs.file-max = 98869

ubuntu@ubuntu:~$ cat /proc/sys/fs/file-max

98869

See also

Find the explanation of various kernel parameters at the following websites:

http://www.cyberciti.biz/files/linux-kernel/Documentation/networking/ip-sysctl.txt

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt