Sep 23

Unix text mail to Outlook missing newlines

If you like myself have spent way too much time with Outlook chomping newlines in a simple text email this little workaround worked for me.  Assuming of course you do actually have newlines in your text that you are sending you can just use sed to add two spaces to the start of each line.

echo "$notifymessage" | sed 's/^/  /g' | mailx -r $fromuser -s "Monitor on $HOSTNAME" "$mail"

Comments Off on Unix text mail to Outlook missing newlines
comments

Sep 19

Solaris Ipfilter Pools

I wasn't aware before that ipfilter (ipf) has a concept of pools.  In other words list of IP addresses etc..

I previously had this basic article on enabling ipf in Solaris and following here is a little on pools.

** Note this was a Solaris 10 LDOM so therefore NIC was vnet0. You have to check your NIC it's most likely net0 in Solaris 11.

Setup the pools you need as follow.

# pwd
/etc/ipf
# cat ippool.conf
### Pool 13 some essential static addresses
table role = ipf type = tree number = 13
{ 10.1.11.34/32, 10.2.10.6/32 };
### Pool 14 some temporary IP's
table role = ipf type = tree number = 14
{ 192.168.8.0/24, 10.200.97.82/32 };

Use the pools in your ipf.conf.

# cat ipf.conf
[...]
pass in quick on lo0 all
pass out quick on lo0 all

### Block all inbound and outbound traffic by default
block in log on vnet0 all head 100
block out log on vnet0 all head 150

### Allow inbound SSH connections
pass in quick on vnet0 proto tcp from any to 10.1.11.87 port = 22 keep state group 100

### Use /etc/ipf/ippool.conf for pools
pass in on vnet0 from pool/13 group 100
pass in on vnet0 from pool/14 group 100

### Allow my box to utilize all UDP, TCP and ICMP services
pass out quick all

Of course flush and reload from file.

# ipf -Fa -f /etc/ipf/ipf.conf

Check the running set.

# ipfstat -io
pass out quick on lo0 all
block out log on vnet0 all head 150
pass out quick all
# Group 150
pass in quick on lo0 all
block in log on vnet0 all head 100
# Group 100
pass in quick on vnet0 proto tcp from any to 10.1.11.87/32 port = ssh keep state group 100
pass in on vnet0 from pool/13 to any group 100
pass in on vnet0 from pool/14 to any group 100

Note that updating the ippools you might need to reload also.

# ippool -F; ippool -f /etc/ipf/ippool.conf

For me that did not always work so I also did.

# svcadm disable ipfilter
# svcadm refresh ipfilter
# svcadm enable ipfilter

Listing the pools will save you a lot of time root causing rules that are actually correct.

# ippool -l
table role = ipf type = tree number = 14
        { 192.168.8.0/24; 10.200.97.82/32; };
table role = ipf type = tree number = 13
        { 10.1.11.34/32; 10.2.10.6/32 };

As always with firewalls test test test.

Comments Off on Solaris Ipfilter Pools
comments

Jul 30

Sendmail Mail Submission

I have struggled with this before and now I will make a note of it to save myself time when I encounter this again.

I have a setup on Solaris 11 where I am running a custom filter to accept mail on port 25 and then pass it on to sendmail for processing.  My filter need the sendmail daemon and I am running the sendmail daemon on port 10026. In a normal sendmail setup you are not stealing port 25 so I doubt you will have local mail submission problems.  And you might not need local mail submission with mail or mailx anyhow.  If you do need local mail submission and defaults are not working as was in my case below is my fix.

Make sure you are running the sendmail client.

# svcs -a | grep sendmail
online         Jun_30   svc:/network/smtp:sendmail
online          6:43:35 svc:/network/sendmail-client:default

Generate /etc/mail/submit.cf. In my case I copied and edited custom_submit.mc. Note I had to use "MSA".

