Using one-time passwords (OTPW) in SSH authentication

One-time passwords/OTPW consists of one-time password generator and PAM-integrated verification routines.

One-time passwords are generated apriori with the generator, given to the user and cryptographic hash of the generated passwords are stored in the host. When a user logs in with a one-time password, OTPW’s PAM module verifies the password, and invalidates it to prevent re-use.

## install (deb/ubuntu)
$ apt-get install otpw-bin libpam-otpw
$ vi /etc/pam.d/sshd
#@include common-auth
auth       required     pam_otpw.so
session    optional     pam_otpw.so

## install (arch)
$ yaourt -S otpw 
$ vi /etc/pam.d/ssh-otpw
auth sufficient pam_otpw.so
session optional pam_otpw.so
$ vi /etc/pam.d/sshd
auth      include   ssh-otpw
#auth      include   system-remote-login

## install (el/fedora)
$ yum git gcc pam-devel
$ git clone https://www.cl.cam.ac.uk/~mgk25/git/otpw ; cd optw
$ vi Makefile
PAMLIB=/usr/lib64/security
$ make ; sudo make install
# disable SELinux
$ vi /etc/selinux/config
SELINUX=disabled
$ vi /etc/pam.d/sshd
#auth       substack     password-auth
auth       required     pam_otpw.so
session    optional     pam_otpw.so

## configure sshd
$ vi /etc/ssh/sshd_config
UsePAM yes
UsePrivilegeSeparation yes
ChallengeResponseAuthentication yes
PubkeyAuthentication yes
PasswordAuthentication no
$ systemctl restart sshd

## generate passwords
# asks for a prefix to user cannot login even if list is public
$ otpw-gen > ~/temporary_password.txt
# print 'otpw_passwords' file; passwords are store in '~/.otpw'

## using
$ ssh user@remote_host
Password INDEX:
# use password in INDEX prefixed with your prefix
# if successful '~/.otpw' is updated to void used password

from otpw@xmodulo and otpw@arch/otpw@ubuntu

How to generate (random) and store (key-derived) passwords in Linux (using pwgen/apg/makepasswd/mkpasswd and crypt/bcrypt/scrypt)

Password strength is a measure of the effectiveness of a password in resisting guessing and brute-force attacks. They should not be repeated hence cryptographically secure random or one-time password.

Generating passwords/strings

# generates a base64 encoded 32 chars length random string
$ openssl rand -base64 32
  • pwgen@man generates pronounceable random (using /dev/urandom) passwords which are designed to be easily memorized by humans, while being as secure as possible.
$ yum install pwgen (EPEL) | apt-get install pwgen | pacman -S pwgen

'-s,--secure' generate completely random, hard-to-memorize passwords
'-B,--ambiguous' dont use characters 'I,1,O,0' that could be confused when printed
'-N,--num-passwords=NUM' number of passwords to generate
'-y,--symbols' include at least one special character in the password
# generate 2 passwords of 20 chars length each (default is 8)
$ pwgen -n 2 20

from pwgen@tecmint and pwgen@nixcraft

  • apg@man generates random passwords using pronounceable password generation algorithm (default) or /dev/urandom.
$ apt-get install apg | yum install apg | pacman -S apg

'-a ALG' 0 for pronounceable or 1 for urandom
'-n NUM' number of passwords to generate
'-m MIN, -x MAX' min/max password length
'-E CHARS' exclude chars from password
'-M MODE' 'S/s' must/should include special chars, 'N/n' numeral, 'C/c' capital, 'L/l' lowercase
'-r DICTFILE' check against a dictionary file
'-y' print encrypted password using crypt(3)
'-t' print pronunciation
$ apg -n 1 -t
  • makepasswd@ubuntu is a perl script that generates random (using /dev/urandom as seed) passwords with the emphasis on security over pronounceability. Optionally it also hashes/encrypts using crypt(3) des or md5.
$ apt-get install makepasswd | pacman -S makepasswd
# note (el/fedora): rawhide's makepasswd is a different program, same idea but in in C also using /dev/random and crypt(3)

'-chars N' password length (default is 10)
'--count N' number of passwords to generate
'-string STRING' uses chars in STRING to generate random password
# generates 2 passwords of 20 chars each
$ makepasswd --char 20 --count 2

'--clearfrom FILE' use tpassword from FILE instead of generating passwords
'--crypt' generates encrypted passwords
'--crypt-md5' encrypts using MD5 (default to DES)
'--cryptsalt N' uses crypt() salt N, defaults to 0 (random seeds)
# encrypt a password (instead of generating)
$ cat PASSWORD > pwd.txt
$ makepasswd --clearfrom pwd.txt --crypt

