Showing posts with label sysadmin. Show all posts
Showing posts with label sysadmin. Show all posts

Saturday, 7 November 2015

Create a bootable USB from an ISO using dd on the Linux command line

Install syslinux, a suite of utilities which ensures the iso image is in SYSLINUX format rather than ISOLINUX

    $ sudo apt-get install syslinux

Convert the iso image to SYSLINUX format

    $ isohybrid /path/image.iso 

Locate the USB device 

    $ lsblk
    sdb         8:16   1   3.8G  0 disk 
    └─sdb1      8:17   1   3.8G  0 part /media/user/usb_disk

Unmount the USB device

    $ sudo umount /dev/sdb1

Ensure it is indeed unmounted

    $ lsblk
    sdb         8:16   1   3.8G  0 disk 
    └─sdb1      8:17   1   3.8G  0 part 

Copy the ISO image onto the USB deisk

    $ sudo dd if=/path/image.iso of=/dev/sdb1

Tuesday, 6 October 2015

Gnome - change default application for text files

xdg-mime query default text/plain
xdg-mime default sublime_text.desktop text/plain

xdg-mime query filetype application/x-shellscript
xdg-mime query default application/x-shellscript

Wednesday, 19 August 2015

Send email from script

Install ssmtp:

    $ sudo apt-get install ssmtp

Edit the ssmtp config file:

    $ sudo vim /etc/ssmtp/ssmtp.conf

Enter this in the file:

root=username@gmail.com
mailhub=smtp.gmail.com:465
rewriteDomain=gmail.com
AuthUser=username
AuthPass=password (create a app-specific password in google accounts)
FromLineOverride=YES
UseTLS=YES

Enter the email address of the person who will receive your email:

    $ ssmtp recepient_name@gmail.com

Now enter this:

To: recipient_name@gmail.com
From: username@gmail.com
Subject: Sent from a terminal!

Your content goes here. Lorem ipsum dolor sit amet, consectetur adipisicing.
(Notice the blank space between the subject and the body.)

To send the email: Ctrl + D

You can also save the text mentioned in Point 5 into a text file and send it using:

    $ ssmtp recipient_name@gmail.com < filename.txt

http://askubuntu.com/questions/12917/how-to-send-mail-from-the-command-line

Tuesday, 2 June 2015

CheckInstall

CheckInstall keeps track of all the files created when installing from source ($ make install), builds a standard binary package and installs it using the system package management software (apt / yum etc), allowing you to later uninstall it

 tar -zxvf source-app.tar.gz;
 cd source/ ;
 ./configure;
 make;
 sudo checkinstall make install;

https://wiki.debian.org/CheckInstall

Thursday, 9 April 2015

Ubuntu terminal tab colors

This sets dark tab colors, except for the active tab, which is higlighted

$ vim ~/.config/gtk-3.0/gtk.css