# pwd
/etc/mail/cf/cf
# diff submit.mc custom_submit.mc
[...]
< FEATURE(`msp', `[127.0.0.1]')dnl
---
> FEATURE(`msp', `[127.0.0.1]',`MSA')dnl

# /usr/ccs/bin/m4 ../m4/cf.m4 custom_submit.mc > /etc/mail/submit.cf

Restart client

# svcadm disable svc:/network/sendmail-client:default
# svcadm enable svc:/network/sendmail-client:default

Links:
http://docs.oracle.com/cd/E19253-01/816-4555/mailrefer-106/index.html

Configuring sendmail as an MSA

Comments Off on Sendmail Mail Submission
comments

Jul 10

MySQL Sort Strings Like Numbers

There are a lot of articles out on the web that have suggestions around sorting a string like a number. One quick way with simple strings is "SELECT st FROM table ORDER BY st * 1". For me it was a little tricky because I needed to sort on a field called section and look like this "1.1.1". All fine until you have "1.1.10" and "1.12.1" etc.

For me the following worked.

mysql> SELECT section FROM tasks ORDER BY SUBSTRING_INDEX(section,'.',1),SUBSTRING_INDEX(SUBSTRING_INDEX(section,'.',2),'.',-1) * 1,SUBSTRING_INDEX(section,'.',-1) * 1;

Comments Off on MySQL Sort Strings Like Numbers
comments

Jun 26

Form Input Validation

Since I have to go research this every time I need it, I am jotting down a little how to. Frequently using html forms + PHP, I need to validate an input field.

Below is a recent simple javascript check for a regex style date + time input field. I also made this regex similar to msql timestamp for easier use in the database.

Of course there are a lot of ways to get this accomplished but my goal is fairly lightweight here. jquery and jquery date pickers are good options.

Like I said this is simple and use simple javascript alerts. You can make this a *lot* nicer with some ajax and css.

edit.php:
#########
Pay attention to the form name "frmEdit", onSubmit action and the name of the field ie "dt_started". Those are the ones that will get used in the javascript code.

<?php
?>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css" />
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/dateValidation.js"></script>
<title>Edit</title>
[...]
<form name="frmEdit" onReset="return confirm('Clear form?')" onSubmit="return ValidateForm()" action="<?php echo $_SERVER['PHP_SELF'] . "?edit=eTask&id=$id"; ?>" method="post">
<table border="0" width="100%">
[...]
<tr><td>dt_started: </td><td><input type="text" name="dt_started" maxlength=19 size=20 value="<?php echo htmlentities($details['dt_started']); ?>" />example: 2014-06-25 16:00:00 </td></tr>
<tr><td>dt_finshed: </td><td><input type="text" name="dt_finshed" maxlength=19 size=20 value="<?php echo htmlentities($details['dt_finshed']); ?>" />example: 2014-06-25 16:45:00 </td></tr>
[...]
<input type="reset" value="Reset" /> <input type="button" onClick="window.location='index.php'" value="Back" /></a></tr></td>
</table>
</form>

dateValidation.js:
##################

// Declaring valid date character, minimum year and maximum year
var dtCh= "-";
var minYear=1900;
var maxYear=2100;
[...]
function isDateTime(dtStr){
  var matches = dtStr.match(/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
  if (matches === null) {
    alert("Please enter a valid date")
    return false
  } else{
    var year = parseInt(matches[1], 10);
    var month = parseInt(matches[2], 10) - 1; // months are 0-11
    var day = parseInt(matches[3], 10);
    var hour = parseInt(matches[4], 10);
    var minute = parseInt(matches[5], 10);
    var second = parseInt(matches[6], 10);
    var date = new Date(year, month, day, hour, minute, second);
    if (date.getFullYear() !== year
      || date.getMonth() != month
      || date.getDate() !== day
      || date.getHours() !== hour
      || date.getMinutes() !== minute
      || date.getSeconds() !== second
    ) {
       alert("Please enter a valid date")
       return false
    } else {
       return true
    }
  }
}

function ValidateForm(){
  var dt=document.frmEdit.dt_started
  if (isDateTime(dt.value)==false){
    dt.focus()
    return false
  }
  var dt=document.frmEdit.dt_finshed
  if (isDateTime(dt.value)==false){
    dt.focus()
    return false
  }
return true
}

1
comments

Jun 18

Solaris 11.1 Update from ISO

Sometimes you don't have a Solaris IPS local repo and just want to update to a newer SRU (Support Repository Update). You can check versions at Oracle support and last check this Doc ID contained a good list: Oracle Solaris 11.1 Support Repository Updates (SRU) Index (Doc ID 1501435.1)

Few things to note:

- In this example I updated from SRU 18.5 to SRU 19.6. Most of my updates was actually all the way from the GA release to the latest SRU. And for me I had to have both the Oracle online repo as well as the local incremental SRU set for the update to catch all possible dependencies.

- If updating to a latest SRU and coming from many versions back you might also see something similar to below when the update tries to activate the new BE (boot environment):
Error while accessing "/dev/rdsk/c2d1s0": No such file or directory
pkg: unable to activate solaris-1

I have not 100% figured out why this is happening and if its just related to LDOM's but so far once or twice when this occurred either one of the following or a combination of the following allowed me to manually activate the BE.  Reboot the updated guest, just doing a simple zpool status, destroying the newly created BE and redoing the update.  Like I said all or one of the above steps.  I have a suspicion its as simple as doing a zfs status and then the activate worked.

Update 7.18.14: The last upgrade I did I encountered the unable to activate error and a simple zpool status allowed me to do beadm activate.

Lets start by checking the existing version. This indicates we are at SRU 18.5 in this case.

# pkg list entire
NAME (PUBLISHER)                                  VERSION                    IFO
entire                                            0.5.11-0.175.1.18.0.5.0    i--

Since I have the luxury of staging on NFS we might as well mount the repo direct. Another option since this is a LDOM is to add a virtual cdrom the guest. Note below I am setting both the incremental repo as well as the Oracle support repo. Use pkg unset-publisher to clear entries you don't want.

# mount -F hsfs /software/solaris/sol-11_1_19_6_0-incr-repo.iso /mnt
# pkg set-publisher -g file:///mnt/repo solaris
# pkg set-publisher -P -g http://pkg.oracle.com/solaris/release/ solaris
# pkg publisher
PUBLISHER                   TYPE     STATUS P LOCATION
solaris                     origin   online F file:///mnt/repo/
solaris                     origin   online F http://pkg.oracle.com/solaris/release/

Now lets do the update. Since the README for SRU 19.6 explained license around java we need to include the --accept flag. Be warned the README might contain more information you need to adhere to for a successful update. In my case to be extra safe even though Solaris can maintain multiple BE's (boot environments), I also made a snapshot of the OS on the storage back end.

# pkg update --accept
           Packages to install:   1
            Packages to update:  72
       Create boot environment: Yes
Create backup boot environment:  No

DOWNLOAD                                PKGS         FILES    XFER (MB)   SPEED
Completed                              73/73     2018/2018    99.8/99.8    0B/s

PHASE                                          ITEMS
Removing old actions                         238/238
Installing new actions                       277/277
Updating modified actions                  3265/3265
Updating package state database                 Done
Updating package cache                         72/72
Updating image state                            Done
Creating fast lookup database                   Done

A clone of solaris-new-2 exists and has been updated and activated.
On the next boot the Boot Environment solaris-new-3 will be
mounted on '/'.  Reboot when ready to switch to this updated BE.


---------------------------------------------------------------------------
NOTE: Please review release notes posted at:

https://support.oracle.com/epmos/faces/DocContentDisplay?id=1501435.1
---------------------------------------------------------------------------

Lets take a look at the boot environments before reboot.

# beadm list
BE              Active Mountpoint Space  Policy Created
--              ------ ---------- -----  ------ -------
solaris-new-1   -      -          13.82M static 2014-01-30 08:27
solaris-new-2   N      /          3.13M  static 2014-05-19 06:37
solaris-new-3   R      -          12.37G static 2014-06-18 04:55
solaris-orig    -      -          11.73M static 2013-07-09 10:26
solaris-sru14.5 -      -          19.87M static 2014-01-29 06:07
# reboot

After a reboot the Solaris version and BE looks like this.

# pkg list entire
NAME (PUBLISHER)                                  VERSION                    IFO
entire                                            0.5.11-0.175.1.19.0.6.0    i--
# beadm list
BE              Active Mountpoint Space  Policy Created
--              ------ ---------- -----  ------ -------
solaris-new-1   -      -          13.82M static 2014-01-30 08:27
solaris-new-2   -      -          14.45M static 2014-05-19 06:37
solaris-new-3   NR     /          12.49G static 2014-06-18 04:55
solaris-orig    -      -          11.73M static 2013-07-09 10:26
solaris-sru14.5 -      -          19.87M static 2014-01-29 06:07

Comments Off on Solaris 11.1 Update from ISO
comments

Jun 05

Ubuntu On a ZFS Root File System for Ubuntu 14.04

This is an update post to making an Ubuntu 14.04 (Trusty Tahr) OS work with ZFS root volume. Mostly the instructions remains the same as a previous post so this is a shortened version:

Booting Ubuntu on a ZFS Root File System

Small warning I did this 4 times. It worked the first time but of course I did not document it well the first time and when I tried again I had grub issues.

Step 1:

$ sudo -i
# apt-add-repository --yes ppa:zfs-native/stable

** Don't need grub ppa as per github instructions???

# apt-get update
# apt-get install debootstrap ubuntu-zfs

** Will take quite a while kernel modules compiles!!

# modprobe zfs
# dmesg | grep ZFS:
[ 1327.346821] ZFS: Loaded module v0.6.2-2~trusty, ZFS pool version 5000, ZFS filesystem version 5

Step 2:

# ls /dev/disk/by-id
ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419
ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1
ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part2

# fdisk /dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419

** Make partitions as follow

# fdisk -l /dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419
                                                 Device Boot      Start         End      Blocks   Id  System
/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1   *        2048      206847      102400   be  Solaris boot
/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part2          206848    16777215     8285184   bf  Solaris

Step 3:

# mke2fs -m 0 -L /boot/grub -j /dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1
# zpool create -o ashift=9 rpool /dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part2

# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
rpool  7.88G   117K  7.87G     0%  1.00x  ONLINE  -

# zfs create rpool/ROOT
# zfs create rpool/ROOT/ubuntu-1
# zfs umount -a
# zfs set mountpoint=/ rpool/ROOT/ubuntu-1
# zpool export rpool

Step 4:

# zpool import -d /dev/disk/by-id -R /mnt rpool
# mkdir -p /mnt/boot/grub
# mount /dev/disk/by-id/scsi-SATA_disk1-part1 /mnt/boot/grub
# debootstrap trusty /mnt

WTF: ** System seems hung. I see on a different terminal there was a messages system restart required. Weird. If you get this after debootstrap you have to redo Step 1 and Step 4.1 then...Is this because of only 2G RAM?

Step 5:

# cp /etc/hostname /mnt/etc/
# cp /etc/hosts /mnt/etc/
# tail -1 /mnt/etc/fstab
/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1  /boot/grub  auto  defaults  0  1

# mount --bind /dev  /mnt/dev
# mount --bind /proc /mnt/proc
# mount --bind /sys  /mnt/sys
# chroot /mnt /bin/bash --login

# locale-gen en_US.UTF-8
# apt-get update
# apt-get install ubuntu-minimal software-properties-common

# apt-add-repository --yes ppa:zfs-native/stable
# apt-add-repository --yes ppa:zfs-native/grub < - See below note on this command
# apt-get update
# apt-get install --no-install-recommends linux-image-generic linux-headers-generic
# apt-get install ubuntu-zfs
# apt-get install grub2-common grub-pc

Quick note on grub issues.  During the install I had to create soft links since I could not figure out the grub-probe failures.  From memory I think I created soft links as follow and purged grub2-common grub-pc and re-installed:

/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419 >>>> /dev/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419
/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1 >>>> /dev/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part1
/dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part2 >>>> /dev/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419-part2

Update 5.6.14:  After I had time to look at it closer I see my grub issues all came from the fact that there is no trusty grub ppa and the apt-add-repository command above is setting up a trusty repo.  Quickest way to fix this is after the apt-add-repository --yes ppa:zfs-native/grub command fix the file manually to use raring. As follow:

# more /etc/apt/sources.list.d/zfs-native-grub-trusty.list
deb http://ppa.launchpad.net/zfs-native/grub/ubuntu raring main

Now ready to continue on.

# apt-get install zfs-initramfs
# apt-get dist-upgrade
# passwd root

Step 6:

# grub-probe /
zfs
# ls /boot/grub/i386-pc/zfs*
/boot/grub/i386-pc/zfs.mod  /boot/grub/i386-pc/zfsinfo.mod

# update-initramfs -c -k all
update-initramfs: Generating /boot/initrd.img-3.13.0-24-generic

# grep "boot=zfs" /boot/grub/grub.cfg
	linux	/ROOT/ubuntu-1@/boot/vmlinuz-3.13.0-24-generic root=ZFS=rpool/ROOT/ubuntu-1 ro  boot=zfs
		linux	/ROOT/ubuntu-1@/boot/vmlinuz-3.13.0-24-generic root=ZFS=rpool/ROOT/ubuntu-1 ro  boot=zfs

# grep zfs /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="boot=zfs"

# update-grub

# grub-install $(readlink -f /dev/disk/by-id/ata-VBOX_HARDDISK_VBb4fe25f7-8f14d419)
Installation finished. No error reported.

# exit

Step 7:

# umount /mnt/boot/grub
# umount /mnt/dev
# umount /mnt/proc
# umount /mnt/sys
# zfs umount -a
# zpool export rpool
# reboot

Post First Reboot:
- Made a VB snapshot of course
- apt-get install ubuntu-desktop
** grub issues again so I remade the link again. Later fixed with the grub ppa repo pointing to raring instead.
- create a user
- install VB Guest Additions

TODO:
- Check into grub issue and having to create soft links. Something to do with grub not following soft links.

4
comments

Jun 02

Multi-Array in Bash

Well kind of...  When you are used to working in Python or any real language then Bash arrays are pretty lame.  But it can help in a few circumstances when you have to use Bash.

# cat bash_array.sh
#!/bin/bash
# Array pretending to be a Pythonic dictionary
ARRAY_DETAILS=( "10.51.20.63:Host1:Solaris"
                "10.51.20.80:Host2:Linux"
                "10.20.50.11:Host3:Windows" )

for hostDetails in "${ARRAY_DETAILS[@]}" ; do
  arrIN=(${hostDetails//:/ })
  IP=${arrIN[0]}
  NAME=${arrIN[1]}
  TYPE=${arrIN[2]}
  printf "Hostname %s with IP %s and is type %s.\n" "$NAME" "$IP" "$TYPE"
done

And the result looks like this:

# ./bash_array.sh
Hostname Host1 with IP 10.51.20.63 and is type Solaris.
Hostname Host2 with IP 10.51.20.80 and is type Linux.
Hostname Host3 with IP 10.20.50.11 and is type Windows.

Comments Off on Multi-Array in Bash
comments

May 28

Solaris 10 which package do I need

In Solaris 11 package management got a lot better and is almost as good as APT in the Linux world.  In Solaris 10 not so much.  A lot of times I find myself comparing systems and trying to track down which package I need for a specific binary.  The pkgchk command can help here:

Example:

# pkgchk -l -p /usr/bin/pdftops
Pathname: /usr/bin/pdftops
Type: regular file
Expected mode: 0755
Expected owner: root
Expected group: other
Expected file size (bytes): 22316
Expected sum(1) of contents: 15618
Expected last modification: May 17 22:40:06 2012
Referenced by the following packages:
        SUNWevince
Current status: installed

And of course install from CDROM as follow.

# pkgadd -d /mnt/Solaris_10/Product/ SUNWevince

Be warned here your nightmare starts when the package management starts pointing out all the dependencies.

Comments Off on Solaris 10 which package do I need
comments

May 28

SSH Through Intermediate Using Putty

Most of the time when you are forced to access a system through an intermediate hop it is fairly trivial either manually or automating it with ssh config.  That is assuming you are using *nix.  When using putty this is also possible and here is a quick note on what I did.

First off ensure you have a working ssh key to the intermediate host you will be using.

Next setup and save your new putty session as you would for any other connection.

Under Connection -> Proxy pick Local and set the Proxy hostname to your intermediate host (I set port to 0 but port does not matter).

Under local proxy command set something like this:

plink.exe %proxyhost -l root -agent -nc %host:%port

Comments Off on SSH Through Intermediate Using Putty
comments