from makepasswd@tecmint and makepasswd@nixcraft

$ apt-get install expect | yum install expect | pacman -S expect
# note(deb/ubuntu): mkpasswd (from whois) is just a crypt(3) wrapper, use expect_mkpasswd instead

# generates a 10 char password and applies to current user
$ ?expect_?mkpasswd -l 10 $USER

from mkpasswd@tecmint and mkpasswd@nixcraft

Using key derivation functions (to store passwords)

Passwords should not be stored as plain-text, but instead be stored as result of key derivation functions. Basically a hash with a salt (a long random string that needn’t be kept secret) called many times.

passwd@wki is used to change user’s password. It is stored in /etc/shadow file encrypted/hashed by crypt(3). Format is $id$salt$encrypted where $id$ is $1$ for MD5, $2$ for blowfish, $5$ for SHA-256 and $6$ for SHA-512(default).

  • openssl dgst digest/hash functions output the message digest of a supplied file or files in hexadecimal.
# sha512 hash a script
$ echo -n STRING | openssl dgst -sha512
  • crypt(3) is the traditional Unix key derivation function. It uses DES by default, but also supports others.
# using deb/ubuntu mkpasswd (from whois), a crypt(3) wrapper
# SHA-512/crypt a password using given a salt
$(deb) mkpasswd PASSWORD -s SALTSASLT -m SHA-512

# DES/crypt a password using a random salt
$ openssl passwd -crypt PASSWORD
  • pbkdf2 is a key derivation function that is part of RSA. It applies a pseudorandom function, such as a cryptographic hash, cipher, or HMAC to the input password along with a salt value and repeats the process many times to produce a derived key. OpenSSL’s PKCS5_PBKDF2_HMAC is one implementation.
$ vi pbkdf2.c
/* usage:  % $0 password salt 1024 56 | openssl base64 */
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/evp.h>
int main(int argc, char *argv[])
{
    const char *usage = "usage: %s <password> <salt> <iterations> <keylen>";
    if (argc != 5) errx(1, usage, argv[0]);
    const char *pass = argv[1], *salt = argv[2]; 
    int iter = (int)strtol(argv[3], (char **)NULL, 10);
    int keylen = (int)strtol(argv[4], (char **)NULL, 10);

    unsigned char *out = malloc(keylen);
    PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), salt, strlen(salt), iter, keylen, out); 
    return (write(1, out, keylen) == -1) ? 1: 0;
}

from pbkdf2.c

# blowfish in CFB mode, prompts for password
$ openssl enc -base64 -e -bf -in <infile> -out <outfile>
$ yum install scrypt | apt-get install scrypt | pacman -S scrypt 

# prompts for password 
$ scrypt enc infile outfile

How to non-interactive/unattended password login to ssh (using sshpass and ssh_askpass)

  • sshpass@man is a noninteractive ssh password provider. Its an less secure alternative to public key authentication. sshpass only works if the password prompt ends in assword:.
## install
$ apt-get install sshpass | yum install sshpass (EPEL) | pacman -S sshpass

'-p PASSWORD' take password from cli
'-e' take password from SSHPASS env var

# need to disable host key checking
$ sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no user@host

# rsync (and scp) over password ssh
$ SSHPASS=PASSWORD rsync --rsh='sshpass -e ssh -l user' host:path .
$ sshpass -p PASSWORD scp user@host:path .

from sshpass@cyberciti

  • ssh@man using SSH_ASKPASS. If ssh does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11 window to read the passphrase.
$ vi mypass.sh
#!/bin/sh
echo PASSWORD
$ export DISPLAY=:0 ; export SSH_ASKPASS=`pwd`/mypass.sh
$ setsid ssh -o StrictHostKeyChecking=no user@host

from ssh password from stdin

How to mass rename/copy/link files in Linux (using mmv and rename)

  • mmv moves (or copies, appends, or links, as specified) each source file matching a from pattern to the target name specified by the to pattern.
$(el) yum install mmv (NUX)
$(deb) apt-get install mmv
$(arch) yaourt -S mmv

# '*.jpeg' -> '*.jpg'
$ mmv '*.jpeg' '#1.jpg'
# '.html.en' -> 'en.html'
$ mmv '*.html.??' '#1.#2#3.html'
  • rename@man/rename@ubuntu is a perl script which can be used to mass rename files according to a regular expression.
$(el) yum install util-linux-ng
$(deb) apt-get install perl
$(arch) pacman -S perl-rename

# '*.php' -> '*.html'
$ rename -n 's/.php$/.html/' *.php
# upper case -> lower case
$ rename 'y/A-Z/a-z/' *
# strip '.bak' extension
$ rename 's/.bak$//' *.bak