TerminalWindow .notebook {
    background-color: shade (#333333, 1.02);
    background-image: none;
    border-radius: 3px;
    padding: 2px;
    background-clip: border-box;
    border-color: shade (#333333, 0.82);
    border-width: 1px;
    border-style: solid;
    /*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/
    /*font-weight: 300;*/

}

TerminalWindow .notebook tab {
    background-image: none;
    background-color: #333333;
    border-style: solid;
    border-image: -gtk-gradient (linear, left top, left bottom,
                                 from (alpha (shade (#333333, 0.9), 0.0)),
                                 to (shade (#333333, 0.9))) 1;
    border-image-width: 0 1px;
    border-color: transparent;
    border-width: 0;
    box-shadow: none;
    /*color: shade (@fg_color, 1.2);*/
    color: #AEA79F;
}

TerminalWindow .notebook tab:active {
    border-color: shade (#333333, 0.82);
    border-style: solid;
    border-width: 1px;
    background-color: shade (#AEA79F, 1.02);
    background-image: none;
    /*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/

    color: #333333;
}

Sunday, 15 March 2015

Bash tab completion example

#!/bin/bash

_apps()
{
echo $(cat ${APPS} | awk '{print $1}' | grep -v -e '^#\|^$')
}

_servers()
{
echo $(cat ${SERVERS} | awk '{print $2}' | sort -u | cut -f2 -d@)
}

_options()
{
echo "--help --verbose --validate --quiet --server"
}

_commands()
{
echo "status start stop restart kill version config"
}

_contains()
{
  local e
for e in ${@:2}; do
if [[ "$e" == "$1" ]]; then
echo 1
return 0
fi
done
  echo 0
  return 1
}

_complete()
{
    local prev_cmd="${COMP_WORDS[COMP_CWORD-1]}"
    local curr_cmd="${COMP_WORDS[COMP_CWORD]}"

    if [[ ${prev_cmd} == "--server" ]]; then
        COMPREPLY=( $(compgen -W "$(_servers)" -- ${curr_cmd}) )
        return 0
    fi

    if [[ ${curr_cmd} == -* ]]; then
        COMPREPLY=( $(compgen -W "$(_options)" -- ${curr_cmd}) )
        return 0
    fi

    # previous command was an app name, so show commands
    if [[ $(_contains "${prev_cmd}" "$(_apps)") -eq 1 ]]; then
        COMPREPLY=( $(compgen -W "$(_commands)" -- ${curr_cmd}) )
        return 0
    fi

    # otherwise try match an app name
    COMPREPLY=( $(compgen -W "$(_apps)" -- ${curr_cmd}) )
}

_main()
{
complete -F _complete cmd
}
_main

Monday, 19 January 2015

find files older than today and zip them up with the date as part of the extension

1. find files older than today in a given directory with a given extension

$ find -mtime +1 ${DIR} -name "*.${EXT}"

2. calculate the last modified time (seconds since epoch)

$ MOD_SECS=$(stat -c%Y ${FILE})

3. convert the seconds since epoch into a human readable date format

$ MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")

4. create a gzip file with the suffix including the date when the file was last modified

$ gzip -S .${MOD_DATE}.gz ${FILE}

5. putting it all together

for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
    MOD_SECS=$(stat -c%Y ${FILE})
    MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
    gzip -S .${MOD_DATE}.gz ${FILE}
done

6. as a script:

#!/bin/bash

if [ "$#" -ne 2 ]; then
    echo "Usage: $0 dir ext"
    exit 1
fi

DIR=$1
EXT=$2

for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
    MOD_SECS=$(stat -c%Y ${FILE})
    MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
    gzip -S .${MOD_DATE}.gz ${FILE}
done

Tuesday, 6 January 2015

bash command line parsing

We want to be able to mix both optional flags, optional arguments and positional arguments

optional flags: getopts character, not followed by a ':'
optional arguments: getopts character, followed by a ':' (which means "take an argument"
positional arguments: after the getopts, use $OPTIND which is the index of the last option getopts parsed.

$ script.sh [options] ARG1 ARG2

#!/bin/bash

usage() 

    echo "Usage: $0 [-a foo] [-b] ARG1 ARG2" 1>&2;
    exit 1
}

while getopts ":a:bh" o; do
    case "${o}" in
        a) a=${OPTARG};;
        b) b=YES;; # turn on flag
        h) usage ;; # display help
    esac
done

# store positional arguments
ARG1=${@:$OPTIND:1}
ARG2=${@:$OPTIND+1:1}

# check positional arguments have been supplied
if [ -z "${ARG1}" ] || [ -z "${ARG2}" ]; then
    usage
fi

# display the results
echo a=${a}
echo b=${b}
echo ARG1=${ARG1}
echo ARG2=${ARG2}

Saturday, 22 November 2014

ssh tunnel

Create a tunnel to a remote host via a gateway

    ssh -L <local-port-to-listen>:<destination-host>:<destination-port> <gateway_user>@<gateway>

This opens a local port listening for traffic on <local-port-to-listen> and forwards that traffic via the gateway (user@gateway) to the remote destination <destination-host>:<destination-port>

-f executes ssh in the background
-N means no remote command (ie: just create a tunnel)

    ssh -N -f -L 8080:destination:8080 user@gateway

Pointing your browser to localhost:8080 will connect to the ssh tunnel which forwards the data to destination:8080, going via the gateway

Tuesday, 18 November 2014

Multicast troubleshooting

Troubleshooting multicast:

Check that the interface is configured with multicast:

$ ifconfig eth9.240
eth9.240 Link encap:Ethernet HWaddr 00:60:DD:44:67:9E
inet addr:10.185.131.41 Bcast:10.185.131.63 Mask:255.255.255.224
inet6 addr: fe80::260:ddff:fe44:679e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1


Check that the multicast addresses you are subscribing to have a route to that particular interface:

$ ip route
224.0.0.0/4 dev eth9.240 scope link


Run your application and check if the subscriptions are going to the correct interface:

$ netstat -g
IPv6/IPv4 Group Memberships
Interface RefCnt Group
[...]
eth9.240 1 239.1.127.215
eth9.240 1 239.1.1.215


Run tcpdump and check that you are indeed receiving traffic. Do this while your application is running; otherwise the igmp subscription will not be on.

$ tcpdump -i eth9.240
10:15:13.385228 IP 10.0.8.121.45666 > 239.1.1.1.51001: UDP, length 16


If you got to the tcpdump part, the networking should be OK.

If your application is still not receiving packets, it is probably because of the rp_filter in Linux. 
The rp_filter filters out any packets that do not have a route on a particular interface. In the example above, if 10.0.8.121 is not routable via eth9.240 so the solution is to:

Check the filter
$ cat /proc/sys/net/ipv4/conf/ethX/rp_filter

add this line to /etc/sysctl.conf
    net.ipv4.conf.eth9/240.rp_filter = 0
$ sudo sysctl -p


Check if it’s OK
$ sysctl -a | grep “eth9/240.rp_filter”


Wednesday, 4 June 2014

Setting up an ubuntu vagrant instance

Install vagrant

Download the latest deb from http://www.vagrantup.com/downloads.html

Install vagrant from downloaded deb

$ sudo dpkg -i ./vagrant.deb

Install virtualbox

Add the appropriate deb source to your apt sources

$ echo "deb http://download.virtualbox.org/virtualbox/debian trusty contrib" | sudo tee -a /etc/apt/sources.list

Add the oracle public key

$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

Update the apt cache

$ sudo apt-get update

Install virtualbox

$ sudo apt-get install virtualbox-4.3

Initialise a vagrant instance

Note that if you're loading a 64 bit vm you need to have hardware virtualisation enabled in your bios (and your processor needs to support it!)

$ vagrant init ubuntu/trusty64
$ vagrant up

ssh into vm

$ vagrant ssh

halt/suspend/destroy vm

$ vagrant suspend saves current state of vm and stops it - fast to resume, uses more space
$ vagrant halt    saves current state of vm and shuts down - slower to resume, less space
$ vagrant destroy destroys all traces of the vm - no space used

Enable remote ssh access

By default vagrant will only create a private network between the host and vm. By changing to a public network, the vm will be allocated an ip address from your LAN and you will be able to ssh in from a remote machine

In the Vagranfile:

config.vm.network "public_network", bridge: 'eth0'

Reload Vagrantfile:

$ vagrant reload

You can ssh into the vm (vagrant ssh) and find out the ip address (ifconfig), allowing you to now ssh directly into the machine

$ ssh vagrant@192.168.1.xxx

Enable provisioning of the vm with ansible

Requires ansible to be installed
In the Vagrantfile

config.vm.provision :ansible do |ansible|
    ansible.playbook = "ansible/provision.yml"
    ansible.inventory_path = "ansible/hosts"
    ansible.limit = "all"
end


Create a file called ansible/hosts which has the vagrant vm listed in it

[vagrant]
192.168.1.xxx


Create a file called ansible/provision.yml which will be our playbook

---
- hosts: vagrant
tasks:
    - name: test vm is up
      ping:


Provision the vm
 
$ vagrant provision

Wednesday, 28 May 2014

RAID: creation and monitoring hard drive and raid health

Create raid array

Create raid 6 array with 4 disks

$ mdadm --create --verbose /dev/md0 --level=6 --raid-devices=4 /dev/sd[b-e]

Save your raid configuration

mdadm --detail --scan >> /etc/mdadm/mdadm.conf

in /etc/mdadm/mdadm.conf rename
ARRAY /dev/md0 metadata=1.2 name=ion:1 UUID=aa1f85b0:a2391657:cfd38029:772c560e
to:
ARRAY /dev/md0 UUID=aa1f85b0:a2391657:cfd38029:772c560e

and recreate the initrd for the kernel and include the configuration files relevant for the MD-RAID configuration

$ sudo update-initramfs -u

Create filesystem

To create our file system for best performance we need to calculate our stride and stripe sizes.

Stride size: divide the array chunk size by the file system block size.

We find the Array chunk size by looking at /proc/mdstat or using mdadm

$ cat /proc/mdstat 
... 512k chunk ...
      
$ mdadm --detail /dev/md{...}
     ...
     Chunk Size : 512K
     ...

A block size of 4k offers best performance for ext4.

Therefore, in the above example, stride size is 512 / 4 = 128

Stripe size: multiply the stripe by the number of data disks.

In raid-6, 2 disks are used for parity, and in raid-5, 1 disk is used for parity.

In my example I have 4 disks and am using raid-6, therefore I have 2 data disks.

Therefore, I have a stripe size of 128 * 2 = 256.

Create the file system:

$ mkfs.ext4 -b 4096 -E stride=128,stripe-width=256 /dev/md0

Mount filesystem

$ sudo mkdir /mnt/raid
$ sudo chmod 1777 /mnt/raid
$ sudo mount -o noauto,rw,async -t ext4 /dev/md0 /mnt/raid

Make it permanent - add to /etc/fstab

/dev/md0      /mnt/raid     ext4    defaults    1 2

Export via NFS

$ sudo apt-get install nfs-kernel-server

Mount the raid drive in the exported tree

$ sudo mkdir /export
$ sudo mkdir /export/raid
$ sudo mount --bind /mnt/raid /export/raid

Make it permanent - add to /etc/fstab

/mnt/raid /export/raid none bind 0 0

Configure /etc/exports

/export      192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async)
/export/raid 192.168.1.0/24(rw,nohide,insecure,no_subtree_check,async)

Start the service

$ sudo service nfs-kernel-server restart

Monitoring drive health

smartmontools: monitor S.M.A.R.T. ( (Self-Monitoring, Analysis and Reporting Technology) attributes and run hard drive self-tests.

enable SMART support if it's not already on
$ for i in `ls -1 /dev/sd[a-z]`; do smartctl -s on $i; done

turn on offline data collection
$ for i in `ls -1 /dev/sd[a-z]`; do smartctl -o on $i; done

enable autosave of device vendor-specific attributes
$ for i in `ls -1 /dev/sd[a-z]`; do smartctl -S on $i; done

check the overall health for each drive
$ for i in `ls -1 /dev/sd[a-z]`; do RESULTS=`smartctl -H $i | grep result | cut -f6 -d' '`; echo $i: $RESULTS; done

If any drive doesn't show PASSED, immediately backup all your data as that drive is probably about to fail.

Configure smartd to automatically check drives
$ vim /etc/smartd.conf
DEVICESCAN -H -m root -M exec /usr/libexec/smartmontools/smartdnotify -n standby,10,q

DEVICESCAN means scan for all devices
-H means monitor SMART health status
-m root means mail to root
-M exec /usr/libexec/smartmontools/smartdnotify means run the smartdnotify script to email warnings
-n standby,10,q means don't take the disk out of standby except if it's been in standby 10 times in a row, and don't report the unsuccessful attempts.

pick up changes
service smartd restart

Other options for smartd.conf:

 -a              \ # Implies all standard testing and reporting.
 -n standby,10,q \ # Don't spin up disk if it is currently spun down
                 \ #   unless it is 10th attempt in a row. 
                 \ #   Don't report unsuccessful attempts anyway.
 -o on           \ # Automatic offline tests (usually every 4 hours).
 -S on           \ # Attribute autosave (I don't really understand
                 \ #   what it is for. If you can explain it to me
                 \ #   please drop me a line.
 -R 194          \ # Show real temperature in the logs.
 -R 231          \ # The same as above.
 -I 194          \ # Ignore temperature attribute changes
 -W 3,50,50      \ # Notify if the temperature changes 3 degrees
                 \ #   comparing to the last check or if
                 \ #   the temperature exceeds 50 degrees.
 -s (S/../.././02|L/../../1/22) \ # short test: every day 2-3am
                                \ # long test every Monday 10pm-2am
                                \ # (Long test takes a lot of time
                                \ # and it should be finished before
                                \ # daily short test starts.
                                \ # At 3am every day this disk will be
                                \ # used heavily as backup storage)
 -m root         \ # To whom we should send mails.
 -M exec /usr/libexec/smartmontools/smartdnotify

Note: this will email root - if you don't monitor root's mails, then you may want to redirect mails sent to root to another email address

vim /etc/aliases
root: user@gmail.com

Now we want to monitor the RAID array.

add the to/from email addresses to mdadm config

$ vim /etc/mdadm.conf
MAILADDR user@gmail.com
MAILFROM user+mdadm@gmail.com

I tested this was working by running /sbin/mdadm --monitor --scan --test

gmail automatically marked the test mail as spam, so I had to create a filter to explicitly not mark emails sent from user+mdadm@gmail.com as spam (note the +mdadm part of the email address, neat gmail trick)

replace a failed drive

find the drive's serial no
$ hdparm -i /dev/sdd | grep SerialNo
 Model=WDC WD2003FZEX-00Z4SA0, FwRev=01.01A01, SerialNo=WD-WMC130D78F55

fail and remove the drive from the array
$ sudo mdadm --manage /dev/md0 --fail /dev/sdd
$ sudo mdadm --manage /dev/md0 --remove /dev/sdd

remove the old drive (using the above serial no to ensure you remove the correct drive), add the new one and add it to the array
$ sudo mdadm --manage /dev/md0 --add /dev/sdd

the array should start rebuilding
$ cat /proc/mdstat 
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md0 : active raid6 sdd[4] sde[3] sdb[1] sdc[0]
      3906765824 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [UU_U]
      [>....................]  recovery =  0.5% (11702016/1953382912) finish=970.5min speed=33344K/sec
      
unused devices: <none>

Tools for monitoring:
logwatch – monitors my /var/log/messages for anything out of the ordinary and mails me the output on a daily basis.
mdadm – mdadm will mail me if a disk has completely failed or the raid for some other reason fails. A complete resync is done every week.
smartd – I have smartd running “short” tests every night and long tests every second week. Reports are mailed to me.
munin – graphical and historical monitoring of performance and all stats of the server.

Thursday, 15 May 2014

byobu keyboard commands

Running byobu in screen mode - Ctrl-A is command mode

F2                           open new window
shift-F2                     new horizontal split
ctrl-F2                      new vertical split

F3/F4                        cycle through windows
alt-left/right               cycle through windows
shift-F3/F4                  cycle through splits
shift-left/right/up/down     cycle through splits
shift-alt-left/right/up/down resize split
ctrl-F3/F4                   move split
ctrl-shift-F3/F4             move window

alt-F11                      move split to new window
shift-F11                    zoom split in/out (full screen)

F8                           rename window

F6                           detach session and log out
shift-F6                     detach session

ctrl-F6                      kill current split

F7                           enter scrollback
alt-page up/page down        enter and move through scrollback
enter                        exit scrollback



byobu-enable: Enable persistent byobu (launch automatically upon login)

Linux tools

byobu - text-based window manager and terminal multiplexer, enhanced screen
htop - interactive process viewer
nethogs - process bandwidth utilisation
nload - realtime bandwidth utilisation graph
iptraf - IP network traffic monitor
    IP traffic monitor:
        top pane: TCP traffic: source addresses, packets/bytes received, link status, interface
        bottom pane: UDP / ICMP / broadcast traffic
    Statistical breakdown by TCP/UDP
        view traffic by protocol (only the common ports by default)
    LAN station monitor:
        IP traffic by MAC address

Wednesday, 14 May 2014

ITIL - Information Technology Infrastructure Library

ITIL: potentially provide a defined and structured argument for IT strategy and using IT to support and promote the business - as opposed to just being a cost centre.

http://en.wikipedia.org/wiki/Information_Technology_Infrastructure_Library

Friday, 11 April 2014

Create a local git repo, a remote github repo and sync them from the command line

Create a local repo

follow the instructions here.

Install hub

# install dependencies
sudo apt-get install rake

# clone repo
cd /tmp
git clone https://github.com/github/hub.git

# install hub
cd hub
sudo rake install prefix=/usr/local

# alias git to hub
echo 'alias git=hub' >> ~/.bashrc
. !$

# check it works
git version
# expected output:
# git version 1.8.3.2
# hub version 1.12.0-6-g8150ddb

Create a remote repo on github

create a repo with the name of the current directory
git create -d "My description" 

# push to github
git push origin master


Wednesday, 23 October 2013

using /proc/irq/#/smp_affinity to shield cpus from IRQs

IRQs (interrupt requests) are a request for service at a hardware level from the kernel.

When an IRQ arrives the kernel switches to interrupt context and loads the ISR (interrupt service routine) for the IRQ number which will process the interrupt.

IRQs have an affinity mask which defines which CPUs the ISR can run on. This is defined in /proc/irq/#/smp_affinity

The irqbalance service distributes IRQs across the processors in their associated affinity masks on a multiprocessor system. It uses /proc/irq/#/smp_affinity if it exists, or otherwise falls back to /proc/irq/default_smp_affinity/

The affinity mask in /proc/irq/#/smp_affinity and /proc/irq/default_smp_affinity is a 32-bit hex bitmask of CPUs.
    eg: ffffffff means all 32 CPUs 0-31
If there are more than 32 cores, we build up multiple comma separated 32-bit hex masks.
    eg: ffffffff,00000000 means CPUs 32-63

The irqbalance service uses the environment variable IRQBALANCE_BANNED_CPUS to tell it which CPUs it can't use for ISRs and IRQBALANCE_BANNED_INTERRUPTS to tell it which IRQs to ignore,

IRQBALANCE_BANNED_CPUS follows the same comma separated 32-bit hex format as /proc/irq/#/smp_affinity
IRQBALANCE_BANNED_INTERRUPTS is a space separated list of integer IRQs.

We can shield some CPUs from being interrupted in order to dedicate them to our own tasks.

We can also pin a network data consuming process onto a certain CPU and set the associated NIC (network interface controller) IRQs affinity mask to the same CPU so that they can share cache lines.



Wednesday, 16 October 2013

MongoDb on Fedora 19

Install and start server

yum install mongodb-server
systemctl start mongod
systemctl enable mongod
systemctl status mongod

Install client and verify it can connect to the server

yum install mongodb
mongo

You should now be in the mongo shell - test you can save and retrieve an object

db.test.save( { a: 1 } )
db.test.find()

Should display something like this:

{ "_id" : ObjectId("525f2fb01ec8e4af43c529c0"), "a" : 1 }

Wednesday, 2 October 2013

node.js / express.js / yeoman / angular installation on Fedora 19

download the prebuilt binary:
http://nodejs.org/dist/v0.10.20/node-v0.10.20-linux-x64.tar.gz

download and build from source
cd /tmp
wget 
http://nodejs.org/dist/v0.10.20/node-v0.10.20.tar.gz
tar -xf node-v0.10.20-linux-x64.tar.gz
cd node-v0.10.20-linux-x64/

configure, build and install
export PREFIX=/usr/local # or whatever your prefix is
./configure --prefix=$PREFIX
export LINK=g++ # only required if you're building on NFS
make
make install


clean up temporary files
rm -rf /tmp/node-v0.10.20-linux-x64*

add node to your path
export PATH=$PREFIX/bin:$PATH

display node and npm versions
node --version
v0.10.20
npm --version
1.3.11


install express.js
npm install -g express

display express version
express --version
3.4.0


install yeoman
npm install -g yo

install yeoman angular generator
npm install -g generator-angular

create angular app
yo angular app-name

serve angular app
grunt server