March 14, 2014

Adding a Static Route to the Route Table

Prerequisite

Install the kernel documentation package, if you have not.

$ yum install kernel-doc -y

The package contains several documentation and you can list them all with 'rpm -ql kernel-doc'.

Display Current Routing

$ ip route show

Enabling Kernel Routing

To enable kernel paremeter ip_forward needs to be on.

$ sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1

And the corresponding documentation.

$ less /usr/share/doc/kernel-doc-2.6.32/Documentation/networking/ip-sysctl.txt
...
ip_forward - BOOLEAN
        0 - disabled (default)
        not 0 - enabled

        Forward Packets between interfaces.

        This variable is special, its change resets all configuration
        parameters to their default state (RFC1122 for hosts, RFC1812
        for routers)
...

If you are not sure how to add search the system documentation.

$ find /usr/share/doc/ -name "*" | xargs grep -i "static route"
...
/usr/share/doc/initscripts-9.03.40/sysconfig.txt:  bring up static routes that depend on that device.  Calls
/usr/share/doc/initscripts-9.03.40/sysconfig.txt:  Set up static routes for a device.
...
$ less /usr/share/doc/initscripts-9.03.40/sysconfig.txt
...
/etc/sysconfig/network-scripts/route-<interface-name>

  Contains lines that specify additional routes that should be added when the
  associated interface is brought up.

  The files are processed by the ifup-routes script and uses the /sbin/ipcalc
  utility for all network masks and numbers. Routes are specified using the
  syntax:

    ADDRESSn=<network>
    NETMASKn=<network/prefix mask>
    GATEWAYn=<next-hop router/gateway IP address>

  The "n" is expected to be consecutive positive integers starting from 0.
  For example:

    ADDRESS0=192.168.2.0
    NETMASK0=255.255.255.0
    GATEWAY0=192.168.1.1

  adds a network route to the 192.168.2.0 network via the gateway at
  192.168.1.1. Since you must already have a route to the network of the
  gateway, there is no need to specify a device.

  Note: The ifup-routes script also supports an older syntax designed to be
  used directly as an argument to "/sbin/ip route add".
  If no "ADDRESSn" lines are found the following will still
  work:
  
  192.168.2.0/24 dev ppp0
  
  adds a network route to the 192.168.2.0 network through ppp0.
...

Or you can add via CLI, but this will not be permanent.

$ ip route add network/netmask via router_ip

Disable Ping Request (ICMP Echo) in Linux Kernel

Prerequisite

Install the kernel documentation package, if you have not.

$ yum install kernel-doc -y

The package contains several documentation and you can list them all with 'rpm -ql kernel-doc'.

Test Before

$ ping 192.168.122.10
PING 192.168.122.10 (192.168.122.10) 56(84) bytes of data.
64 bytes from 192.168.122.10: icmp_seq=1 ttl=64 time=0.171 ms

Ok. The machine is responding to ping.

Set Kernel Parameter to Ignore Ping (ICMP echo) Request

Now use kernel configuration tool, sysctl, to first list all parameter that contain ICMP.

$ sysctl -a | grep icmp
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.ipv4.icmp_echo_ignore_all = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.icmp_errors_use_inbound_ifaddr = 0
net.ipv4.icmp_ratelimit = 1000
net.ipv4.icmp_ratemask = 6168
net.ipv6.icmp.ratelimit = 1000

To find out what each parameter do read the kernel network ip sysctl documentation.

$ grep -A5 icmp /usr/share/doc/kernel-doc-*/Documentation/networking/ip-sysctl.txt 
icmp_echo_ignore_all - BOOLEAN
 If set non-zero, then the kernel will ignore all ICMP ECHO
 requests sent to it.
 Default: 0
...

And to set kernel parameter.

$ sysctl -w net.ipv4.icmp_echo_ignore_all=1

Now test again to ping server and you should not get any respond.

To make the changes permanent.

$ echo "net.ipv4.icmp_echo_ignore_all = 1" >> /etc/sysctl.conf

Network Bonding in RHEL 6

Introduction

To bind multiple network interfaces together into a single channel is called bonding.

The reason for this is to achieve:

  1. Round robin around network interfaces.
  2. Master - slave for redundancy.
  3. Throughput. Use all at the same time.

Reference

RHEL 6 Deployment Guide

IP Aliases in RHEL 6

Introduction

Assigning multiple IP addresses to a single interface is called IP aliasing. This can be handy if you want a single web server to serve multiple sites.

Prerequisite

It is advised to disable NetworkManager.

$ service NetworkManager stop; chkconfig NetworkManager off

Configuration

Show current configuration for eth0.

$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:22:d1:df brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.20/24 brd 192.168.122.255 scope global eth0
    inet6 fe80::5054:ff:fe22:d1df/64 scope link 
       valid_lft forever preferred_lft forever

Add IP alias.

$ ip addr add 192.168.122.250/24 dev eth0 label eth0:0

Show new configuration for eth0

$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:22:d1:df brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.20/24 brd 192.168.122.255 scope global eth0
    inet 192.168.122.250/24 scope global eth0:0
    inet6 fe80::5054:ff:fe22:d1df/64 scope link 
       valid_lft forever preferred_lft forever

To make it persistent edit the following

$ vi /etc/sysconfig/network-scripts/ifcfg-eth0:0
DEVICE=eth0:0
IPADDR=192.168.122.250
PREFIX=24
ONPARENT=yes