from rename@cyberciti and rename@tecmint

Using youtube-dl/ffmpeg to download Youtube videos/playlists and convert to mp3

youtube-dl is a small command-line python program to download videos from YouTube.com and a few more sites.

## install
$(el) sudo yum install youtube-dl ffmpeg(RPMforge)
$(deb) sudo apt-get install youtube-dl ffmpeg(>=15.04)|libav-tools(<=14.10)
$(osx) brew install youtube-dl ffmpeg
$(arch) sudo pacman -S youtube-dl ffmpeg
$(pip) sudo pip install -U youtube-dl
$(bin) sudo wget https://yt-dl.org/latest/youtube-dl -O /usr/local/bin/youtube-dl ; sudo chmod a+x /usr/local/bin/youtube-dl

youtube-dl [OPTIONS] URL [URL...] (where URL can also be a playlist)

# video formats
'-F,--list-formats' list available formats
'-f,--format FORMAT' download selected format
'--max-quality FORMAT' highest quality format to download
$ youtube-dl -f 17 URL

# filesystem/download options
'-a,--batch-file FILE' file containing URLs to download, - to stdin
'-o,--output TEMPLATE' output filename template, e.g.: 'downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s'
'-c,--continue' force resume of partially downloaded files
'-i,--ignore-errors' continue on download errors, e.g.: skip unavailable videos in a playlist
'-w,--no-overwrites' do not overwrite files
$ youtube-dl -a FILE

# post-processing (e.g: extract audio)
'-x,--extract-audio' convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe)
'--audio-format FORMAT' best(default), aac, vorbis, mp3,m4a, opus or wav
'--recode-video FORMAT' encode the video to another format (mp4,flv,ogg,webm,mkv)
$ youtube-dl PlaylistURL -cit --max-quality FORMAT --extract-audio --audio-format mp3

from save youtube videos, install ffmpeg and download youtube playlist

clipgrab is an alternative to youtube-dl. Its a GUI app that grabs URLs from clipboard and adds them to a download list.

Using terminal pager in Linux (“less is more”, multitail and most)

Terminal pager is used to view (but not modify) the contents of a text file moving down the file one line or one screen at a time. Some, but not all, pagers allow movement up a file.

  • less@wiki/less@man is similar to more@wki, but has the extended capability of allowing forward/backward navigation and following a file.
## install
$ sudo apt-get|yum install util-linux

# navigation
'space,pgdown' next page
'b,pgup' previous page
'g,<' first line
'G,>' last line
'<n> G' line n
'F' enter follow mode, exit CTRL+C
$ less +F FILE

# search
'/ <text>' forward regexp search
'? <text>' backward regexp search
'n' next match
'N' previous match
$ less -I -p PATTERN FILE
  • multitail@wiki/multitail@man splits the terminal window or console (using ncurses) of a into two or more subwindows into which it can merge log files and command outputs.
## install
$ sudo apt-get|yum install multitail (EPEL) | sudo pacman -S multitail

# navigation
'b/B' scroll back selected/all windows
  'q' quit, 'g/G' goto first/last line, 'pgup/pgdown' page up/down
'Y' toggle line wrap
'F' simulate 'tail -f' mode

# window
'a/d' add/delete new window (or file to existing window)
'v' toggle vertical/horizontal window

# search
'/' regexp search
'I' toggle case sensitivity

'-i/I FILE' open file in new/previous window
'--mergeall' merge all windows
$ multitail /var/log/dmesg -I /var/log/syslog

'-l,L CMD' open command output in new/previous window
'-r/R INTERVAL' restarts command periodically, '-R' only shows differences
$ multitail -R 2 -l "netstat -tap"

'-s X' splits vertically 'x' columns
'-sn Y' how many windows per colum
$(2x2) multitail -s 2 -sn 2,2 FILE1..4

'-q INTERVAL PATH' periodicaly checks path for new files, '-Q' merges all in one window
$ multitail -Q 5 /var/log/*.log

from multitail@howtoforge

  • most@wiki/most@ is similar to more@wki, but has the extended capability of allowing both forward/backward and left/right navigation through the file, and supports multiple windows.
## install
$ sudo apt-get|yum install most | sudo pacman -S most

# navigation
'space,D,pgdown' page down
'U,delete,pgup' page up
'T/B' scroll top/bottom
'</>' scroll left/right
'J,G' goto line
':n' skip to next file

# window
'ctrl-w,x 2' horizontal split window in half
'ctrl-w,x 1' delete all other windows
'ctrl-x 0' delete this window
'o,ctrl-x 0' move to other window

# search
'S,f,/' forward search
'?' backward search
'n' next match

Using KVM Linux hypervisor (with libvirt, virtsh, virt-install and guestfish/libguestfs)

KVM (Kernel-based Virtual Machine) is a virtualization infrastructure for the Linux kernel that turns it into a hypervisor.

Installing

## check hardware virtualization supoort
$ egrep -i 'vmx|svm' --color=always /proc/cpuinfo

## disable SELinux
$ vi /etc/selinux/config
SELINUX=permissive
$ reboot

## install KVM, QEMU and user-space tools
$ apt-get install qemu-kvm qemu-utils libvirt-bin | yum install qemu-kvm qemu-img libvirt
$ sudo service libvirtd start | sudo systemctl start libvirtd 

# optionally add yourself to libvirtd group, otherwise sudo
$ sudo adduser <youruser> libvirtd
# check libvirtd daemon
$ sudo virsh -c qemu:///system list

from kvm@debian and kvm@centos

Networking

libvirt installation provides NAT based connectivity, also called default virtual network. It adds iptables rules to allow traffic to/from guests attached to the virbr0 device in the INPUT, FORWARD, OUTPUT and POSTROUTING chains, and attempt to enable ip_forward.

Advanced users will want to use full bridging, where the guest is connected directly to the LAN. Don’t attach a physical device to virbr0 (this is only for NAT connectivity).

## check default NAT virtual network
$ virsh net-list --all
default              active     yes
$ brctl show
virbr0

## bridging non-persistent using bridge-utils/brctl
$ apt-get|yum install bridge-utils
$ brctl addbr br0
$ brctl addif br0 eth0
# assign ip to bridge
$ ip link set dev br0 up
$ ip addr add dev br0 10.10.1.105/24
# delete
$ ip link set dev eth0 promisc on
$ ip link set dev eth0 master br0

## bridging using ifcfg/rhel
# disable network manager
$ sudo service NetworkManager stop ; sudo chkconfig NetworkManager off
$ sudo chkconfig network on ; sudo service network start
$ ifdown eth0
$ vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BRIDGE=br0
$ vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
NM_CONTROLLED=yes
ONBOOT=yes
TYPE=Bridge
# either static
BOOTPROTO=none
IPADDR=10.10.1.105
NETMASK=255.255.255.0
GATEWAY=10.10.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
# or dhcp
#BOOTPROTO=dhcp
$ ifup eth0 ; ifup br0

## bridging in debian
$ vi /etc/network/interfaces
#auto eth0
#iface eth0 inet dhcp
# either static
iface br0 inet static
  bridge_ports eth0 eth1
  address 10.10.1.105
  broadcast 10.10.1.255
  netmask 255.255.255.0
  gateway 10.10.1.1
# or dhcp
auto br0
iface br0 inet dhcp
  bridge_ports eth0
  bridge_stp off
  bridge_fd 0
  bridge_maxwait 0
$ /etc/init.d/networking restart

## bridging using nmcli/networkmanager
$ nmcli con add type bridge autoconnect yes con-name br0 ifname br0
# either static
$ nmcli con mod br0 ipv4.addresses "10.10.1.105/24 10.10.1.1" ipv4.method manual 
$ nmcli con mod br0 ipv4.dns "8.8.8.8 8.8.4.4"
# or dhcp
$ nmcli con mod br0 ipv4.method auto
# remove current setting and add interface to bridge
$ nmcli c delete eth0
$ nmcli c add type bridge-slave autoconnect yes con-name eth0 ifname eth0 master br0
$ systemctl restart NetworkManager

from virtual networking and networking hints and tips

Using virsh

Virsh/virsh@man is main interface for managing (create, pause shutdown) virsh guest domains. It uses libvirt@wiki, an open source C API/lib, daemon and management tool for managing platform virtualization. It can be used to manage KVM, Xen, LXC, VMware ESX, QEMU, VirtualBox, Hyper-V, Bhyve and other virtualization technologies.

$ curl http://cdimage.ubuntu.com/ubuntu-server/daily/current/vivid-server-amd64.iso 
  -o linux.iso

## create virtual disk using qcow2 (grows as needed)
$ qemu-img create -f qcow2 /var/lib/libvirt/images/guest.qcow2 8G

## create domain xml file either manually
$ uuid
f5b8c05b-9c7a-3211-49b9-2bd635f7e2aa
$ vi guest.xml
<domain type='kvm'>
  <name>guest</name>
  <uuid>f5b8c05b-9c7a-3211-49b9-2bd635f7e2aa</uuid>
  <memory>1048576</memory>
  <currentMemory>1048576</currentMemory>
  <vcpu>2</vcpu>
  <os>
    <type>hvm</type>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type="file" device="disk">
      <driver name="qemu" type="qcow2"/>
      <source file="/var/lib/libvirt/images/guest.qcow2"/>
      <target dev="vda" bus="virtio"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x0"/>
    </disk>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file=linux.iso"/>
      <target dev="hdc" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="1" target="0" unit="0"/>
    </disk>
    <controller type="ide" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
    </controller>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport="yes" listen='127.0.0.1'/>
    <console type='pty'>
      <target port='0'/>
    </console>
  </devices>
</domain>

## start vm
$ virsh create guest.xml
$ virsh list
...

## remote access vm
# either by vnc, usually kvm-host:5900
$ sudo netstat -nap | grep kvm
tcp 0 0.0.0.0:5900
# or console
$ virsh console guest

## manage VMs
$ virsh destroy|shutdown|undefined|suspend|resume|autostart guest

Using virt-install

virt-install@man is a command line tool for creating new KVM , Xen, or Linux container guests using libvirt

## install
$ apt-get install virtinst | yum install virt-install

'-r,--ram MEMORY' guest memory
'--vcpus VCPUS' guest virtual cpus
'--cpuset CPUSET' physical cpus used by guest, eg: 1-5,^3,8
'-c,--cdrom CDROM or' virtual file or device, iso usually
'--boot=BOOTOPTS' boot priority and kernel args, eg: cdrom,fd,hd,network,kernel_args="console=/dev/ttyS0"
'--disk path=PATH,size=G,format=raw|qcow2' same as '--filesystem PATH' guest storage media, created if doesnt exist
'--network bridge=BRIDGE|network=NAME'
'--graphics vnc|none' defaults to vnc
'--hvm' request full virtualization, useful if both para and full virtualizations are available
'--autostart' start domain on host boot

## start VM (from ISO locally or remotelly)
$ virt-install --name guest --ram 1024 --vcpus=2 
  --disk path=/var/lib/libvirt/images/guest.qcow2,device=disk,size=8 
  --network bridge=virbr0 --cdrom linux.iso

from Installing a virtual machine using virt-install and virt-install@tecmint

Using guestfish/libguestfs

libguestfs/Libguestfs@wiki/guestfish@man is a set of tools for accessing and modifying virtual machine (VM) disk images. You can use this for viewing and editing files inside guests, scripting changes to VMs, monitoring disk used/free statistics, creating guests, P2V, V2V, performing backups, cloning VMs, building VMs, formatting disks, resizing disks, and much more.

Libguestfs is a C library. All this functionality is available through guestfish scriptable and interactive shell, or virt-* tools (just a script wrapper).

## install
$ apt-get install libguestfs-tools | yum install libguestfs-tools | yaourt -S libguestfs

'-rw(default) or -ro' read-write or read-only
'-d libvirt-domain or -a disk.img'
'-i' interactive shell

# list files
$ virt-ls -d DOMAIN DIRECTORY

# edit file
$ virt-edit -d DOMAIN FILE -e 'SED-EXPR'
$ guestfish --rw -i -d DOMAIN
><fs> download FILE /tmp/FILE
><fs> ! sed -i 'SED-EXP' /tmp/FILE
><fs> upload /tmp/FILE FILE
# remove root password
$ virt-edit -a disk.img /etc/passwd -e 's/^root:.*?:/root::/'

# checksum file
$ guestfish --ro -a disk.img -i checksum sha256 FILE

# convert ISO to tarball
$ guestfish --ro -a in.iso -m /dev/sda tgz-out / out.tar.gz

# interactive commands, eg: delete,touch,stat a file
$ guestfish -a disk.img -i rm FILE
$ guestfish --ro -a disk.img -i stat FILE
# list all commands
$ guestfish -h

# lists differences between files in two VMs (or disk images)
$ virt-diff -d oldguest -D newguest
$ virt-diff -a old.img -A new.img

# disable systemd service
$ guestfish -a disk.img -i ln-sf /dev/null /etc/systemd/system/cloud-init.service

# export directory from VM
$ virt-copy-out -d DOMAIN VMDIR LOCALDIR

# read file
$ virt-cat disk.img FILE

# install packages
$ virt-builder fedora-20 -edit '/etc/yum.repos.d/fedora-updates-testing.repo:s/enabled=0/enabled=1/' --install emacs
# list os/templates supported
$ virt-builder --list
# same but using virt-customize
$ virt-customize -a fedora-20.img --update --install gcc

# show free space
$ virt-df -a disk.img
# list all filesystems
$ virt-filesystems -a disk.img --all --long -h

# show OS info, including version and installed packages
$ virt-inspector -d DOMAIN

# create a new image
$ virt-builder centos-7.0

# set root password
$ virt-sysprep --enable customize --root-password password:123456 -a /dev/sdX

# resize image, expand '/dev/sda2' by '+5G'
$ virt-filesystems --long -h --all -a olddisk
$ truncate -r olddisk newdisk ; truncate -s +5G newdisk
$ virt-resize --expand /dev/sda2 olddisk newdisk

from virt-tools, virt-tools@rwmj and guestfs-recipes/guestfs-recipes@ubuntu

Other KVM management tools

Virt-manager@wiki, GNOME_Boxes@wiki and OVirt@wiki are GUI versions of virtsh. See tools@kvm.

How to do network bridging in Linux (using initscripts/ifcfg/ifupdown, brctl/bridge-utils, nmcli/networkmanager, netctl/arch and systemd-networkd)

Network bridge is Link Layer device which forwards traffic between networks based on MAC addresses and is therefore also referred to as a Layer 2 device.

It makes forwarding decisions based on tables of MAC addresses which it builds by learning what hosts are connected to each network. A software bridge can be used within a Linux host in order to emulate a hardware bridge, for example in virtualization applications for sharing a NIC with one or more virtual NICs.

  • ifup/ifdown@man network interface configuration files used by ifup/ifdown, called by initscripts (used prior to systemd). Works all distros (but configuration file location and syntax changes).
$ apt-get|yum install bridge-utils

# disable network manager
$ sudo service NetworkManager stop ; sudo chkconfig NetworkManager off

## fedora/rhel
$ vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BRIDGE=br0
$ vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
NM_CONTROLLED=yes
ONBOOT=yes
TYPE=Bridge
# either static
BOOTPROTO=none
IPADDR=10.10.1.105
NETMASK=255.255.255.0
GATEWAY=10.10.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
# or dhcp
#BOOTPROTO=dhcp
$ service network restart

## bridging in debian/ubuntu
$ vi /etc/network/interfaces
#auto eth0
#iface eth0 inet dhcp
# either static
iface br0 inet static
  bridge_ports eth0 eth1
  address 10.10.1.105
  broadcast 10.10.1.255
  netmask 255.255.255.0
  gateway 10.10.1.1
# or dhcp
auto br0
iface br0 inet dhcp
  bridge_ports eth0
  bridge_stp off
  bridge_fd 0
  bridge_maxwait 0
$ service networking restart

## manual, non-persistent using brctl
$ brctl addbr br0
$ brctl addif br0 eth0
# assign ip to bridge
$ ip link set dev br0 up
$ ip addr add dev br0 10.10.1.105/24
# delete
$ ip link set dev eth0 promisc on
$ ip link set dev eth0 master br0

## manual, non-persistent using iproute2/net-tools
$ ip link add name br0 type bridge
$ ip link set dev eth0 promisc on
$ ip link set dev eth0 master br0
# assign ip to bridge
$ ip link set dev br0 up
$ ip addr add dev br0 10.10.1.105/24
# delete
$ ip link set eth0 promisc off
$ ip link set dev eth0 nomaster
$ ip link delete br0 type bridge

from bridge@rhel, bridge@debian and bridge@rhel

# install
$ sudo yum install NetworkManager | sudo apt-get install network-manager | sudo pacman -Sy networkmanager

# create bridge
$ nmcli con add type bridge autoconnect yes con-name br0 ifname br0

# assign ip either static
$ nmcli con mod br0 ipv4.addresses "10.10.1.105/24 10.10.1.1" ipv4.method manual 
$ nmcli con mod br0 ipv4.dns "8.8.8.8 8.8.4.4"
# or dhcp
$ nmcli con mod br0 ipv4.method auto

# remove current setting and add interface to bridge
$ nmcli c delete eth0
$ nmcli c add type bridge-slave autoconnect yes con-name eth0 ifname eth0 master br0

$ systemctl restart NetworkManager | service network-manager restart

from nmcli@rhel7

  • netctl@arch is a CLI-based tool used to configure and manage network connections via profiles. Arch only.
## install
$ sudo pacman -Sy netctl

## create 'br0' with real eethernet adaptor 'eth0' and 'tap0' tap device
$ cp /etc/netctl/examples/bridge /etc/netctl/bridge
$ vi /etc/netctl/bridge
Description="Example Bridge connection"
Interface=br0
Connection=bridge
BindsToInterfaces=(eth0 tap0)
# either static
IP=static
Address='192.168.10.20/24'
Gateway='192.168.10.200'
SkipForwardingDelay=yes # ignore (R)STP and immediately activate the bridge
# or dynamic
#IP=dhcp

$ netctl enable bridge ; netctl start bridge

from Bridge with netctl@arch

  • systemd.network as of version 210, systemd supports basic network configuration through udev and networkd.
# disable network manager
$ systemctl disable NetworkManager
# enable daemons
$ systemctl enable systemd-networkd
$ systemctl restart systemd-networkd
$ systemctl enable systemd-resolved
$ ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

# create bridge
$ vi /etc/systemd/network/br0.netdev 
[NetDev]
Name=br0
Kind=bridge
$ vi /etc/systemd/network/br0.network
[Match]
Name=br0
[Network]
# static
DNS=192.168.250.1
Address=192.168.250.33/24
Gateway=192.168.250.1
# or dynamic
#DHCP=v4

# assign network adaptor
$ vi /etc/systemd/network/uplink.network
[Match]
Name=en*
[Network]
Bridge=br0

# using in container
$ systemd-nspawn --network-bridge=br0 -bD /path_to/my_container

from Network bridge@arch

How to generate SSL CSR (certificate signing request) and self-signed certificates for Apache/Nginx (using OpenSSL)

  • OpenSSL is an open-source implementation of the SSL and TLS protocols.
'req' PKCS#10 certificate request and certificate generating utility.
'-x509' outputs a self signed certificate instead of a certificate request
'-newkey alg:file' creates a new certificate request and a new private key
'-keyout filename' filename to write the newly created private key to
'-out filename' filename to write to
'-days n' number of days to certify the certificate for, defaults to 30 for x509

# create private key 'key.pem' and generate a certificate signing request 'req.pem'
$ openssl req -newkey rsa:1024 -keyout key.pem -out req.pem
or
$ openssl genrsa -out key.pem 1024 ; openssl req -new -key key.pem -out req.pem

# generate a self signed root certificate 'cert.pem' and private key 'key.pem'
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

from openssl-req@man

'-nodes' if a private key is created it will not be encrypted

# generate a self signed root certificate '$CERT.csr' for apache, and private key '$CERT.key'
$ export CERT=/etc/httpd/ssl/server
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out $CERT.key
$ chmod 600 $CERT.key
$ openssl req -new -key $CERT.key -out $CERT.csr
$ openssl x509 -req -in $CERT.csr -signkey $CERT.key -out $CERT.crt -days 365
# edit SSLCertificateFile $CERT.crt and SSLCertificateKeyFile $CERT.key

# same
$ export CERT=/etc/httpd/ssl/server
$ openssl req -x509 -nodes -newkey rsa:2048 -keyout $CERT.key -out $CERT.crt -days 365

# same but using 'make testcert'
$ cd /usr/share/ssl/certs ; make testcert

# same but using 'crypto-utils'
$ sudo yum install crypto-utils | sudo apt-get install crypto-utils
$ genkey your_FQDN
# edit SSLCertificateFile and SSLCertificateKeyFile

from How to Create Self-Signed SSL Certificates and Keys for Apache

$ nginx -V
TLS SNI support enabled
$ mkdir -p /etc/nginx/ssl/ ; cd $_

# create private key; asks for passphrase
$ openssl genrsa -des3 -out self-ssl.key 2048
# create a certificate signing request - CSR
$ openssl req -new -key self-ssl.key -out self-ssl.csr
# optional remove passphrase
$ cp -v self-ssl.{key,original} ; openssl rsa -in self-ssl.original -out self-ssl.key ; rm -v self-ssl.original
# create certificate
$ openssl x509 -req -days 365 -in self-ssl.csr -signkey self-ssl.key -out self-ssl.crt
# configure nginx
$ cat etc/nginx/virtual/.conf
server {
  listen 443;
  ssl on;
  ssl_certificate /path/to/self-ssl.crt;
  ssl_certificate_key /path/to/self-ssl.key;
  server_name theos.in;
}

# verify certificates
$ openssl verify pem-file
$ openssl verify self-ssl.crt

from HowTo: Create a Self-Signed SSL Certificate on Nginx For CentOS / RHEL

Using bhyve (BSD hypervisor)

BHyVe is a type-2 hypervisor developed on FreeBSD. Its similar to KVM, and a different approach to jail/lxc containers.

Requires Intel VT-x and Extended Page Tables (EPT). BIOS/UEFI support is in progress. Minimal device emulation support (virtio-blk, virtio-net).

Guest OS supported are FreeBSD/amd64 using bhyveload@man and OpenBSD/Linux using grub2-bhyve.

It uses bhyve@man a userland part of hypervisor that emulates devices, bhyvectl as a management tool, libvmmapi a userland api (wrapper library of /dev/vmm operations) and vmm.ko a kernel part of hypervisor.

Preparing host

# detect vmx
$ dmesg | grep vmx
vmx_init: processor does not support VMX operation

# load kernel module
$ kldload vmm
# create tap device and bridge network interface
$ ifconfig tap0 create
$ sysctl net.link.tap.up_on_open=1
$ ifconfig bridge0 create
# add lan 'em0' and tap interfaces to the bridge
$ ifconfig bridge0 addm em0 addm tap0
$ ifconfig bridge0 up

## persistent configuration: start bhyve guests at boot time
$ vi /etc/sysctl.conf
net.link.tap.up_on_open=1
$ vi /boot/loader.conf
vmm_load="YES"
nmdm_load="YES"
if_bridge_load="YES"
if_tap_load="YES"
$ vi /etc/rc.conf
cloned_interfaces="bridge0 tap0"
ifconfig_bridge0="addm igb0 addm tap0"

## delete/destroy network interface
$ ifconfig bridge0 down
$ ifconfig bridge0 deletem em0 deletem tap0
$ ifconfig bridge0 destroy

Creating guests

# load a guest
bhyveload -m ${mem} -d ${disk} ${name}
# run it
bhyve -c ${cpus} -m ${mem} -s 0,hostbridge -s 2,virtio-blk,${disk} 
  -s 3,virtio-net,${tap} -s 31,lpc -l com1,stdio vm0
  • FreeBSD
$ fetch ftp://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/10.1/FreeBSD-10.1-RELEASE-amd64-bootonly.iso

# create virtual disk
$ truncate -s 16G guest.img
# 'vmrun.sh' shell wrapper that loads VM and starts it in a loop
$ /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 
  -d guest.img -i -I FreeBSD-10.1-RELEASE-amd64-bootonly.iso guestname
# install guest and in the end enter shell
# (prior to 10.0 only) edit '/etc/ttys' and 
  ttyu0 "/usr/libexec/getty 3wire" xterm on secure
# reboot

# to start guest from virtual disk do
$ /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 
  -d guest.img guestname
  • OpenBSD
$ fetch http://people.freebsd.org/~grehan/flashimg.amd64-20131014.bz2
$ bunzip2 flashimg.amd64-20131014.bz2

# install port grub2-bhyve
$ cd /usr/ports/sysutils/grub2-bhyve
$ make install clean
# create tap device and add-it to bridge
$ ifconfig tap1 create
$ ifconfig bridge0 addm tap1

# create a grub device map
$ vi obsd.map
(hd0) ./obsd.img
# boot/load image
$ grub-bhyve -m obsd.map -r hd0 -M 512 obsd
# on boot prompt type
kopenbsd -h com0 (hd0,openbsd1)/bsd
boot
# start guest vm, use root:test123
$ bhyve -c 2 -m 512M -A -H -P -s 0:0,amd_hostbridge -s \
  1:0,lpc -s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,obsd.img \
  -l com1,stdio -W obsd
# cleanup
$ bhyvectl --destroy --vm=obsd

see create USB flash installer for OpenBSD

  • Linux
$ fetch http://releases.ubuntu.com/14.10/ubuntu-14.10-server-amd64.iso \
  -o somelinux.iso

# create virtual disk
$ truncate -s 16G linux.img
# create grub device map
$ vi device.map
(hd0) ./linux.img
(cd0) ./somelinux.iso
# boot/load image
$ grub-bhyve -m device.map -r cd0 -M 1024M linuxguest
# install guest and reboot
$ bhyve -AI -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap1 \
  -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./somelinux.iso \
  -l com1,stdio -c 4 -m 1024M linuxguest
# after install stop guest
$ bhyvectl --destroy --vm=linuxguest

# now can start from virtual disk, and boot
$ grub-bhyve -m device.map -r hd0,msdos1 -M 1024M linuxguest
$ bhyve -AI -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap1 \
  -s 3:0,virtio-blk,./linux.img -l com1,stdio -c 4 -m 1024M linuxguest

see FreeBSD as a Host with bhyve and Virtualization with bhyve @ BSDNow.

Virtual Machine Consoles

# use null modem device *nmdm* kernel module to wrap the bhyve console
$ kldload nmdm
$ bhyve -AI -H -P -s 0:0,hostbridge -s 1:0,lpc \
  -s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./linux.img \
  -l com1,/dev/nmdm0A -c 4 -m 1024M linuxguest

# use 'cu' to attach/reattach to the console
$ cu -l /dev/nmdm0B -s 9600
Connected
...

Managing Virtual Machines

# device node is created in /dev/vmm for each virtual machine
$ ls /dev/vmm
guestname linuxguest

# destroy a VM
$ bhyvectl --destroy --vm=guestname