Now restart network service.

$ service network restart

Test

Ping from another machine

$ ping 192.168.122.250
PING 192.168.122.250 (192.168.122.250) 56(84) bytes of data.
64 bytes from 192.168.122.250: icmp_seq=1 ttl=64 time=1.05 ms

Reference

/usr/share/doc/initscripts-*/sysconfig.txt

March 13, 2014

Build a Simple RPM Package

Prerequisite

Install package that contain the rpmbuild tool that create the rpm package.

$ yum install rpm-build

Install also a convenient development tool for setting up environment.

$ yum install rpmdevtools

When building rpm package you should do that with a noon root user. To create a new user.

$ useradd rpmuser

Setup

Change to rpm user and from it's home directory run:

$ rpmdev-setuptree

This will create a new empty catalogue structure for your rpm package development.

Creating the Program

$ vi ~/rpmbuild/SOURCES/hello.sh

#!/bin/bash
echo "Good morning, world."

We can test run to see that it actually runs.

$ chmod +x ~/rpmbuild/SOURCES/hello.sh
$ ~/rpmbuild/SOURCES/hello.sh
Good morning, world.

Creating the RPM Spec File

Now with help of wim, that will create a template spec file, we will create a rpm spec file for our hello rpm package.

$ vim ~/rpmbuild/SPECS/hello.spec
Name:   hello  
Version: 1.0 
Release: 1%{?dist}
Summary:  A simple hello world application. 

Group:  Applications/File
License: GPLv2+
URL:  http://magnus-k-karlsson.blogspot.se/  
Source0: hello.sh 
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

#BuildRequires: 
Requires: bash

%description

# Prep is used to set up the environment for building the rpm package
# Expansion of source tar balls are done in this section
#%prep
#%setup -q

# Used to compile and to build the source
#%build
#%configure
#make %{?_smp_mflags}

# The installation.
%install
rm -rf %{buildroot}
#make install DESTDIR=%{buildroot}
mkdir -p %{buildroot}/usr/bin
cp %{SOURCE0} $RPM_BUILD_ROOT/usr/bin/.

%clean
rm -rf %{buildroot}

%files
%defattr(-,root,root,-)
/usr/bin/hello.sh
%doc

%changelog

Build the RPM

$ rpmbuild -ba ~/rpmbuild/SPECS/hello.spec

Test the RPM

Query (q) the local package (p) for all it's files (l).

$ rpm -qpl rpmbuild/RPMS/x86_64/hello-1.0-1.el6.x86_64.rpm
/usr/bin/hello.sh

Now switch to root and install the package.

$ rpm -pi /home/rpmuser/rpmbuild/RPMS/x86_64/hello-1.0-1.el6.x86_64.rpm

And test it.

$ hello.sh 
Good morning, world.

And to uninstall it.

$ yum erase hello
...

Yum Plugins

There are numerous yum plugins. You can search for which are available.

$ yum search yum-plugin
...
PackageKit-yum-plugin.x86_64 : Tell PackageKit to check for updates when yum exits
anaconda-yum-plugins.noarch : Installation-related yum plugins
kabi-yum-plugins.noarch : The Red Hat Enterprise Linux kernel ABI yum plugin
yum-plugin-aliases.noarch : Yum plugin to enable aliases filters
yum-plugin-changelog.noarch : Yum plugin for viewing package changelogs before/after updating
yum-plugin-downloadonly.noarch : Yum plugin to add downloadonly command option
yum-plugin-protect-packages.noarch : Yum plugin to prevents Yum from removing itself and other protected packages
yum-plugin-security.noarch : Yum plugin to enable security filters
yum-plugin-tmprepo.noarch : Yum plugin to add temporary repositories
yum-plugin-verify.noarch : Yum plugin to add verify command, and options
yum-plugin-versionlock.noarch : Yum plugin to lock specified packages from being updated

What does yum-plugin-verify do?

"This plugin adds the commands verify, verify-all and verify-rpm. There are also a couple of options. This command works like rpm -V, to verify your installation." [yum info yum-plugin-verify]

For more information about each commands, run 'yum --help'

What does yum-plugin-versionlock do?

"This plugin takes a set of name/versions for packages and excludes all other versions of those packages (including optionally following obsoletes). This allows you to protect packages from being updated by newer versions, for example." [yum info yum-plugin-versionlock]

The yum-plugin-versionlock uses the /etc/yum/pluginconf.d/versionlock.list to lock down specific packages.

The following format is used for locking down. See /usr/share/doc/yum-plugin-versionlock-*/README.

EPOCH:NAME-VERSION-RELEASE.ARCH

Encrypting Files with GnuPG

Generate private key.

$ gpg --gen-key

List all public keys.

$ gpg --list-keys

Export a public key.

$ gpg --armor --output "magnus.k.karlsson.txt.asc" --export "Magnus K Karlsson"

Import a public key from "Pelle Petterson".

$ gpg --import pelle.petterson.txt.asc

Encrypt a file for recipient "Pelle Petterson", with public key from "Pelle Petterson".

$ gpg --armor --recipient "Pelle Petterson" --output "foo.txt.gpg" --encrypt "foo.txt"

Decrypt a file, encrypted with your public key.

$ gpg --output "foo.txt" --decrypt "foo.txt.gpg"